WIP #183 tap_action support. State change event fix
This commit is contained in:
@ -29,3 +29,9 @@ class EntityState {
|
||||
static const ok = 'ok';
|
||||
static const problem = 'problem';
|
||||
}
|
||||
|
||||
class EntityTapAction {
|
||||
static const moreInfo = 'more-info';
|
||||
static const toggle = 'toggle';
|
||||
static const callService = 'call-service';
|
||||
}
|
@ -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,
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
|
@ -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) {
|
||||
|
@ -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",
|
||||
|
@ -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}";
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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>(
|
||||
|
@ -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,
|
||||
)
|
||||
);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
),
|
||||
|
@ -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
|
||||
),
|
||||
|
@ -17,7 +17,7 @@ class MediaControlCardWidget extends StatelessWidget {
|
||||
|
||||
return Card(
|
||||
child: EntityModel(
|
||||
entity: card.linkedEntity,
|
||||
entityWrapper: card.linkedEntity,
|
||||
handleTap: null,
|
||||
child: MediaPlayerWidget()
|
||||
)
|
||||
|
@ -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)
|
||||
),
|
||||
|
Reference in New Issue
Block a user