Skip to content

Commit

Permalink
feat: Adding icons to menu items. #4
Browse files Browse the repository at this point in the history
  • Loading branch information
LuchoTurtle committed May 9, 2023
1 parent a8ebb28 commit 081a7ea
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 14 deletions.
15 changes: 15 additions & 0 deletions assets/menu_items.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,33 @@
"index_in_level": 0,
"title": "People",
"text_color": "#Ffb97e",
"icon": {
"colour": "#Ffb97e",
"code": 61668,
"emoji": "🧑‍🤝‍🧑",
"url": "https://cdn-icons-png.flaticon.com/512/4436/4436481.png"
},
"tiles": [
{
"id": 2,
"index_in_level": 0,
"title": "Online Now",
"text_color": "#FFFFFF",
"icon": {
"colour": "#Ffb97e",
"emoji": "🧑‍🤝‍🧑",
"url": "https://cdn-icons-png.flaticon.com/512/4436/4436481.png"
},
"tiles": [
{
"id": 3,
"index_in_level": 0,
"title": "Family",
"text_color": "#FFFFFF",
"icon": {
"colour": "#Ffb97e",
"url": "https://cdn-icons-png.flaticon.com/512/4436/4436481.png"
},
"tiles": []
},
{
Expand Down
2 changes: 2 additions & 0 deletions lib/dynamic_menu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class _MenuItemState extends State<MenuItem> {
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.white))),
child: ListTile(
contentPadding: EdgeInsets.only(left: widget.leftPadding),
leading: widget.info.getIcon(),
title: Text(widget.info.title,
style: TextStyle(
fontSize: 25,
Expand Down Expand Up @@ -172,6 +173,7 @@ class _MenuItemState extends State<MenuItem> {
_expanded ? Icons.expand_less : Icons.arrow_drop_down,
color: Colors.white,
),
leading: widget.info.getIcon(),
children: [
ReorderableListView(
// https://stackoverflow.com/questions/56726298/nesting-reorderable-lists
Expand Down
115 changes: 101 additions & 14 deletions lib/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,33 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'dynamic_menu.dart';

const jsonFilePath = 'assets/menu_items.json';
const storageKey = 'menuItems';

/// Converts a [hexString] to a Color.
/// Color white is returned by default.
Color hexToColor(String hexString) {
try {
final buffer = StringBuffer();
if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
buffer.write(hexString.replaceFirst('#', ''));
return Color(int.parse(buffer.toString(), radix: 16));
} catch (e) {
return const Color(0xFFFFFFFF);
/// Class that holds information about the possible tile icon
class MenuItemInfoIcon {
late final int? code;
late final String? emoji;
late final String? url;
late final String? colour;

MenuItemInfoIcon({this.code, this.emoji, this.url, this.colour});

MenuItemInfoIcon.fromJson(Map<String, dynamic> json) {
code = json['code'];
emoji = json['emoji'];
url = json['url'];
colour = json['colour'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['code'] = code;
data['emoji'] = emoji;
data['url'] = url;
data['colour'] = colour;

return data;
}
}

Expand All @@ -28,22 +40,89 @@ class MenuItemInfo {
late int indexInLevel;
late String title;
late Color textColor;
late MenuItemInfoIcon? _icon;
late List<MenuItemInfo> tiles;

MenuItemInfo({required this.id, required this.title, this.tiles = const []});

/// Converts a [hexString] to a Color.
/// Color white is returned by default.
Color _hexToColor(String hexString) {
try {
final buffer = StringBuffer();
if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
buffer.write(hexString.replaceFirst('#', ''));
return Color(int.parse(buffer.toString(), radix: 16));
} catch (e) {
return const Color(0xFFFFFFFF);
}
}

/// Gets the icon widget of the tile.
/// The priority of the icon retrieved is by:
/// 1 - the `code` field.
/// 2 - the `emoji` field.
/// 3 - the `url` field.
/// If there is no icon, the `null` is returned.
Widget? getIcon() {
bool iconExists = _icon != null;

// Check if any icon information exists
if (iconExists) {

// Icon parameters
int? iconCode = _icon?.code;
String? emojiText = _icon?.emoji;
String? imageUrl = _icon?.url;
String? colourHex = _icon?.colour;

// Icon colour
Color colour = _hexToColor(colourHex!);

if (iconCode != null) {
return Icon(
IconData(iconCode, fontFamily: 'MaterialIcons'),
color: colour,
);
}

if (emojiText != null) {
return Text(emojiText.toString(), style: TextStyle(color: colour, fontSize: 30));
}

if(imageUrl != null) {
return Container(
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Image.network(imageUrl, fit: BoxFit.fitHeight, height: 64));
}
}

// If there's no icon information, return null
else {
return null;
}
}

/// Converts `json` text to BasicTile
MenuItemInfo.fromJson(Map<String, dynamic> json) {
id = json['id'];
indexInLevel = json['index_in_level'];
title = json['title'];
textColor = hexToColor(json['text_color']);
textColor = _hexToColor(json['text_color']);

// Decoding `tiles` field
if (json['tiles'] != null) {
tiles = [];
json['tiles'].forEach((v) {
tiles.add(MenuItemInfo.fromJson(v));
});
}

_icon = null;
// Decoding `icon` field
if (json['icon'] != null) {
_icon = MenuItemInfoIcon.fromJson(json['icon']);
}
}

Map<String, dynamic> toJson() {
Expand All @@ -52,11 +131,19 @@ class MenuItemInfo {
data['index_in_level'] = indexInLevel;
data['title'] = title;
data['text_color'] = '#${textColor.value.toRadixString(16)}';

// Adding `tiles` field
if (tiles.isNotEmpty) {
data['tiles'] = tiles.map((v) => v.toJson()).toList();
} else {
data['tiles'] = [];
}

// Adding `icon` field
if (_icon != null) {
data['icon'] = _icon!.toJson();
}

return data;
}
}
Expand All @@ -67,7 +154,7 @@ class MenuItemInfo {
Future<List<MenuItemInfo>> loadMenuItems() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();

//await prefs.remove(storageKey);
await prefs.remove(storageKey);

final String? jsonStringFromLocalStorage = prefs.getString(storageKey);

Expand Down

0 comments on commit 081a7ea

Please sign in to comment.