From bc045344a54ec70fad6d6106751cbc69675d38ca Mon Sep 17 00:00:00 2001 From: Yegor Vialov Date: Wed, 29 Apr 2020 07:45:15 +0000 Subject: [PATCH] Handle card rendering errors to show in ui --- lib/cards/card.class.dart | 137 +++++++++++++++++++++++--------------- lib/cards/error_card.dart | 38 +++++++++++ lib/const.dart | 1 + lib/main.dart | 1 + 4 files changed, 122 insertions(+), 55 deletions(-) create mode 100644 lib/cards/error_card.dart diff --git a/lib/cards/card.class.dart b/lib/cards/card.class.dart index 29c1b6c..a7f6b34 100644 --- a/lib/cards/card.class.dart +++ b/lib/cards/card.class.dart @@ -12,65 +12,77 @@ class CardData { EntityWrapper get entity => entities.isNotEmpty ? entities[0] : null; factory CardData.parse(Map rawData) { - switch (rawData['type']) { - case CardType.ENTITIES: - return EntitiesCardData(rawData); - 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 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')) { + try { + switch (rawData['type']) { + case CardType.ENTITIES: return EntitiesCardData(rawData); - } else if (rawData.containsKey('entity')) { - rawData['entities'] = [rawData['entity']]; - return EntitiesCardData(rawData); - } - return CardData(rawData); + 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 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 rawData) { - type = rawData['type'] ?? CardType.ENTITIES; - conditions = rawData['conditions'] ?? []; - showEmpty = rawData['show_empty'] ?? true; - stateFilter = rawData['state_filter'] ?? []; + if (rawData != null) { + type = rawData['type'] ?? CardType.ENTITIES; + conditions = rawData['conditions'] ?? []; + showEmpty = rawData['show_empty'] ?? true; + stateFilter = rawData['state_filter'] ?? []; + } else { + type = CardType.UNKNOWN; + conditions = []; + showEmpty = true; + stateFilter = []; + } } Widget buildCardWidget() { @@ -288,7 +300,7 @@ class ButtonCardData extends CardData { ButtonCardData(Map rawData) : super(rawData) { //Parsing card data name = rawData['name']; - icon = rawData['icon']; + icon = rawData['icondd'].replace('d',''); showName = rawData['show_name'] ?? true; showIcon = rawData['show_icon'] ?? 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 rawData) : super(rawData) { + cardConfig = '$rawData'; + } + +} diff --git a/lib/cards/error_card.dart b/lib/cards/error_card.dart new file mode 100644 index 0000000..523f933 --- /dev/null +++ b/lib/cards/error_card.dart @@ -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: [ + 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'), + ) + ], + ), + ) + ); + } +} \ No newline at end of file diff --git a/lib/const.dart b/lib/const.dart index 639b580..f38bcf2 100644 --- a/lib/const.dart +++ b/lib/const.dart @@ -119,6 +119,7 @@ class CardType { static const MARKDOWN = "markdown"; static const LIGHT = "light"; static const ENTITY_FILTER = "entity-filter"; + static const UNKNOWN = "unknown"; } class Sizes { diff --git a/lib/main.dart b/lib/main.dart index b2a7d47..bd532b3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -142,6 +142,7 @@ part 'cards/horizontal_srack_card.dart'; part 'cards/markdown_card.dart'; part 'cards/media_control_card.dart'; part 'cards/unsupported_card.dart'; +part 'cards/error_card.dart'; part 'cards/vertical_stack_card.dart'; part 'cards/glance_card.dart'; part 'pages/play_media.page.dart';