WIP #183 tap_action support. State change event fix

This commit is contained in:
Yegor Vialov
2018-11-16 22:32:43 +02:00
parent 1bd04abd37
commit 82c9bd26d1
29 changed files with 89 additions and 50 deletions

View File

@ -28,4 +28,10 @@ class EntityState {
static const unavailable = 'unavailable';
static const ok = 'ok';
static const problem = 'problem';
}
class EntityTapAction {
static const moreInfo = 'more-info';
static const toggle = 'toggle';
static const callService = 'call-service';
}

View File

@ -106,7 +106,7 @@ class Entity {
Widget buildEntityPageWidget(BuildContext context) {
return EntityModel(
entity: EntityWrapper(entity: this),
entityWrapper: EntityWrapper(entity: this),
child: EntityPageContainer(children: <Widget>[
DefaultEntityContainer(state: _buildStatePartForPage(context)),
LastUpdatedWidget(),
@ -128,7 +128,7 @@ class Entity {
Widget buildBadgeWidget(BuildContext context) {
return EntityModel(
entity: EntityWrapper(entity: this),
entityWrapper: EntityWrapper(entity: this),
child: BadgeWidget(),
handleTap: true,
);

View File

@ -4,9 +4,18 @@ class EntityWrapper {
String displayName;
String icon;
String tapAction;
String holdAction;
Entity entity;
EntityWrapper({this.entity, String icon, String displayName}) {
EntityWrapper({
this.entity,
String icon,
String displayName,
this.tapAction: EntityTapAction.moreInfo,
this.holdAction
}) {
this.icon = icon ?? entity.icon;
this.displayName = displayName ?? entity.displayName;
}

View File

@ -7,12 +7,12 @@ class BadgeWidget extends StatelessWidget {
double iconSize = 26.0;
Widget badgeIcon;
String onBadgeTextValue;
Color iconColor = EntityColor.badgeColors[entityModel.entity.entity.domain] ??
Color iconColor = EntityColor.badgeColors[entityModel.entityWrapper.entity.domain] ??
EntityColor.badgeColors["default"];
switch (entityModel.entity.entity.domain) {
switch (entityModel.entityWrapper.entity.domain) {
case "sun":
{
badgeIcon = entityModel.entity.entity.state == "below_horizon"
badgeIcon = entityModel.entityWrapper.entity.state == "below_horizon"
? Icon(
MaterialDesignIcons.createIconDataFromIconCode(0xf0dc),
size: iconSize,
@ -25,10 +25,10 @@ class BadgeWidget extends StatelessWidget {
}
case "sensor":
{
onBadgeTextValue = entityModel.entity.entity.unitOfMeasurement;
onBadgeTextValue = entityModel.entityWrapper.entity.unitOfMeasurement;
badgeIcon = Center(
child: Text(
"${entityModel.entity.entity.state}",
"${entityModel.entityWrapper.entity.state}",
overflow: TextOverflow.fade,
softWrap: false,
textAlign: TextAlign.center,
@ -40,14 +40,14 @@ class BadgeWidget extends StatelessWidget {
case "device_tracker":
{
badgeIcon = MaterialDesignIcons.createIconWidgetFromEntityData(
entityModel.entity, iconSize, Colors.black);
onBadgeTextValue = entityModel.entity.entity.state;
entityModel.entityWrapper, iconSize, Colors.black);
onBadgeTextValue = entityModel.entityWrapper.entity.state;
break;
}
default:
{
badgeIcon = MaterialDesignIcons.createIconWidgetFromEntityData(
entityModel.entity, iconSize, Colors.black);
entityModel.entityWrapper, iconSize, Colors.black);
}
}
Widget onBadgeText;
@ -109,7 +109,7 @@ class BadgeWidget extends StatelessWidget {
Container(
width: 60.0,
child: Text(
"${entityModel.entity.displayName}",
"${entityModel.entityWrapper.displayName}",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 12.0),
softWrap: true,
@ -120,6 +120,6 @@ class BadgeWidget extends StatelessWidget {
],
),
onTap: () =>
eventBus.fire(new ShowEntityPageEvent(entityModel.entity.entity)));
eventBus.fire(new ShowEntityPageEvent(entityModel.entityWrapper.entity)));
}
}

View File

@ -165,7 +165,7 @@ class _ClimateControlWidgetState extends State<ClimateControlWidget> {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final ClimateEntity entity = entityModel.entity.entity;
final ClimateEntity entity = entityModel.entityWrapper.entity;
if (_changedHere) {
_showPending = (_tmpTemperature != entity.temperature);
_changedHere = false;

View File

@ -38,7 +38,7 @@ class _CoverControlWidgetState extends State<CoverControlWidget> {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final CoverEntity entity = entityModel.entity.entity;
final CoverEntity entity = entityModel.entityWrapper.entity;
if (_changedHere) {
_changedHere = false;
} else {
@ -152,7 +152,7 @@ class CoverTiltControlsWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final CoverEntity entity = entityModel.entity.entity;
final CoverEntity entity = entityModel.entityWrapper.entity;
List<Widget> buttons = [];
if (entity.supportOpenTilt) {
buttons.add(IconButton(

View File

@ -80,7 +80,7 @@ class _LightControlsWidgetState extends State<LightControlsWidget> {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final LightEntity entity = entityModel.entity.entity;
final LightEntity entity = entityModel.entityWrapper.entity;
if (!_changedHere) {
_resetState(entity);
} else {

View File

@ -28,7 +28,7 @@ class MediaPlayerWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final EntityModel entityModel = EntityModel.of(context);
final MediaPlayerEntity entity = entityModel.entity.entity;
final MediaPlayerEntity entity = entityModel.entityWrapper.entity;
return Column(
children: <Widget>[
Stack(
@ -229,7 +229,7 @@ class _MediaPlayerProgressWidgetState extends State<MediaPlayerProgressWidget> {
@override
Widget build(BuildContext context) {
final EntityModel entityModel = EntityModel.of(context);
final MediaPlayerEntity entity = entityModel.entity.entity;
final MediaPlayerEntity entity = entityModel.entityWrapper.entity;
double progress;
try {
DateTime lastUpdated = DateTime.parse(

View File

@ -25,7 +25,7 @@ class _SliderControlsWidgetState extends State<SliderControlsWidget> {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final SliderEntity entity = entityModel.entity.entity;
final SliderEntity entity = entityModel.entityWrapper.entity;
if (entity.valueStep < 1) {
_multiplier = 10;
} else if (entity.valueStep < 0.1) {

View File

@ -7,14 +7,14 @@ class EntityAttributesList extends StatelessWidget {
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
List<Widget> attrs = [];
if ((entityModel.entity.entity.attributesToShow == null) ||
(entityModel.entity.entity.attributesToShow.contains("all"))) {
entityModel.entity.entity.attributes.forEach((name, value) {
if ((entityModel.entityWrapper.entity.attributesToShow == null) ||
(entityModel.entityWrapper.entity.attributesToShow.contains("all"))) {
entityModel.entityWrapper.entity.attributes.forEach((name, value) {
attrs.add(_buildSingleAttribute("$name", "$value"));
});
} else {
entityModel.entity.entity.attributesToShow.forEach((String attr) {
String attrValue = entityModel.entity.entity.getAttribute("$attr");
entityModel.entityWrapper.entity.attributesToShow.forEach((String attr) {
String attrValue = entityModel.entityWrapper.entity.getAttribute("$attr");
if (attrValue != null) {
attrs.add(
_buildSingleAttribute("$attr", "$attrValue"));

View File

@ -15,14 +15,29 @@ class EntityIcon extends StatelessWidget {
child: Padding(
padding: padding,
child: MaterialDesignIcons.createIconWidgetFromEntityData(
entityModel.entity,
entityModel.entityWrapper,
iconSize,
EntityColor.stateColor(entityModel.entity.entity.state)
EntityColor.stateColor(entityModel.entityWrapper.entity.state)
),
),
onTap: () => entityModel.handleTap
? eventBus.fire(new ShowEntityPageEvent(entityModel.entity.entity))
: null,
onTap: () {
if (entityModel.handleTap) {
switch (entityModel.entityWrapper.tapAction) {
case EntityTapAction.moreInfo: {
eventBus.fire(
new ShowEntityPageEvent(entityModel.entityWrapper.entity));
break;
}
case EntityTapAction.toggle: {
eventBus.fire(
ServiceCallEvent("homeassistant", "toggle", entityModel.entityWrapper.entity.entityId, null));
break;
}
}
}
}
);
}
}

View File

@ -17,7 +17,7 @@ class EntityName extends StatelessWidget {
child: Padding(
padding: padding,
child: Text(
"${entityModel.entity.displayName}",
"${entityModel.entityWrapper.displayName}",
overflow: textOverflow,
softWrap: wordsWrap,
style: TextStyle(fontSize: fontSize),
@ -26,7 +26,7 @@ class EntityName extends StatelessWidget {
),
onTap: () =>
entityModel.handleTap
? eventBus.fire(new ShowEntityPageEvent(entityModel.entity.entity))
? eventBus.fire(new ShowEntityPageEvent(entityModel.entityWrapper.entity))
: null,
);
}

View File

@ -65,7 +65,7 @@ class _EntityHistoryWidgetState extends State<EntityHistoryWidget> {
Widget build(BuildContext context) {
final HomeAssistantModel homeAssistantModel = HomeAssistantModel.of(context);
final EntityModel entityModel = EntityModel.of(context);
final Entity entity = entityModel.entity.entity;
final Entity entity = entityModel.entityWrapper.entity;
if (!_needToUpdateHistory) {
_needToUpdateHistory = true;
} else {

View File

@ -8,7 +8,7 @@ class LastUpdatedWidget extends StatelessWidget {
padding: EdgeInsets.fromLTRB(
Sizes.leftWidgetPadding, 0.0, 0.0, 0.0),
child: Text(
'${entityModel.entity.entity.lastUpdated}',
'${entityModel.entityWrapper.entity.lastUpdated}',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: Sizes.smallFontSize, color: Colors.black26),

View File

@ -3,12 +3,12 @@ part of '../main.dart';
class EntityModel extends InheritedWidget {
const EntityModel({
Key key,
@required this.entity,
@required this.entityWrapper,
@required this.handleTap,
@required Widget child,
}) : super(key: key, child: child);
final EntityWrapper entity;
final EntityWrapper entityWrapper;
final bool handleTap;
static EntityModel of(BuildContext context) {

View File

@ -13,7 +13,7 @@ class ButtonStateWidget extends StatelessWidget {
height: 34.0,
child: FlatButton(
onPressed: (() {
_setNewState(entityModel.entity.entity);
_setNewState(entityModel.entityWrapper.entity);
}),
child: Text(
"EXECUTE",

View File

@ -4,7 +4,7 @@ class ClimateStateWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final ClimateEntity entity = entityModel.entity.entity;
final ClimateEntity entity = entityModel.entityWrapper.entity;
String targetTemp = "-";
if ((entity.supportTargetTemperature) && (entity.temperature != null)) {
targetTemp = "${entity.temperature}";

View File

@ -19,7 +19,7 @@ class CoverStateWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final CoverEntity entity = entityModel.entity.entity;
final CoverEntity entity = entityModel.entityWrapper.entity;
List<Widget> buttons = [];
if (entity.supportOpen) {
buttons.add(IconButton(

View File

@ -4,7 +4,7 @@ class DateTimeStateWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final DateTimeEntity entity = entityModel.entity.entity;
final DateTimeEntity entity = entityModel.entityWrapper.entity;
return Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, Sizes.rightWidgetPadding, 0.0),
child: GestureDetector(

View File

@ -18,7 +18,7 @@ class _SelectStateWidgetState extends State<SelectStateWidget> {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final SelectEntity entity = entityModel.entity.entity;
final SelectEntity entity = entityModel.entityWrapper.entity;
Widget ctrl;
if (entity.listOptions.isNotEmpty) {
ctrl = DropdownButton<String>(

View File

@ -15,7 +15,7 @@ class SimpleEntityState extends StatelessWidget {
padding: padding,
child: GestureDetector(
child: Text(
"${entityModel.entity.entity.state}${entityModel.entity.entity.unitOfMeasurement}",
"${entityModel.entityWrapper.entity.state}${entityModel.entityWrapper.entity.unitOfMeasurement}",
textAlign: textAlign,
maxLines: 4,
overflow: TextOverflow.ellipsis,
@ -24,7 +24,7 @@ class SimpleEntityState extends StatelessWidget {
fontSize: Sizes.stateFontSize,
)),
onTap: () => entityModel.handleTap
? eventBus.fire(new ShowEntityPageEvent(entityModel.entity.entity))
? eventBus.fire(new ShowEntityPageEvent(entityModel.entityWrapper.entity))
: null,
)
);

View File

@ -34,7 +34,7 @@ class _SwitchStateWidgetState extends State<SwitchStateWidget> {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final entity = entityModel.entity.entity;
final entity = entityModel.entityWrapper.entity;
if (!updatedHere) {
newState = entity.state;
} else {

View File

@ -55,7 +55,7 @@ class _TextInputStateWidgetState extends State<TextInputStateWidget> {
@override
Widget build(BuildContext context) {
final entityModel = EntityModel.of(context);
final TextEntity entity = entityModel.entity.entity;
final TextEntity entity = entityModel.entityWrapper.entity;
_entityState = entity.state;
_entityDomain = entity.domain;
_entityId = entity.entityId;

View File

@ -427,7 +427,9 @@ class HomeAssistant {
EntityWrapper(
entity: entities.get(rawEntity["entity"]),
displayName: rawEntity["name"],
icon: rawEntity["icon"]
icon: rawEntity["icon"],
tapAction: rawEntity["tap_action"] ?? EntityTapAction.moreInfo,
holdAction: rawEntity["hold_action"] ?? EntityTapAction.moreInfo
)
);
}

View File

@ -140,6 +140,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
String _authType;
//int _uiViewsCount = 0;
String _instanceHost;
StreamSubscription _stateSubscription;
StreamSubscription _settingsSubscription;
StreamSubscription _serviceCallSubscription;
StreamSubscription _showEntityPageSubscription;
@ -208,6 +209,11 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
}
_subscribe() {
if (_stateSubscription == null) {
_stateSubscription = eventBus.on<StateChangedEvent>().listen((event) {
setState(() {});
});
}
if (_serviceCallSubscription == null) {
_serviceCallSubscription =
eventBus.on<ServiceCallEvent>().listen((event) {
@ -546,6 +552,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
if (_stateSubscription != null) _stateSubscription.cancel();
if (_settingsSubscription != null) _settingsSubscription.cancel();
if (_serviceCallSubscription != null) _serviceCallSubscription.cancel();
if (_showEntityPageSubscription != null) _showEntityPageSubscription.cancel();

View File

@ -30,7 +30,7 @@ class EntitiesCardWidget extends StatelessWidget {
Padding(
padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding),
child: EntityModel(
entity: entity,
entityWrapper: entity,
handleTap: true,
child: entity.entity.buildDefaultWidget(context)
),

View File

@ -33,7 +33,7 @@ class GlanceCardWidget extends StatelessWidget {
SizedBox(
width: width / columnsCount,
child: EntityModel(
entity: entity,
entityWrapper: entity,
child: entity.entity.buildGlanceWidget(context, card.showName, card.showState),
handleTap: true
),

View File

@ -17,7 +17,7 @@ class MediaControlCardWidget extends StatelessWidget {
return Card(
child: EntityModel(
entity: card.linkedEntity,
entityWrapper: card.linkedEntity,
handleTap: null,
child: MediaPlayerWidget()
)

View File

@ -33,7 +33,7 @@ class UnsupportedCardWidget extends StatelessWidget {
Padding(
padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding),
child: EntityModel(
entity: card.linkedEntity,
entityWrapper: card.linkedEntity,
handleTap: true,
child: card.linkedEntity.entity.buildDefaultWidget(context)
),