Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
a8500d44e1 | |||
b4d4c5abec | |||
c19a3f272a | |||
b264534858 | |||
ab53f77f9e | |||
c73956720c | |||
051041e794 | |||
5c83be9fee | |||
4bece42693 | |||
4ae107fe4c | |||
9523ed2562 | |||
9c403480e2 | |||
20b1b90e39 | |||
5633e30448 |
1
docs/empty
Normal file
1
docs/empty
Normal file
@ -0,0 +1 @@
|
||||
|
BIN
docs/ha_access_tokens.png
Normal file
BIN
docs/ha_access_tokens.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
docs/ha_profile-300x247.png
Normal file
BIN
docs/ha_profile-300x247.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
docs/settings-869x1024.png
Normal file
BIN
docs/settings-869x1024.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
@ -38,6 +38,8 @@ class EntityTapAction {
|
||||
}
|
||||
|
||||
class CardType {
|
||||
static const horizontalStack = "horizontal-stack";
|
||||
static const verticalStack = "vertical-stack";
|
||||
static const entities = "entities";
|
||||
static const glance = "glance";
|
||||
static const mediaControl = "media-control";
|
||||
|
@ -91,13 +91,6 @@ class Entity {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildGlanceWidget(BuildContext context, bool showName, bool showState) {
|
||||
return GlanceEntityContainer(
|
||||
showName: showName,
|
||||
showState: showState,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
return SimpleEntityState();
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ class EntityWrapper {
|
||||
}
|
||||
|
||||
void handleTap() {
|
||||
TheLogger.debug(tapAction);
|
||||
switch (tapAction) {
|
||||
case EntityTapAction.toggle: {
|
||||
eventBus.fire(
|
||||
|
45
lib/entity_widgets/button_entity_container.dart
Normal file
45
lib/entity_widgets/button_entity_container.dart
Normal file
@ -0,0 +1,45 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class ButtonEntityContainer extends StatelessWidget {
|
||||
|
||||
ButtonEntityContainer({
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final EntityWrapper entityWrapper = EntityModel.of(context).entityWrapper;
|
||||
|
||||
return InkWell(
|
||||
onTap: () => entityWrapper.handleTap(),
|
||||
onLongPress: () => entityWrapper.handleHold(),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
FractionallySizedBox(
|
||||
widthFactor: 0.4,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.fitHeight,
|
||||
child: EntityIcon(
|
||||
padding: EdgeInsets.fromLTRB(2.0, 6.0, 2.0, 2.0),
|
||||
iconSize: Sizes.iconSize,
|
||||
)
|
||||
),
|
||||
),
|
||||
_buildName()
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildName() {
|
||||
return EntityName(
|
||||
padding: EdgeInsets.fromLTRB(Sizes.buttonPadding, 0.0, Sizes.buttonPadding, Sizes.rowPadding),
|
||||
textOverflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
wordsWrap: true,
|
||||
textAlign: TextAlign.center,
|
||||
fontSize: Sizes.nameFontSize,
|
||||
);
|
||||
}
|
||||
}
|
@ -7,8 +7,9 @@ class EntityName extends StatelessWidget {
|
||||
final bool wordsWrap;
|
||||
final double fontSize;
|
||||
final TextAlign textAlign;
|
||||
final int maxLines;
|
||||
|
||||
const EntityName({Key key, this.padding: const EdgeInsets.only(right: 10.0), this.textOverflow: TextOverflow.ellipsis, this.wordsWrap: true, this.fontSize: Sizes.nameFontSize, this.textAlign: TextAlign.left}) : super(key: key);
|
||||
const EntityName({Key key, this.maxLines, this.padding: const EdgeInsets.only(right: 10.0), this.textOverflow: TextOverflow.ellipsis, this.wordsWrap: true, this.fontSize: Sizes.nameFontSize, this.textAlign: TextAlign.left}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -19,6 +20,7 @@ class EntityName extends StatelessWidget {
|
||||
"${entityWrapper.displayName}",
|
||||
overflow: textOverflow,
|
||||
softWrap: wordsWrap,
|
||||
maxLines: maxLines,
|
||||
style: TextStyle(fontSize: fontSize),
|
||||
textAlign: textAlign,
|
||||
),
|
||||
|
@ -4,41 +4,52 @@ class GlanceEntityContainer extends StatelessWidget {
|
||||
|
||||
final bool showName;
|
||||
final bool showState;
|
||||
final bool nameInTheBottom;
|
||||
final double iconSize;
|
||||
final double nameFontSize;
|
||||
final bool wordsWrapInName;
|
||||
|
||||
GlanceEntityContainer({
|
||||
Key key, @required this.showName, @required this.showState,
|
||||
Key key,
|
||||
@required this.showName,
|
||||
@required this.showState,
|
||||
this.nameInTheBottom: false,
|
||||
this.iconSize: Sizes.iconSize,
|
||||
this.nameFontSize: Sizes.smallFontSize,
|
||||
this.wordsWrapInName: false
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final EntityWrapper entityWrapper = EntityModel.of(context).entityWrapper;
|
||||
List<Widget> result = [];
|
||||
if (showName) {
|
||||
result.add(EntityName(
|
||||
padding: EdgeInsets.only(bottom: Sizes.rowPadding),
|
||||
textOverflow: TextOverflow.ellipsis,
|
||||
wordsWrap: false,
|
||||
textAlign: TextAlign.center,
|
||||
fontSize: Sizes.smallFontSize,
|
||||
));
|
||||
if (!nameInTheBottom) {
|
||||
if (showName) {
|
||||
result.add(_buildName());
|
||||
}
|
||||
} else {
|
||||
if (showState) {
|
||||
result.add(_buildState());
|
||||
}
|
||||
}
|
||||
result.add(
|
||||
EntityIcon(
|
||||
padding: EdgeInsets.all(0.0),
|
||||
iconSize: Sizes.iconSize,
|
||||
iconSize: iconSize,
|
||||
)
|
||||
);
|
||||
if (showState) {
|
||||
result.add(SimpleEntityState(
|
||||
textAlign: TextAlign.center,
|
||||
expanded: false,
|
||||
padding: EdgeInsets.only(top: Sizes.rowPadding),
|
||||
));
|
||||
if (!nameInTheBottom) {
|
||||
if (showState) {
|
||||
result.add(_buildState());
|
||||
}
|
||||
} else {
|
||||
result.add(_buildName());
|
||||
}
|
||||
|
||||
return Center(
|
||||
child: InkResponse(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(minWidth: Sizes.iconSize*2),
|
||||
constraints: BoxConstraints(minWidth: Sizes.iconSize * 2),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
//mainAxisAlignment: MainAxisAlignment.start,
|
||||
@ -51,4 +62,23 @@ class GlanceEntityContainer extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildName() {
|
||||
return EntityName(
|
||||
padding: EdgeInsets.only(bottom: Sizes.rowPadding),
|
||||
textOverflow: TextOverflow.ellipsis,
|
||||
wordsWrap: wordsWrapInName,
|
||||
textAlign: TextAlign.center,
|
||||
fontSize: nameFontSize,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildState() {
|
||||
return SimpleEntityState(
|
||||
textAlign: TextAlign.center,
|
||||
expanded: false,
|
||||
maxLines: 1,
|
||||
padding: EdgeInsets.only(top: Sizes.rowPadding),
|
||||
);
|
||||
}
|
||||
}
|
@ -5,8 +5,9 @@ class SimpleEntityState extends StatelessWidget {
|
||||
final bool expanded;
|
||||
final TextAlign textAlign;
|
||||
final EdgeInsetsGeometry padding;
|
||||
final int maxLines;
|
||||
|
||||
const SimpleEntityState({Key key, this.expanded: true, this.textAlign: TextAlign.right, this.padding: const EdgeInsets.fromLTRB(0.0, 0.0, Sizes.rightWidgetPadding, 0.0)}) : super(key: key);
|
||||
const SimpleEntityState({Key key, this.maxLines: 10, this.expanded: true, this.textAlign: TextAlign.right, this.padding: const EdgeInsets.fromLTRB(0.0, 0.0, Sizes.rightWidgetPadding, 0.0)}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -16,7 +17,7 @@ class SimpleEntityState extends StatelessWidget {
|
||||
child: Text(
|
||||
"${entityModel.entityWrapper.entity.state} ${entityModel.entityWrapper.entity.unitOfMeasurement}",
|
||||
textAlign: textAlign,
|
||||
maxLines: 10,
|
||||
maxLines: maxLines,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
style: new TextStyle(
|
||||
|
@ -428,64 +428,96 @@ class HomeAssistant {
|
||||
List<HACard> _createLovelaceCards(List rawCards) {
|
||||
List<HACard> result = [];
|
||||
rawCards.forEach((rawCard){
|
||||
bool isThereCardOptionsInside = rawCard["card"] != null;
|
||||
HACard card = HACard(
|
||||
id: "card",
|
||||
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) {
|
||||
result.addAll(_createLovelaceCards(rawCard["cards"]));
|
||||
} else {
|
||||
HACard card = HACard(
|
||||
id: "card",
|
||||
name: rawCard["title"],
|
||||
type: rawCard['type'],
|
||||
columnsCount: rawCard['columns'] ?? 4,
|
||||
showName: rawCard['show_name'] ?? true,
|
||||
showState: rawCard['show_state'] ?? true,
|
||||
);
|
||||
rawCard["entities"]?.forEach((rawEntity) {
|
||||
if (rawEntity is String) {
|
||||
if (entities.isExist(rawEntity)) {
|
||||
card.entities.add(EntityWrapper(entity: entities.get(rawEntity)));
|
||||
}
|
||||
} else {
|
||||
if (entities.isExist(rawEntity["entity"])) {
|
||||
Entity e = entities.get(rawEntity["entity"]);
|
||||
String tapAction = EntityTapAction.moreInfo;
|
||||
String holdAction = EntityTapAction.none;
|
||||
if (card.type == CardType.glance) {
|
||||
tapAction = rawEntity["tap_action"] ?? EntityTapAction.moreInfo;
|
||||
holdAction = rawEntity["hold_action"] ?? EntityTapAction.none;
|
||||
card.childCards = _createLovelaceCards(rawCard["cards"]);
|
||||
}
|
||||
rawCard["entities"]?.forEach((rawEntity) {
|
||||
if (rawEntity is String) {
|
||||
if (entities.isExist(rawEntity)) {
|
||||
card.entities.add(EntityWrapper(entity: entities.get(rawEntity)));
|
||||
}
|
||||
} else {
|
||||
if (entities.isExist(rawEntity["entity"])) {
|
||||
Entity e = entities.get(rawEntity["entity"]);
|
||||
String tapAction = EntityTapAction.moreInfo;
|
||||
String holdAction = EntityTapAction.none;
|
||||
if (card.type == CardType.glance || card.type == CardType.entityButton) {
|
||||
if (rawEntity["tap_action"] != null) {
|
||||
if (rawEntity["tap_action"] is String) {
|
||||
tapAction = rawEntity["tap_action"];
|
||||
holdAction = rawEntity["hold_action"];
|
||||
} else {
|
||||
tapAction = rawEntity["tap_action"]["action"];
|
||||
holdAction = rawEntity["hold_action"]["action"];
|
||||
}
|
||||
}
|
||||
card.entities.add(
|
||||
EntityWrapper(
|
||||
}
|
||||
card.entities.add(
|
||||
EntityWrapper(
|
||||
entity: e,
|
||||
displayName: rawEntity["name"],
|
||||
icon: rawEntity["icon"],
|
||||
tapAction: tapAction,
|
||||
holdAction: holdAction,
|
||||
tapActionService: rawEntity["service"],
|
||||
tapActionServiceData: rawEntity["service_data"] ?? {"entity_id": e.entityId}
|
||||
)
|
||||
);
|
||||
}
|
||||
//tapActionService: rawEntity["service"],
|
||||
//tapActionServiceData: rawEntity["service_data"] ?? {"entity_id": e.entityId}
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
if (rawCard["entity"] != null) {
|
||||
var en = rawCard["entity"];
|
||||
if (en is String) {
|
||||
if (entities.isExist(en)) {
|
||||
card.linkedEntity = EntityWrapper(entity: entities.get(en));
|
||||
}
|
||||
} else {
|
||||
if (entities.isExist(en["entity"])) {
|
||||
card.linkedEntity = EntityWrapper(
|
||||
entity: entities.get(en["entity"]),
|
||||
icon: en["icon"],
|
||||
displayName: en["name"]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(card);
|
||||
});
|
||||
if (rawCard["entity"] != null) {
|
||||
var en = rawCard["entity"];
|
||||
String tapAction = EntityTapAction.moreInfo;
|
||||
String holdAction = EntityTapAction.none;
|
||||
if (rawCard["tap_action"] != null) {
|
||||
if (rawCard["tap_action"] is String) {
|
||||
tapAction = rawCard["tap_action"];
|
||||
holdAction = rawCard["hold_action"];
|
||||
} else {
|
||||
tapAction = rawCard["tap_action"]["action"];
|
||||
holdAction = rawCard["hold_action"]["action"];
|
||||
}
|
||||
}
|
||||
if (en is String) {
|
||||
if (entities.isExist(en)) {
|
||||
Entity e = entities.get(en);
|
||||
card.linkedEntityWrapper = EntityWrapper(
|
||||
entity: e,
|
||||
tapAction: tapAction,
|
||||
holdAction: holdAction,
|
||||
//tapActionService: rawCard["service"],
|
||||
//tapActionServiceData: rawCard["service_data"] ?? {"entity_id": e.entityId}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (entities.isExist(en["entity"])) {
|
||||
Entity e = entities.get(en["entity"]);
|
||||
card.linkedEntityWrapper = EntityWrapper(
|
||||
entity: e,
|
||||
icon: en["icon"],
|
||||
displayName: en["name"],
|
||||
tapAction: tapAction,
|
||||
holdAction: holdAction,
|
||||
tapActionService: rawCard["service"],
|
||||
tapActionServiceData: rawCard["service_data"] ?? {"entity_id": e.entityId}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(card);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ part 'entity_widgets/common/badge.dart';
|
||||
part 'entity_widgets/model_widgets.dart';
|
||||
part 'entity_widgets/default_entity_container.dart';
|
||||
part 'entity_widgets/glance_entity_container.dart';
|
||||
part 'entity_widgets/button_entity_container.dart';
|
||||
part 'entity_widgets/common/entity_attributes_list.dart';
|
||||
part 'entity_widgets/entity_icon.dart';
|
||||
part 'entity_widgets/entity_name.dart';
|
||||
@ -78,16 +79,13 @@ 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/unsupported_card.dart';
|
||||
part 'ui_widgets/media_control_card.dart';
|
||||
part 'ui_widgets/card_widget.dart';
|
||||
part 'ui_widgets/card_header_widget.dart';
|
||||
|
||||
|
||||
EventBus eventBus = new EventBus();
|
||||
const String appName = "HA Client";
|
||||
const appVersion = "0.3.10";
|
||||
const appVersion = "0.3.11";
|
||||
|
||||
String homeAssistantWebHost;
|
||||
|
||||
|
@ -2,76 +2,45 @@ part of '../main.dart';
|
||||
|
||||
class HACard {
|
||||
List<EntityWrapper> entities = [];
|
||||
EntityWrapper linkedEntity;
|
||||
List<HACard> childCards = [];
|
||||
EntityWrapper linkedEntityWrapper;
|
||||
String name;
|
||||
String id;
|
||||
String type;
|
||||
bool showName;
|
||||
bool showState;
|
||||
bool showEmpty;
|
||||
int columnsCount;
|
||||
List stateFilter;
|
||||
|
||||
HACard({
|
||||
this.name,
|
||||
this.id,
|
||||
this.linkedEntity,
|
||||
this.linkedEntityWrapper,
|
||||
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.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.entityButton:
|
||||
case CardType.conditional:
|
||||
case CardType.alarmPanel: {
|
||||
return UnsupportedCardWidget(
|
||||
card: this,
|
||||
);
|
||||
}
|
||||
|
||||
default: {
|
||||
if ((linkedEntity == null) && (entities.isNotEmpty)) {
|
||||
return EntitiesCardWidget(
|
||||
card: this,
|
||||
);
|
||||
} else {
|
||||
return UnsupportedCardWidget(
|
||||
card: this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List<EntityWrapper> 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,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -3,9 +3,10 @@ part of '../main.dart';
|
||||
class Sizes {
|
||||
static const rightWidgetPadding = 14.0;
|
||||
static const leftWidgetPadding = 8.0;
|
||||
static const buttonPadding = 4.0;
|
||||
static const extendedWidgetHeight = 50.0;
|
||||
static const iconSize = 28.0;
|
||||
static const largeIconSize = 34.0;
|
||||
static const largeIconSize = 46.0;
|
||||
static const stateFontSize = 15.0;
|
||||
static const nameFontSize = 15.0;
|
||||
static const smallFontSize = 14.0;
|
||||
|
@ -28,8 +28,8 @@ class HAView {
|
||||
HACard card = HACard(
|
||||
name: e.displayName,
|
||||
id: e.entityId,
|
||||
linkedEntity: EntityWrapper(entity: e),
|
||||
type: "media-control"
|
||||
linkedEntityWrapper: EntityWrapper(entity: e),
|
||||
type: CardType.mediaControl
|
||||
);
|
||||
cards.add(card);
|
||||
});
|
||||
@ -40,7 +40,7 @@ class HAView {
|
||||
HACard card = HACard(
|
||||
id: groupIdToAdd,
|
||||
name: entity.domain,
|
||||
type: "entities"
|
||||
type: CardType.entities
|
||||
);
|
||||
card.entities.add(EntityWrapper(entity: entity));
|
||||
autoGeneratedCards.add(card);
|
||||
@ -51,16 +51,16 @@ class HAView {
|
||||
HACard card = HACard(
|
||||
name: entity.displayName,
|
||||
id: entity.entityId,
|
||||
linkedEntity: EntityWrapper(entity: entity),
|
||||
type: "entities"
|
||||
linkedEntityWrapper: EntityWrapper(entity: entity),
|
||||
type: CardType.entities
|
||||
);
|
||||
card.entities.addAll(entity.childEntities.where((entity) {return entity.domain != "media_player";}).map((e) {return EntityWrapper(entity: e);}));
|
||||
entity.childEntities.where((entity) {return entity.domain == "media_player";}).forEach((entity){
|
||||
HACard mediaCard = HACard(
|
||||
name: entity.displayName,
|
||||
id: entity.entityId,
|
||||
linkedEntity: EntityWrapper(entity: entity),
|
||||
type: "media-control"
|
||||
linkedEntityWrapper: EntityWrapper(entity: entity),
|
||||
type: CardType.mediaControl
|
||||
);
|
||||
cards.add(mediaCard);
|
||||
});
|
||||
|
206
lib/ui_widgets/card_widget.dart
Normal file
206
lib/ui_widgets/card_widget.dart
Normal file
@ -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<Widget> 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<Widget> 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<EntityWrapper> entitiesToShow = card.getEntitiesToShow();
|
||||
if (entitiesToShow.isEmpty && !card.showEmpty) {
|
||||
return Container(height: 0.0, width: 0.0,);
|
||||
}
|
||||
List<Widget> 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<EntityWrapper> entitiesToShow = card.getEntitiesToShow();
|
||||
if (entitiesToShow.isEmpty && !card.showEmpty) {
|
||||
return Container(height: 0.0, width: 0.0,);
|
||||
}
|
||||
List<Widget> rows = [];
|
||||
rows.add(CardHeaderWidget(name: card.name));
|
||||
|
||||
List<Widget> 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<Widget> body = [];
|
||||
body.add(CardHeaderWidget(name: card.name ?? ""));
|
||||
List<Widget> result = [];
|
||||
if (card.linkedEntityWrapper != null) {
|
||||
result.addAll(<Widget>[
|
||||
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(<Widget>[
|
||||
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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -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.linkedEntity!= null) && (card.linkedEntity.entity.isHidden)) {
|
||||
return Container(width: 0.0, height: 0.0,);
|
||||
}
|
||||
List<Widget> body = [];
|
||||
body.add(CardHeaderWidget(name: card.name));
|
||||
body.addAll(_buildCardBody(context));
|
||||
return Card(
|
||||
child: new Column(mainAxisSize: MainAxisSize.min, children: body)
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildCardBody(BuildContext context) {
|
||||
List<Widget> 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;
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +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.linkedEntity!= null) && (card.linkedEntity.entity.isHidden)) {
|
||||
return Container(width: 0.0, height: 0.0,);
|
||||
}
|
||||
List<Widget> 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<Widget> result = [];
|
||||
List<EntityWrapper> 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: entity.entity.buildGlanceWidget(context, card.showName, 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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -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.linkedEntity == null) || (card.linkedEntity.entity.isHidden)) {
|
||||
return Container(width: 0.0, height: 0.0,);
|
||||
}
|
||||
|
||||
return Card(
|
||||
child: EntityModel(
|
||||
entityWrapper: card.linkedEntity,
|
||||
handleTap: null,
|
||||
child: MediaPlayerWidget()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -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.linkedEntity!= null) && (card.linkedEntity.entity.isHidden)) {
|
||||
return Container(width: 0.0, height: 0.0,);
|
||||
}
|
||||
List<Widget> 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<Widget> _buildCardBody(BuildContext context) {
|
||||
List<Widget> result = [];
|
||||
if (card.linkedEntity != null) {
|
||||
result.addAll(<Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding),
|
||||
child: EntityModel(
|
||||
entityWrapper: card.linkedEntity,
|
||||
handleTap: true,
|
||||
child: card.linkedEntity.entity.buildDefaultWidget(context)
|
||||
),
|
||||
)
|
||||
]);
|
||||
} else {
|
||||
result.addAll(<Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, Sizes.rowPadding),
|
||||
child: Text("'${card.type}' card is not supported yet"),
|
||||
),
|
||||
]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
12
pubspec.lock
12
pubspec.lock
@ -35,7 +35,7 @@ packages:
|
||||
name: cached_network_image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0+1"
|
||||
version: "0.5.1"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -83,7 +83,7 @@ packages:
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: c5727795659e886a7db8b39a14e2c8987280fe1f
|
||||
resolved-ref: e26916e095244a7e5ea61315b030d298d127ed26
|
||||
url: "https://github.com/MarkOSullivan94/dart_config.git"
|
||||
source: git
|
||||
version: "0.5.0"
|
||||
@ -126,7 +126,7 @@ packages:
|
||||
name: flutter_launcher_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
version: "0.7.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -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:
|
||||
@ -327,5 +327,5 @@ packages:
|
||||
source: hosted
|
||||
version: "2.1.15"
|
||||
sdks:
|
||||
dart: ">=2.0.0 <=2.1.0-dev.9.3.flutter-9c07fb64c4"
|
||||
dart: ">=2.0.0 <3.0.0"
|
||||
flutter: ">=0.5.6 <2.0.0"
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: hass_client
|
||||
description: Home Assistant Android Client
|
||||
|
||||
version: 0.3.10+74
|
||||
version: 0.3.11+78
|
||||
|
||||
environment:
|
||||
sdk: ">=2.0.0-dev.68.0 <3.0.0"
|
||||
|
Reference in New Issue
Block a user