Massive refactoring: UIBuilder, Vew, HACArd, Badge
This commit is contained in:
		
							
								
								
									
										9
									
								
								lib/badge_class.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								lib/badge_class.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | part of 'main.dart'; | ||||||
|  |  | ||||||
|  | class Badge { | ||||||
|  |   String _entityId; | ||||||
|  |  | ||||||
|  |   Badge(String groupId) { | ||||||
|  |     _entityId = groupId; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								lib/card_class.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								lib/card_class.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | part of 'main.dart'; | ||||||
|  |  | ||||||
|  | class HACard { | ||||||
|  |   String _entityId; | ||||||
|  |   List _entities; | ||||||
|  |   String _friendlyName; | ||||||
|  |  | ||||||
|  |   List get entities => _entities; | ||||||
|  |   String get friendlyName => _friendlyName; | ||||||
|  |  | ||||||
|  |   HACard(String groupId, String friendlyName) { | ||||||
|  |     _entityId = groupId; | ||||||
|  |     _entities = []; | ||||||
|  |     _friendlyName = friendlyName; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void addEntity(String entityId) { | ||||||
|  |     _entities.add(entityId); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void addEntities(List entities) { | ||||||
|  |     _entities.addAll(entities); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -3,30 +3,25 @@ part of 'main.dart'; | |||||||
| class EntityCollection { | class EntityCollection { | ||||||
|  |  | ||||||
|   Map<String, Entity> _entities; |   Map<String, Entity> _entities; | ||||||
|   Map<String, dynamic> _uiStructure = {}; |   List<String> viewList; | ||||||
|  |  | ||||||
|   List _topBadgeDomains = ["alarm_control_panel", "binary_sensor", "device_tracker", "updater", "sun", "timer", "sensor"]; |  | ||||||
|  |  | ||||||
|   EntityCollection() { |   EntityCollection() { | ||||||
|     _entities = {}; |     _entities = {}; | ||||||
|  |     viewList = []; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Map<String, dynamic> get ui => _uiStructure; |  | ||||||
|  |  | ||||||
|   void parse(List rawData) { |   void parse(List rawData) { | ||||||
|     _entities.clear(); |     _entities.clear(); | ||||||
|     _uiStructure.clear(); |     viewList.clear(); | ||||||
|  |  | ||||||
|     TheLogger.log("Debug","Parsing ${rawData.length} Home Assistant entities"); |     TheLogger.log("Debug","Parsing ${rawData.length} Home Assistant entities"); | ||||||
|     rawData.forEach((rawEntityData) { |     rawData.forEach((rawEntityData) { | ||||||
|       Entity newEntity = addFromRaw(rawEntityData); |       Entity newEntity = addFromRaw(rawEntityData); | ||||||
|  |  | ||||||
|       if (newEntity.isView) { |       if (newEntity.isView) { | ||||||
|         _uiStructure.addAll({newEntity.entityId: {}}); |         viewList.add(newEntity.entityId); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     _createViews(); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void updateState(Map rawStateData) { |   void updateState(Map rawStateData) { | ||||||
| @@ -60,66 +55,4 @@ class EntityCollection { | |||||||
|     return _entities[entityId] != null; |     return _entities[entityId] != null; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void _createViews() async { |  | ||||||
|     TheLogger.log("Debug","Gethering views"); |  | ||||||
|     int viewCounter = 0; |  | ||||||
|     _uiStructure.forEach((viewId, viewStructure) { //Each view |  | ||||||
|       try { |  | ||||||
|         viewCounter += 1; |  | ||||||
|         Entity viewGroupData = get(viewId); |  | ||||||
|         if (viewGroupData != null) { |  | ||||||
|           viewStructure["groups"] = {}; |  | ||||||
|           viewStructure["state"] = "on"; |  | ||||||
|           viewStructure["entity_id"] = viewGroupData.entityId; |  | ||||||
|           viewStructure["badges"] = {"children": []}; |  | ||||||
|           viewStructure["attributes"] = { |  | ||||||
|             "icon": viewGroupData.icon |  | ||||||
|           }; |  | ||||||
|  |  | ||||||
|           viewGroupData.childEntities.forEach(( |  | ||||||
|               entityId) { //Each entity or group in view |  | ||||||
|             Map newGroup = {}; |  | ||||||
|             if (isExist(entityId)) { |  | ||||||
|               Entity cardOrEntityData = get(entityId); |  | ||||||
|               if (!cardOrEntityData.isGroup) { |  | ||||||
|                 if (_topBadgeDomains.contains(cardOrEntityData.domain)) { |  | ||||||
|                   viewStructure["badges"]["children"].add(entityId); |  | ||||||
|                 } else { |  | ||||||
|                   String autoGroupID = "${cardOrEntityData.domain}.${cardOrEntityData.domain}$viewCounter"; |  | ||||||
|                   if (viewStructure["groups"]["$autoGroupID"] == null) { |  | ||||||
|                     newGroup["entity_id"] = autoGroupID; |  | ||||||
|                     newGroup["friendly_name"] = cardOrEntityData.domain; |  | ||||||
|                     newGroup["children"] = []; |  | ||||||
|                     newGroup["children"].add(entityId); |  | ||||||
|                     viewStructure["groups"]["$autoGroupID"] = |  | ||||||
|                         Map.from(newGroup); |  | ||||||
|                   } else { |  | ||||||
|                     viewStructure["groups"]["$autoGroupID"]["children"].add( |  | ||||||
|                         entityId); |  | ||||||
|                   } |  | ||||||
|                 } |  | ||||||
|               } else { |  | ||||||
|                 newGroup["entity_id"] = entityId; |  | ||||||
|                 newGroup["friendly_name"] = cardOrEntityData.displayName; |  | ||||||
|                 newGroup["children"] = List<String>(); |  | ||||||
|                 cardOrEntityData.childEntities.forEach(( |  | ||||||
|                     groupedEntityId) { |  | ||||||
|                   newGroup["children"].add(groupedEntityId); |  | ||||||
|                 }); |  | ||||||
|                 viewStructure["groups"]["$entityId"] = Map.from(newGroup); |  | ||||||
|               } |  | ||||||
|             } else { |  | ||||||
|               TheLogger.log("Warning", "Unknown entity inside view: $entityId"); |  | ||||||
|             } |  | ||||||
|           }); |  | ||||||
|         } else { |  | ||||||
|           TheLogger.log("Warning", "No state or attributes found for view: $viewId"); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|       } catch (error) { |  | ||||||
|         TheLogger.log("Error","Error parsing view: $viewId"); |  | ||||||
|       } |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -13,6 +13,7 @@ class HomeAssistant { | |||||||
|   int _subscriptionMessageId = 0; |   int _subscriptionMessageId = 0; | ||||||
|   int _configMessageId = 0; |   int _configMessageId = 0; | ||||||
|   EntityCollection _entities; |   EntityCollection _entities; | ||||||
|  |   UIBuilder _uiBuilder; | ||||||
|   Map _instanceConfig = {}; |   Map _instanceConfig = {}; | ||||||
|  |  | ||||||
|   Completer _fetchCompleter; |   Completer _fetchCompleter; | ||||||
| @@ -22,7 +23,8 @@ class HomeAssistant { | |||||||
|   Timer _fetchingTimer; |   Timer _fetchingTimer; | ||||||
|  |  | ||||||
|   String get locationName => _instanceConfig["location_name"] ?? ""; |   String get locationName => _instanceConfig["location_name"] ?? ""; | ||||||
|  |   int get viewsCount => _entities.viewList.length ?? 0; | ||||||
|  |   UIBuilder get uiBuilder => _uiBuilder; | ||||||
|  |  | ||||||
|   EntityCollection get entities => _entities; |   EntityCollection get entities => _entities; | ||||||
|  |  | ||||||
| @@ -31,6 +33,7 @@ class HomeAssistant { | |||||||
|     _hassioPassword = password; |     _hassioPassword = password; | ||||||
|     _hassioAuthType = authType; |     _hassioAuthType = authType; | ||||||
|     _entities = EntityCollection(); |     _entities = EntityCollection(); | ||||||
|  |     _uiBuilder = UIBuilder(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future fetch() { |   Future fetch() { | ||||||
| @@ -226,6 +229,7 @@ class HomeAssistant { | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     _entities.parse(response["result"]); |     _entities.parse(response["result"]); | ||||||
|  |     _uiBuilder.build(_entities); | ||||||
|     _statesCompleter.complete(); |     _statesCompleter.complete(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,6 +18,10 @@ part 'utils.class.dart'; | |||||||
| part 'mdi.class.dart'; | part 'mdi.class.dart'; | ||||||
| part 'entity.class.dart'; | part 'entity.class.dart'; | ||||||
| part 'entity_collection.class.dart'; | part 'entity_collection.class.dart'; | ||||||
|  | part 'ui_builder_class.dart'; | ||||||
|  | part 'view_class.dart'; | ||||||
|  | part 'card_class.dart'; | ||||||
|  | part 'badge_class.dart'; | ||||||
|  |  | ||||||
| EventBus eventBus = new EventBus(); | EventBus eventBus = new EventBus(); | ||||||
| const String appName = "HA Client"; | const String appName = "HA Client"; | ||||||
| @@ -74,7 +78,6 @@ class MainPage extends StatefulWidget { | |||||||
| class _MainPageState extends State<MainPage> with WidgetsBindingObserver { | class _MainPageState extends State<MainPage> with WidgetsBindingObserver { | ||||||
|   HomeAssistant _homeAssistant; |   HomeAssistant _homeAssistant; | ||||||
|   EntityCollection _entities; |   EntityCollection _entities; | ||||||
|   Map _uiStructure; |  | ||||||
|   //Map _instanceConfig; |   //Map _instanceConfig; | ||||||
|   int _uiViewsCount = 0; |   int _uiViewsCount = 0; | ||||||
|   String _instanceHost; |   String _instanceHost; | ||||||
| @@ -158,8 +161,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver { | |||||||
|         setState(() { |         setState(() { | ||||||
|           //_instanceConfig = _homeAssistant.instanceConfig; |           //_instanceConfig = _homeAssistant.instanceConfig; | ||||||
|           _entities = _homeAssistant.entities; |           _entities = _homeAssistant.entities; | ||||||
|           _uiStructure = _entities.ui; |           _uiViewsCount = _homeAssistant.viewsCount; | ||||||
|           _uiViewsCount = _uiStructure.length; |  | ||||||
|           _isLoading = false; |           _isLoading = false; | ||||||
|         }); |         }); | ||||||
|       }).catchError((e) { |       }).catchError((e) { | ||||||
| @@ -189,14 +191,14 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver { | |||||||
|  |  | ||||||
|   List<Widget> _buildViews() { |   List<Widget> _buildViews() { | ||||||
|     List<Widget> result = []; |     List<Widget> result = []; | ||||||
|     if ((_entities != null) && (_uiStructure != null)) { |     if ((_entities != null) && (!_homeAssistant.uiBuilder.isEmpty)) { | ||||||
|       _uiStructure.forEach((viewId, structure) { |       _homeAssistant.uiBuilder.views.forEach((viewId, view) { | ||||||
|         result.add( |         result.add( | ||||||
|             RefreshIndicator( |             RefreshIndicator( | ||||||
|               color: Colors.amber, |               color: Colors.amber, | ||||||
|               child: ListView( |               child: ListView( | ||||||
|                 physics: const AlwaysScrollableScrollPhysics(), |                 physics: const AlwaysScrollableScrollPhysics(), | ||||||
|                 children: _buildSingleView(structure), |                 children: _buildSingleView(view), | ||||||
|               ), |               ), | ||||||
|               onRefresh: () => _refreshData(), |               onRefresh: () => _refreshData(), | ||||||
|             ) |             ) | ||||||
| @@ -206,36 +208,35 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver { | |||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   List<Widget> _buildSingleView(structure) { |   List<Widget> _buildSingleView(View view) { | ||||||
|     List<Widget> result = []; |     List<Widget> result = []; | ||||||
|     if (structure["badges"]["children"].length > 0) { |     if (view.isThereBadges) { | ||||||
|       result.add( |       result.add( | ||||||
|             Wrap( |             Wrap( | ||||||
|               alignment: WrapAlignment.center, |               alignment: WrapAlignment.center, | ||||||
|               spacing: 10.0, |               spacing: 10.0, | ||||||
|               runSpacing: 4.0, |               runSpacing: 4.0, | ||||||
|               children: _buildBadges(structure["badges"]["children"]), |               children: _buildBadges(view.badges), | ||||||
|             ) |             ) | ||||||
|       ); |       ); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|     structure["groups"].forEach((id, group) { |     view.cards.forEach((id, card) { | ||||||
|       if (group["children"].length > 0) { |       if (card.entities.isNotEmpty) { | ||||||
|         result.add(_buildCard( |         result.add(_buildCard(card)); | ||||||
|             group["children"], group["friendly_name"].toString())); |  | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   List<Widget> _buildBadges(List ids) { |   List<Widget> _buildBadges( Map<String, Badge> badges) { | ||||||
|     List<Widget> result = []; |     List<Widget> result = []; | ||||||
|     ids.forEach((entityId) { |     badges.forEach((id, badge) { | ||||||
|       var data = _entities.get(entityId); |       var badgeEntity = _entities.get(id); | ||||||
|       if (data != null) { |       if (badgeEntity != null) { | ||||||
|         result.add( |         result.add( | ||||||
|           _buildSingleBadge(data) |           _buildSingleBadge(badgeEntity) | ||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
| @@ -351,12 +352,13 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Card _buildCard(List ids, String name) { |   Card _buildCard(HACard card) { | ||||||
|     List<Widget> body = []; |     List<Widget> body = []; | ||||||
|     body.add(_buildCardHeader(name)); |     body.add(_buildCardHeader(card.friendlyName)); | ||||||
|     body.addAll(_buildCardBody(ids)); |     body.addAll(_buildCardBody(card.entities)); | ||||||
|     Card result = |     Card result = Card( | ||||||
|     Card(child: new Column(mainAxisSize: MainAxisSize.min, children: body)); |         child: new Column(mainAxisSize: MainAxisSize.min, children: body) | ||||||
|  |     ); | ||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -462,8 +464,8 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver { | |||||||
|  |  | ||||||
|   List<Tab> buildUIViewTabs() { |   List<Tab> buildUIViewTabs() { | ||||||
|     List<Tab> result = []; |     List<Tab> result = []; | ||||||
|     if ((_entities != null) && (_uiStructure != null)) { |     if ((_entities != null) && (!_homeAssistant.uiBuilder.isEmpty)) { | ||||||
|       _uiStructure.forEach((viewId, structure) { |       _homeAssistant.uiBuilder.views.forEach((viewId, view) { | ||||||
|         result.add( |         result.add( | ||||||
|             Tab( |             Tab( | ||||||
|                 icon: MaterialDesignIcons.createIconFromEntityData(_entities.get(viewId), 24.0, null) |                 icon: MaterialDesignIcons.createIconFromEntityData(_entities.get(viewId), 24.0, null) | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								lib/ui_builder_class.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								lib/ui_builder_class.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | part of 'main.dart'; | ||||||
|  |  | ||||||
|  | class UIBuilder { | ||||||
|  |   EntityCollection _entities; | ||||||
|  |   Map<String, View> _views; | ||||||
|  |   List _topBadgeDomains = ["alarm_control_panel", "binary_sensor", "device_tracker", "updater", "sun", "timer", "sensor"]; | ||||||
|  |  | ||||||
|  |   bool get isEmpty => _views.length == 0; | ||||||
|  |   Map<String, View> get views => _views ?? {}; | ||||||
|  |  | ||||||
|  |   UIBuilder() { | ||||||
|  |     _views = {}; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void build(EntityCollection entitiesCollection) { | ||||||
|  |     _entities = entitiesCollection; | ||||||
|  |     _views.clear(); | ||||||
|  |     _createViewsContainers(entitiesCollection.viewList); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void _createViewsContainers(List<String> viewsList) { | ||||||
|  |     int counter = 0; | ||||||
|  |     viewsList.forEach((viewId) { | ||||||
|  |       counter += 1; | ||||||
|  |       _views[viewId] = View(viewId, counter); | ||||||
|  |     }); | ||||||
|  |     //TODO merge this two func into one | ||||||
|  |     _createViews(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void _createViews() { | ||||||
|  |     TheLogger.log("Debug","Gethering views"); | ||||||
|  |     _views.forEach((viewId, view) { //Each view | ||||||
|  |       try { | ||||||
|  |         Entity viewGroupEntity = _entities.get(viewId); | ||||||
|  |         viewGroupEntity.childEntities.forEach(( | ||||||
|  |               entityId) { //Each entity or group in view | ||||||
|  |           if (_entities.isExist(entityId)) { | ||||||
|  |             Entity entityToAdd = _entities.get(entityId); | ||||||
|  |             if (!entityToAdd.isGroup) { | ||||||
|  |               if (_topBadgeDomains.contains(entityToAdd.domain)) { | ||||||
|  |                 //This is badge | ||||||
|  |                 view.addBadge(entityId); | ||||||
|  |               } else { | ||||||
|  |                 //This is a standalone entity | ||||||
|  |                 view.addEntityWithoutGroup(entityToAdd); | ||||||
|  |               } | ||||||
|  |             } else { | ||||||
|  |               view.addCardWithEntities(entityId, entityToAdd.displayName, entityToAdd.childEntities); | ||||||
|  |             } | ||||||
|  |           } else { | ||||||
|  |             TheLogger.log("Warning", "Unknown entity inside view: $entityId"); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       } catch (error) { | ||||||
|  |         TheLogger.log("Error","Error parsing view: $viewId"); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								lib/view_class.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								lib/view_class.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | part of 'main.dart'; | ||||||
|  |  | ||||||
|  | class View { | ||||||
|  |   String _entityId; | ||||||
|  |   int _count; | ||||||
|  |   Map<String, HACard> cards; | ||||||
|  |   Map<String, Badge> badges; | ||||||
|  |  | ||||||
|  |   bool get isThereBadges => (badges != null) && (badges.isNotEmpty); | ||||||
|  |  | ||||||
|  |   View(String groupId, int viewCount) { | ||||||
|  |     _entityId = groupId; | ||||||
|  |     _count = viewCount; | ||||||
|  |     cards = {}; | ||||||
|  |     badges = {}; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void addBadge(String entityId) { | ||||||
|  |     badges.addAll({entityId: Badge(entityId)}); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void addEntityWithoutGroup(Entity entity) { | ||||||
|  |     String groupIdToAdd = "${entity.domain}.${entity.domain}$_count"; | ||||||
|  |     if (cards[groupIdToAdd] == null) { | ||||||
|  |       addCard(groupIdToAdd, entity.domain); | ||||||
|  |     } | ||||||
|  |     cards[groupIdToAdd].addEntity(entity.entityId); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void addCard(String entityId, String friendlyName) { | ||||||
|  |     cards.addAll({"$entityId": HACard(entityId, friendlyName)}); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void addCardWithEntities(String entityId, String friendlyName, List entities) { | ||||||
|  |     cards.addAll({"$entityId": HACard(entityId, friendlyName)}); | ||||||
|  |     cards[entityId].addEntities(entities); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user