Handle card rendering errors to show in ui

This commit is contained in:
Yegor Vialov 2020-04-29 07:45:15 +00:00
parent 7d746fd546
commit bc045344a5
4 changed files with 122 additions and 55 deletions

View File

@ -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
View 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'),
)
],
),
)
);
}
}

View File

@ -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 {

View File

@ -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';