From 081a7eae7c92e1b1eea28514c194cdf4d7072c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20Arteiro?= Date: Tue, 9 May 2023 10:49:17 +0100 Subject: [PATCH] feat: Adding icons to menu items. #4 --- assets/menu_items.json | 15 ++++++ lib/dynamic_menu.dart | 2 + lib/settings.dart | 115 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 118 insertions(+), 14 deletions(-) diff --git a/assets/menu_items.json b/assets/menu_items.json index d3571ca..dcbc3a4 100644 --- a/assets/menu_items.json +++ b/assets/menu_items.json @@ -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": [] }, { diff --git a/lib/dynamic_menu.dart b/lib/dynamic_menu.dart index 936467a..907fb02 100644 --- a/lib/dynamic_menu.dart +++ b/lib/dynamic_menu.dart @@ -145,6 +145,7 @@ class _MenuItemState extends State { 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, @@ -172,6 +173,7 @@ class _MenuItemState extends State { _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 diff --git a/lib/settings.dart b/lib/settings.dart index af59308..d7bc415 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -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 json) { + code = json['code']; + emoji = json['emoji']; + url = json['url']; + colour = json['colour']; + } + + Map toJson() { + final Map data = {}; + data['code'] = code; + data['emoji'] = emoji; + data['url'] = url; + data['colour'] = colour; + + return data; } } @@ -28,22 +40,89 @@ class MenuItemInfo { late int indexInLevel; late String title; late Color textColor; + late MenuItemInfoIcon? _icon; late List 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 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 toJson() { @@ -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; } } @@ -67,7 +154,7 @@ class MenuItemInfo { Future> loadMenuItems() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); - //await prefs.remove(storageKey); + await prefs.remove(storageKey); final String? jsonStringFromLocalStorage = prefs.getString(storageKey);