Handle card rendering errors to show in ui
This commit is contained in:
		| @@ -12,65 +12,77 @@ class CardData { | |||||||
|   EntityWrapper get entity => entities.isNotEmpty ? entities[0] : null; |   EntityWrapper get entity => entities.isNotEmpty ? entities[0] : null; | ||||||
|  |  | ||||||
|   factory CardData.parse(Map<String, dynamic> rawData) { |   factory CardData.parse(Map<String, dynamic> rawData) { | ||||||
|     switch (rawData['type']) { |     try { | ||||||
|       case CardType.ENTITIES: |       switch (rawData['type']) { | ||||||
|         return EntitiesCardData(rawData); |         case CardType.ENTITIES: | ||||||
|         break; |  | ||||||
|       case CardType.ALARM_PANEL: |  | ||||||
|         return AlarmPanelCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.BUTTON: |  | ||||||
|         return ButtonCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.ENTITY_BUTTON: |  | ||||||
|         return ButtonCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.CONDITIONAL: |  | ||||||
|         return CardData.parse(rawData['card']); |  | ||||||
|         break; |  | ||||||
|       case CardType.ENTITY_FILTER: |  | ||||||
|         Map<String, dynamic> cardData = Map.from(rawData); |  | ||||||
|         cardData.remove('type'); |  | ||||||
|         if (rawData.containsKey('card')) { |  | ||||||
|           cardData.addAll(rawData['card']); |  | ||||||
|         } |  | ||||||
|         cardData['type'] ??= CardType.ENTITIES; |  | ||||||
|         return CardData.parse(cardData); |  | ||||||
|         break; |  | ||||||
|       case CardType.GAUGE: |  | ||||||
|         return GaugeCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.GLANCE: |  | ||||||
|         return GlanceCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.HORIZONTAL_STACK: |  | ||||||
|         return HorizontalStackCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.VERTICAL_STACK: |  | ||||||
|         return VerticalStackCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.MARKDOWN: |  | ||||||
|         return MarkdownCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       case CardType.MEDIA_CONTROL: |  | ||||||
|         return MediaControlCardData(rawData); |  | ||||||
|         break; |  | ||||||
|       default: |  | ||||||
|         if (rawData.containsKey('entities')) { |  | ||||||
|           return EntitiesCardData(rawData); |           return EntitiesCardData(rawData); | ||||||
|         } else if (rawData.containsKey('entity')) { |           break; | ||||||
|           rawData['entities'] = [rawData['entity']]; |         case CardType.ALARM_PANEL: | ||||||
|           return EntitiesCardData(rawData); |           return AlarmPanelCardData(rawData); | ||||||
|         } |           break; | ||||||
|         return CardData(rawData); |         case CardType.BUTTON: | ||||||
|  |           return ButtonCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         case CardType.ENTITY_BUTTON: | ||||||
|  |           return ButtonCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         case CardType.CONDITIONAL: | ||||||
|  |           return CardData.parse(rawData['card']); | ||||||
|  |           break; | ||||||
|  |         case CardType.ENTITY_FILTER: | ||||||
|  |           Map<String, dynamic> cardData = Map.from(rawData); | ||||||
|  |           cardData.remove('type'); | ||||||
|  |           if (rawData.containsKey('card')) { | ||||||
|  |             cardData.addAll(rawData['card']); | ||||||
|  |           } | ||||||
|  |           cardData['type'] ??= CardType.ENTITIES; | ||||||
|  |           return CardData.parse(cardData); | ||||||
|  |           break; | ||||||
|  |         case CardType.GAUGE: | ||||||
|  |           return GaugeCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         case CardType.GLANCE: | ||||||
|  |           return GlanceCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         case CardType.HORIZONTAL_STACK: | ||||||
|  |           return HorizontalStackCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         case CardType.VERTICAL_STACK: | ||||||
|  |           return VerticalStackCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         case CardType.MARKDOWN: | ||||||
|  |           return MarkdownCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         case CardType.MEDIA_CONTROL: | ||||||
|  |           return MediaControlCardData(rawData); | ||||||
|  |           break; | ||||||
|  |         default: | ||||||
|  |           if (rawData.containsKey('entities')) { | ||||||
|  |             return EntitiesCardData(rawData); | ||||||
|  |           } else if (rawData.containsKey('entity')) { | ||||||
|  |             rawData['entities'] = [rawData['entity']]; | ||||||
|  |             return EntitiesCardData(rawData); | ||||||
|  |           } | ||||||
|  |           return CardData(rawData); | ||||||
|  |       } | ||||||
|  |     } catch (error) { | ||||||
|  |       Logger.e('Error parsing card: $error'); | ||||||
|  |       return ErrorCardData(rawData); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   CardData(Map<String, dynamic> rawData) { |   CardData(Map<String, dynamic> rawData) { | ||||||
|     type = rawData['type'] ?? CardType.ENTITIES; |     if (rawData != null) { | ||||||
|     conditions = rawData['conditions'] ?? []; |       type = rawData['type'] ?? CardType.ENTITIES; | ||||||
|     showEmpty = rawData['show_empty'] ?? true; |       conditions = rawData['conditions'] ?? []; | ||||||
|     stateFilter = rawData['state_filter'] ?? []; |       showEmpty = rawData['show_empty'] ?? true; | ||||||
|  |       stateFilter = rawData['state_filter'] ?? []; | ||||||
|  |     } else { | ||||||
|  |       type = CardType.UNKNOWN; | ||||||
|  |       conditions = []; | ||||||
|  |       showEmpty = true; | ||||||
|  |       stateFilter = []; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Widget buildCardWidget() { |   Widget buildCardWidget() { | ||||||
| @@ -288,7 +300,7 @@ class ButtonCardData extends CardData { | |||||||
|   ButtonCardData(Map<String, dynamic> rawData) : super(rawData) { |   ButtonCardData(Map<String, dynamic> rawData) : super(rawData) { | ||||||
|     //Parsing card data |     //Parsing card data | ||||||
|     name = rawData['name']; |     name = rawData['name']; | ||||||
|     icon = rawData['icon']; |     icon = rawData['icondd'].replace('d',''); | ||||||
|     showName = rawData['show_name'] ?? true; |     showName = rawData['show_name'] ?? true; | ||||||
|     showIcon = rawData['show_icon'] ?? true; |     showIcon = rawData['show_icon'] ?? true; | ||||||
|     stateColor = rawData['state_color'] ?? true; |     stateColor = rawData['state_color'] ?? true; | ||||||
| @@ -508,3 +520,18 @@ class MediaControlCardData extends CardData { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | class ErrorCardData extends CardData { | ||||||
|  |  | ||||||
|  |   String cardConfig; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget buildCardWidget() { | ||||||
|  |     return ErrorCard(card: this); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ErrorCardData(Map<String, dynamic> rawData) : super(rawData) { | ||||||
|  |     cardConfig = '$rawData'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								lib/cards/error_card.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								lib/cards/error_card.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | part of '../main.dart'; | ||||||
|  |  | ||||||
|  | class ErrorCard extends StatelessWidget { | ||||||
|  |   final ErrorCardData card; | ||||||
|  |  | ||||||
|  |   const ErrorCard({Key key, this.card}) : super(key: key); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return CardWrapper( | ||||||
|  |       child: Padding( | ||||||
|  |         padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, Sizes.rowPadding), | ||||||
|  |         child: Column( | ||||||
|  |           mainAxisSize: MainAxisSize.min, | ||||||
|  |           crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|  |           children: <Widget>[ | ||||||
|  |             Text( | ||||||
|  |               'There was an error rendering card: ${card.type}. Please copy card config to clipboard and report this issue. Thanks!', | ||||||
|  |               textAlign: TextAlign.center, | ||||||
|  |             ), | ||||||
|  |             RaisedButton( | ||||||
|  |               onPressed: () { | ||||||
|  |                 Clipboard.setData(new ClipboardData(text: card.cardConfig)); | ||||||
|  |               }, | ||||||
|  |               child: Text('Copy card config'), | ||||||
|  |             ), | ||||||
|  |             RaisedButton( | ||||||
|  |               onPressed: () { | ||||||
|  |                 Launcher.launchURL("https://github.com/estevez-dev/ha_client/issues/new?assignees=&labels=&template=bug_report.md&title="); | ||||||
|  |               }, | ||||||
|  |               child: Text('Report issue'), | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ) | ||||||
|  |     ); | ||||||
|  |   }   | ||||||
|  | } | ||||||
| @@ -119,6 +119,7 @@ class CardType { | |||||||
|   static const MARKDOWN = "markdown"; |   static const MARKDOWN = "markdown"; | ||||||
|   static const LIGHT = "light"; |   static const LIGHT = "light"; | ||||||
|   static const ENTITY_FILTER = "entity-filter"; |   static const ENTITY_FILTER = "entity-filter"; | ||||||
|  |   static const UNKNOWN = "unknown"; | ||||||
| } | } | ||||||
|  |  | ||||||
| class Sizes { | class Sizes { | ||||||
|   | |||||||
| @@ -142,6 +142,7 @@ part 'cards/horizontal_srack_card.dart'; | |||||||
| part 'cards/markdown_card.dart'; | part 'cards/markdown_card.dart'; | ||||||
| part 'cards/media_control_card.dart'; | part 'cards/media_control_card.dart'; | ||||||
| part 'cards/unsupported_card.dart'; | part 'cards/unsupported_card.dart'; | ||||||
|  | part 'cards/error_card.dart'; | ||||||
| part 'cards/vertical_stack_card.dart'; | part 'cards/vertical_stack_card.dart'; | ||||||
| part 'cards/glance_card.dart'; | part 'cards/glance_card.dart'; | ||||||
| part 'pages/play_media.page.dart'; | part 'pages/play_media.page.dart'; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user