From 5c83be9fee18107e8d6af8be368c253ce3c8eb0e Mon Sep 17 00:00:00 2001 From: Yegor Vialov Date: Fri, 7 Dec 2018 22:04:14 +0200 Subject: [PATCH] Resolves #207 Entity filter card support --- lib/home_assistant.class.dart | 13 +- lib/main.dart | 6 +- lib/ui_class/card.class.dart | 113 +++----------- lib/ui_widgets/card_widget.dart | 206 +++++++++++++++++++++++++ lib/ui_widgets/entities_card.dart | 43 ------ lib/ui_widgets/entity_button_card.dart | 27 ---- lib/ui_widgets/glance_card.dart | 55 ------- lib/ui_widgets/media_control_card.dart | 29 ---- lib/ui_widgets/unsupported_card.dart | 53 ------- pubspec.lock | 4 +- 10 files changed, 236 insertions(+), 313 deletions(-) create mode 100644 lib/ui_widgets/card_widget.dart delete mode 100644 lib/ui_widgets/entities_card.dart delete mode 100644 lib/ui_widgets/entity_button_card.dart delete mode 100644 lib/ui_widgets/glance_card.dart delete mode 100644 lib/ui_widgets/media_control_card.dart delete mode 100644 lib/ui_widgets/unsupported_card.dart diff --git a/lib/home_assistant.class.dart b/lib/home_assistant.class.dart index d0e64cb..4f28705 100644 --- a/lib/home_assistant.class.dart +++ b/lib/home_assistant.class.dart @@ -428,13 +428,16 @@ class HomeAssistant { List _createLovelaceCards(List rawCards) { List result = []; rawCards.forEach((rawCard){ + bool isThereCardOptionsInside = rawCard["card"] != null; HACard card = HACard( id: "card", - name: rawCard["title"] ?? rawCard["name"], - type: rawCard['type'], - columnsCount: rawCard['columns'] ?? 4, - showName: rawCard['show_name'] ?? true, - showState: rawCard['show_state'] ?? true, + name: isThereCardOptionsInside ? rawCard["card"]["title"] ?? rawCard["card"]["name"] : rawCard["title"] ?? rawCard["name"], + type: isThereCardOptionsInside ? rawCard["card"]['type'] : rawCard['type'], + columnsCount: isThereCardOptionsInside ? rawCard["card"]['columns'] ?? 4 : rawCard['columns'] ?? 4, + showName: isThereCardOptionsInside ? rawCard["card"]['show_name'] ?? true : rawCard['show_name'] ?? true, + showState: isThereCardOptionsInside ? rawCard["card"]['show_state'] ?? true : rawCard['show_state'] ?? true, + showEmpty: rawCard['show_empty'] ?? true, + stateFilter: rawCard['state_filter'] ?? [] ); if (rawCard["cards"] != null) { card.childCards = _createLovelaceCards(rawCard["cards"]); diff --git a/lib/main.dart b/lib/main.dart index 47bac4c..3ffd0c4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -79,11 +79,7 @@ part 'ui_class/view.class.dart'; part 'ui_class/card.class.dart'; part 'ui_class/sizes_class.dart'; part 'ui_widgets/view.dart'; -part 'ui_widgets/entities_card.dart'; -part 'ui_widgets/glance_card.dart'; -part 'ui_widgets/entity_button_card.dart'; -part 'ui_widgets/unsupported_card.dart'; -part 'ui_widgets/media_control_card.dart'; +part 'ui_widgets/card_widget.dart'; part 'ui_widgets/card_header_widget.dart'; diff --git a/lib/ui_class/card.class.dart b/lib/ui_class/card.class.dart index 9e73f8e..dad72da 100644 --- a/lib/ui_class/card.class.dart +++ b/lib/ui_class/card.class.dart @@ -9,7 +9,9 @@ class HACard { String type; bool showName; bool showState; + bool showEmpty; int columnsCount; + List stateFilter; HACard({ this.name, @@ -18,104 +20,27 @@ class HACard { this.columnsCount: 4, this.showName: true, this.showState: true, + this.stateFilter: const [], + this.showEmpty: true, @required this.type }); - Widget build(BuildContext context) { - switch (type) { - - case CardType.entities: { - return EntitiesCardWidget( - card: this, - ); - } - - case CardType.glance: { - return GlanceCardWidget( - card: this, - ); - } - - case CardType.mediaControl: { - return MediaControlCardWidget( - card: this, - ); - } - - case CardType.entityButton: { - return EntityButtonCardWidget( - card: this, - ); - } - - case CardType.horizontalStack: { - if (childCards.isNotEmpty) { - List children = []; - childCards.forEach((card) { - children.add( - Flexible( - fit: FlexFit.tight, - child: card.build(context), - ) - ); - }); - return Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: children, - ); - } - return Container(height: 0.0, width: 0.0,); - } - - case CardType.verticalStack: { - if (childCards.isNotEmpty) { - List children = []; - childCards.forEach((card) { - children.add( - card.build(context) - ); - }); - return Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - children: children, - ); - } - return Container(height: 0.0, width: 0.0,); - } - - case CardType.weatherForecast: - case CardType.thermostat: - case CardType.sensor: - case CardType.plantStatus: - case CardType.pictureEntity: - case CardType.pictureElements: - case CardType.picture: - case CardType.map: - case CardType.iframe: - case CardType.gauge: - case CardType.conditional: - case CardType.alarmPanel: { - return UnsupportedCardWidget( - card: this, - ); - } - - default: { - if ((linkedEntityWrapper == null) && (entities.isNotEmpty)) { - return EntitiesCardWidget( - card: this, - ); - } else { - return UnsupportedCardWidget( - card: this, - ); - } - } - + List getEntitiesToShow() { + return entities.where((entityWrapper) { + if (entityWrapper.entity.isHidden) { + return false; } + if (stateFilter.isNotEmpty) { + return stateFilter.contains(entityWrapper.entity.state); + } + return true; + }).toList(); + } + + Widget build(BuildContext context) { + return CardWidget( + card: this, + ); } } \ No newline at end of file diff --git a/lib/ui_widgets/card_widget.dart b/lib/ui_widgets/card_widget.dart new file mode 100644 index 0000000..2ff2412 --- /dev/null +++ b/lib/ui_widgets/card_widget.dart @@ -0,0 +1,206 @@ +part of '../main.dart'; + +class CardWidget extends StatelessWidget { + + final HACard card; + + const CardWidget({ + Key key, + this.card + }) : super(key: key); + + @override + Widget build(BuildContext context) { + if ((card.linkedEntityWrapper!= null) && (card.linkedEntityWrapper.entity.isHidden)) { + return Container(width: 0.0, height: 0.0,); + } + + switch (card.type) { + + case CardType.entities: { + return _buildEntitiesCard(context); + } + + case CardType.glance: { + return _buildGlanceCard(context); + } + + case CardType.mediaControl: { + return _buildMediaControlsCard(context); + } + + case CardType.entityButton: { + return _buildEntityButtonCard(context); + } + + case CardType.horizontalStack: { + if (card.childCards.isNotEmpty) { + List children = []; + card.childCards.forEach((card) { + children.add( + Flexible( + fit: FlexFit.tight, + child: card.build(context), + ) + ); + }); + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: children, + ); + } + return Container(height: 0.0, width: 0.0,); + } + + case CardType.verticalStack: { + if (card.childCards.isNotEmpty) { + List children = []; + card.childCards.forEach((card) { + children.add( + card.build(context) + ); + }); + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: children, + ); + } + return Container(height: 0.0, width: 0.0,); + } + + default: { + if ((card.linkedEntityWrapper == null) && (card.entities.isNotEmpty)) { + return _buildEntitiesCard(context); + } else { + return _buildUnsupportedCard(context); + } + } + + } + } + + Widget _buildEntitiesCard(BuildContext context) { + List entitiesToShow = card.getEntitiesToShow(); + if (entitiesToShow.isEmpty && !card.showEmpty) { + return Container(height: 0.0, width: 0.0,); + } + List body = []; + body.add(CardHeaderWidget(name: card.name)); + entitiesToShow.forEach((EntityWrapper entity) { + if (!entity.entity.isHidden) { + body.add( + Padding( + padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), + child: EntityModel( + entityWrapper: entity, + handleTap: true, + child: entity.entity.buildDefaultWidget(context) + ), + )); + } + }); + return Card( + child: new Column(mainAxisSize: MainAxisSize.min, children: body) + ); + } + + Widget _buildGlanceCard(BuildContext context) { + List entitiesToShow = card.getEntitiesToShow(); + if (entitiesToShow.isEmpty && !card.showEmpty) { + return Container(height: 0.0, width: 0.0,); + } + List rows = []; + rows.add(CardHeaderWidget(name: card.name)); + + List result = []; + int columnsCount = entitiesToShow.length >= card.columnsCount ? card.columnsCount : entitiesToShow.length; + + entitiesToShow.forEach((EntityWrapper entity) { + result.add( + FractionallySizedBox( + widthFactor: 1/columnsCount, + child: EntityModel( + entityWrapper: entity, + child: GlanceEntityContainer( + showName: card.showName, + showState: card.showState, + ), + handleTap: true + ), + ) + ); + }); + rows.add( + Padding( + padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, 2*Sizes.rowPadding), + child: Wrap( + //alignment: WrapAlignment.spaceAround, + runSpacing: Sizes.rowPadding*2, + children: result, + ), + ) + ); + + return Card( + child: new Column(mainAxisSize: MainAxisSize.min, children: rows) + ); + } + + Widget _buildMediaControlsCard(BuildContext context) { + return Card( + child: EntityModel( + entityWrapper: card.linkedEntityWrapper, + handleTap: null, + child: MediaPlayerWidget() + ) + ); + } + + Widget _buildEntityButtonCard(BuildContext context) { + card.linkedEntityWrapper.displayName = card.name?.toUpperCase() ?? card.linkedEntityWrapper.displayName.toUpperCase(); + return Card( + child: EntityModel( + entityWrapper: card.linkedEntityWrapper, + child: ButtonEntityContainer(), + handleTap: true + ) + ); + } + + Widget _buildUnsupportedCard(BuildContext context) { + List body = []; + body.add(CardHeaderWidget(name: card.name ?? "")); + List result = []; + if (card.linkedEntityWrapper != null) { + result.addAll([ + Padding( + padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), + child: EntityModel( + entityWrapper: card.linkedEntityWrapper, + handleTap: true, + child: card.linkedEntityWrapper.entity.buildDefaultWidget(context) + ), + ) + ]); + } else { + result.addAll([ + Padding( + padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, Sizes.rowPadding), + child: Text("'${card.type}' card is not supported yet"), + ), + ]); + } + body.addAll(result); + return Card( + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: body + ) + ); + } + +} \ No newline at end of file diff --git a/lib/ui_widgets/entities_card.dart b/lib/ui_widgets/entities_card.dart deleted file mode 100644 index 2dc16a8..0000000 --- a/lib/ui_widgets/entities_card.dart +++ /dev/null @@ -1,43 +0,0 @@ -part of '../main.dart'; - -class EntitiesCardWidget extends StatelessWidget { - - final HACard card; - - const EntitiesCardWidget({ - Key key, - this.card - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if ((card.linkedEntityWrapper!= null) && (card.linkedEntityWrapper.entity.isHidden)) { - return Container(width: 0.0, height: 0.0,); - } - List body = []; - body.add(CardHeaderWidget(name: card.name)); - body.addAll(_buildCardBody(context)); - return Card( - child: new Column(mainAxisSize: MainAxisSize.min, children: body) - ); - } - - List _buildCardBody(BuildContext context) { - List result = []; - card.entities.forEach((EntityWrapper entity) { - if (!entity.entity.isHidden) { - result.add( - Padding( - padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), - child: EntityModel( - entityWrapper: entity, - handleTap: true, - child: entity.entity.buildDefaultWidget(context) - ), - )); - } - }); - return result; - } - -} \ No newline at end of file diff --git a/lib/ui_widgets/entity_button_card.dart b/lib/ui_widgets/entity_button_card.dart deleted file mode 100644 index 6a53f3d..0000000 --- a/lib/ui_widgets/entity_button_card.dart +++ /dev/null @@ -1,27 +0,0 @@ -part of '../main.dart'; - -class EntityButtonCardWidget extends StatelessWidget { - - final HACard card; - - const EntityButtonCardWidget({ - Key key, - this.card - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if (card.linkedEntityWrapper!= null && card.linkedEntityWrapper.entity.isHidden) { - return Container(width: 0.0, height: 0.0,); - } - card.linkedEntityWrapper.displayName = card.name?.toUpperCase() ?? card.linkedEntityWrapper.displayName.toUpperCase(); - return Card( - child: EntityModel( - entityWrapper: card.linkedEntityWrapper, - child: ButtonEntityContainer(), - handleTap: true - ) - ); - } - -} \ No newline at end of file diff --git a/lib/ui_widgets/glance_card.dart b/lib/ui_widgets/glance_card.dart deleted file mode 100644 index 21e8f56..0000000 --- a/lib/ui_widgets/glance_card.dart +++ /dev/null @@ -1,55 +0,0 @@ -part of '../main.dart'; - -class GlanceCardWidget extends StatelessWidget { - - final HACard card; - - const GlanceCardWidget({ - Key key, - this.card - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if ((card.linkedEntityWrapper!= null) && (card.linkedEntityWrapper.entity.isHidden)) { - return Container(width: 0.0, height: 0.0,); - } - List rows = []; - rows.add(CardHeaderWidget(name: card.name)); - rows.add(_buildRows(context)); - return Card( - child: new Column(mainAxisSize: MainAxisSize.min, children: rows) - ); - } - - Widget _buildRows(BuildContext context) { - List result = []; - List toShow = card.entities.where((entity) {return !entity.entity.isHidden;}).toList(); - int columnsCount = toShow.length >= card.columnsCount ? card.columnsCount : toShow.length; - - toShow.forEach((EntityWrapper entity) { - result.add( - FractionallySizedBox( - widthFactor: 1/columnsCount, - child: EntityModel( - entityWrapper: entity, - child: GlanceEntityContainer( - showName: card.showName, - showState: card.showState, - ), - handleTap: true - ), - ) - ); - }); - return Padding( - padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, 2*Sizes.rowPadding), - child: Wrap( - //alignment: WrapAlignment.spaceAround, - runSpacing: Sizes.rowPadding*2, - children: result, - ), - ); - } - -} \ No newline at end of file diff --git a/lib/ui_widgets/media_control_card.dart b/lib/ui_widgets/media_control_card.dart deleted file mode 100644 index b0ba69c..0000000 --- a/lib/ui_widgets/media_control_card.dart +++ /dev/null @@ -1,29 +0,0 @@ -part of '../main.dart'; - -class MediaControlCardWidget extends StatelessWidget { - - final HACard card; - - const MediaControlCardWidget({ - Key key, - this.card - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if ((card.linkedEntityWrapper == null) || (card.linkedEntityWrapper.entity.isHidden)) { - return Container(width: 0.0, height: 0.0,); - } - - return Card( - child: EntityModel( - entityWrapper: card.linkedEntityWrapper, - handleTap: null, - child: MediaPlayerWidget() - ) - ); - } - - - -} \ No newline at end of file diff --git a/lib/ui_widgets/unsupported_card.dart b/lib/ui_widgets/unsupported_card.dart deleted file mode 100644 index 0a8dcd9..0000000 --- a/lib/ui_widgets/unsupported_card.dart +++ /dev/null @@ -1,53 +0,0 @@ -part of '../main.dart'; - -class UnsupportedCardWidget extends StatelessWidget { - - final HACard card; - - const UnsupportedCardWidget({ - Key key, - this.card - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if ((card.linkedEntityWrapper!= null) && (card.linkedEntityWrapper.entity.isHidden)) { - return Container(width: 0.0, height: 0.0,); - } - List body = []; - body.add(CardHeaderWidget(name: card.name ?? "")); - body.addAll(_buildCardBody(context)); - return Card( - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: body - ) - ); - } - - List _buildCardBody(BuildContext context) { - List result = []; - if (card.linkedEntityWrapper != null) { - result.addAll([ - Padding( - padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), - child: EntityModel( - entityWrapper: card.linkedEntityWrapper, - handleTap: true, - child: card.linkedEntityWrapper.entity.buildDefaultWidget(context) - ), - ) - ]); - } else { - result.addAll([ - Padding( - padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, Sizes.rowPadding), - child: Text("'${card.type}' card is not supported yet"), - ), - ]); - } - return result; - } - -} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 149dcea..5edccb5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -152,7 +152,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" intl: dependency: transitive description: @@ -290,7 +290,7 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "4.0.2" uuid: dependency: transitive description: