diff --git a/lib/entity_class/entity.class.dart b/lib/entity_class/entity.class.dart index 9c51cd2..845c71e 100644 --- a/lib/entity_class/entity.class.dart +++ b/lib/entity_class/entity.class.dart @@ -16,17 +16,6 @@ class Entity { "sensor" ]; - static const rightWidgetPadding = 14.0; - static const leftWidgetPadding = 8.0; - static const extendedWidgetHeight = 50.0; - static const iconSize = 28.0; - static const stateFontSize = 16.0; - static const nameFontSize = 16.0; - static const smallFontSize = 14.0; - static const largeFontSize = 24.0; - static const inputWidth = 160.0; - static const rowPadding = 10.0; - Map attributes; String domain; String entityId; diff --git a/lib/entity_widgets/controls/climate_controls.dart b/lib/entity_widgets/controls/climate_controls.dart index 909526f..6657aa8 100644 --- a/lib/entity_widgets/controls/climate_controls.dart +++ b/lib/entity_widgets/controls/climate_controls.dart @@ -174,7 +174,7 @@ class _ClimateControlWidgetState extends State { _resetVars(entity); } return Padding( - padding: EdgeInsets.fromLTRB(Entity.leftWidgetPadding, Entity.rowPadding, Entity.rightWidgetPadding, 0.0), + padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -273,7 +273,7 @@ class _ClimateControlWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Target temperature", style: TextStyle( - fontSize: Entity.stateFontSize + fontSize: Sizes.stateFontSize )), TemperatureControlWidget( value: _tmpTemperature, @@ -324,7 +324,7 @@ class _ClimateControlWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Target temperature range", style: TextStyle( - fontSize: Entity.stateFontSize + fontSize: Sizes.stateFontSize )), Row( children: controls, @@ -342,7 +342,7 @@ class _ClimateControlWidgetState extends State { result.addAll([ Text( "$_tmpTargetHumidity%", - style: TextStyle(fontSize: Entity.largeFontSize), + style: TextStyle(fontSize: Sizes.largeFontSize), ), Expanded( child: Slider( @@ -366,9 +366,9 @@ class _ClimateControlWidgetState extends State { children: [ Padding( padding: EdgeInsets.fromLTRB( - 0.0, Entity.rowPadding, 0.0, Entity.rowPadding), + 0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), child: Text("Target humidity", style: TextStyle( - fontSize: Entity.stateFontSize + fontSize: Sizes.stateFontSize )), ), Row( @@ -376,7 +376,7 @@ class _ClimateControlWidgetState extends State { children: result, ), Container( - height: Entity.rowPadding, + height: Sizes.rowPadding, ) ], ); diff --git a/lib/entity_widgets/controls/cover_controls.dart b/lib/entity_widgets/controls/cover_controls.dart index 8911fc3..7c1b83d 100644 --- a/lib/entity_widgets/controls/cover_controls.dart +++ b/lib/entity_widgets/controls/cover_controls.dart @@ -45,7 +45,7 @@ class _CoverControlWidgetState extends State { _resetVars(entity); } return Padding( - padding: EdgeInsets.fromLTRB(Entity.leftWidgetPadding, Entity.rowPadding, Entity.rightWidgetPadding, 0.0), + padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, 0.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -63,9 +63,9 @@ class _CoverControlWidgetState extends State { children: [ Padding( padding: EdgeInsets.fromLTRB( - 0.0, Entity.rowPadding, 0.0, Entity.rowPadding), + 0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), child: Text("Position", style: TextStyle( - fontSize: Entity.stateFontSize + fontSize: Sizes.stateFontSize )), ), Slider( @@ -81,7 +81,7 @@ class _CoverControlWidgetState extends State { }, onChangeEnd: (double value) => _setNewPosition(entity, value), ), - Container(height: Entity.rowPadding,) + Container(height: Sizes.rowPadding,) ], ); } else { @@ -111,15 +111,15 @@ class _CoverControlWidgetState extends State { }, onChangeEnd: (double value) => _setNewTiltPosition(entity, value), ), - Container(height: Entity.rowPadding,) + Container(height: Sizes.rowPadding,) ]); } if (controls.isNotEmpty) { controls.insert(0, Padding( padding: EdgeInsets.fromLTRB( - 0.0, Entity.rowPadding, 0.0, Entity.rowPadding), + 0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), child: Text("Tilt position", style: TextStyle( - fontSize: Entity.stateFontSize + fontSize: Sizes.stateFontSize )), )); return Column( @@ -159,24 +159,24 @@ class CoverTiltControlsWidget extends StatelessWidget { icon: Icon( MaterialDesignIcons.createIconDataFromIconName( "mdi:arrow-top-right"), - size: Entity.iconSize, + size: Sizes.iconSize, ), onPressed: entity.canTiltBeOpened ? () => _open(entity) : null)); } else { buttons.add(Container( - width: Entity.iconSize + 20.0, + width: Sizes.iconSize + 20.0, )); } if (entity.supportStopTilt) { buttons.add(IconButton( icon: Icon( MaterialDesignIcons.createIconDataFromIconName("mdi:stop"), - size: Entity.iconSize, + size: Sizes.iconSize, ), onPressed: () => _stop(entity))); } else { buttons.add(Container( - width: Entity.iconSize + 20.0, + width: Sizes.iconSize + 20.0, )); } if (entity.supportCloseTilt) { @@ -184,12 +184,12 @@ class CoverTiltControlsWidget extends StatelessWidget { icon: Icon( MaterialDesignIcons.createIconDataFromIconName( "mdi:arrow-bottom-left"), - size: Entity.iconSize, + size: Sizes.iconSize, ), onPressed: entity.canTiltBeClosed ? () => _close(entity) : null)); } else { buttons.add(Container( - width: Entity.iconSize + 20.0, + width: Sizes.iconSize + 20.0, )); } diff --git a/lib/entity_widgets/controls/light_controls.dart b/lib/entity_widgets/controls/light_controls.dart index aedfaa1..753ae08 100644 --- a/lib/entity_widgets/controls/light_controls.dart +++ b/lib/entity_widgets/controls/light_controls.dart @@ -102,12 +102,12 @@ class _LightControlsWidgetState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container(height: Entity.rowPadding,), + Container(height: Sizes.rowPadding,), Text( "Brightness", - style: TextStyle(fontSize: Entity.stateFontSize), + style: TextStyle(fontSize: Sizes.stateFontSize), ), - Container(height: Entity.rowPadding,), + Container(height: Sizes.rowPadding,), Row( children: [ Icon(Icons.brightness_5), @@ -127,7 +127,7 @@ class _LightControlsWidgetState extends State { ) ], ), - Container(height: Entity.rowPadding,) + Container(height: Sizes.rowPadding,) ], ); } else { @@ -140,12 +140,12 @@ class _LightControlsWidgetState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container(height: Entity.rowPadding,), + Container(height: Sizes.rowPadding,), Text( "Color temperature", - style: TextStyle(fontSize: Entity.stateFontSize), + style: TextStyle(fontSize: Sizes.stateFontSize), ), - Container(height: Entity.rowPadding,), + Container(height: Sizes.rowPadding,), Row( children: [ Text("Cold", style: TextStyle(color: Colors.lightBlue),), @@ -166,7 +166,7 @@ class _LightControlsWidgetState extends State { Text("Warm", style: TextStyle(color: Colors.amberAccent),), ], ), - Container(height: Entity.rowPadding,) + Container(height: Sizes.rowPadding,) ], ); } else { @@ -179,7 +179,7 @@ class _LightControlsWidgetState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container(height: Entity.rowPadding,), + Container(height: Sizes.rowPadding,), RaisedButton( onPressed: () => _showColorPicker(entity), color: _tmpColor ?? Colors.black45, @@ -193,7 +193,7 @@ class _LightControlsWidgetState extends State { ), ), ), - Container(height: 2*Entity.rowPadding,), + Container(height: 2*Sizes.rowPadding,), ], ); } else { diff --git a/lib/entity_widgets/controls/media_player_widget.dart b/lib/entity_widgets/controls/media_player_widget.dart new file mode 100644 index 0000000..dbc69dc --- /dev/null +++ b/lib/entity_widgets/controls/media_player_widget.dart @@ -0,0 +1,155 @@ +part of '../../main.dart'; + +class MediaPlayerWidget extends StatelessWidget { + + @override + Widget build(BuildContext context) { + final EntityModel entityModel = EntityModel.of(context); + final MediaPlayerEntity entity = entityModel.entity; + List body = []; + body.add(Stack( + alignment: AlignmentDirectional.topEnd, + children: [ + _buildImage(entity), + Positioned( + bottom: 0.0, + left: 0.0, + right: 0.0, + child: Container( + color: Colors.black45, + child: _buildState(entity), + ), + ), + Positioned( + bottom: 0.0, + left: 0.0, + right: 0.0, + child: MediaPlayerProgressWidget() + ) + ], + )); + return Column( + children: body + ); + } + + Widget _buildState(MediaPlayerEntity entity) { + TextStyle style = TextStyle( + fontSize: 14.0, + color: Colors.white, + fontWeight: FontWeight.normal, + height: 1.2 + ); + List states = []; + states.add(Text("${entity.displayName}", style: style)); + String state = entity.state; + if (state == null || state == "off" || state == "unavailable" || state == "idle") { + states.add(Text("${entity.state}", style: style.apply(fontSizeDelta: 4.0),)); + } + if (entity.attributes['media_title'] != null) { + states.add(Text("${entity.attributes['media_title']}", style: style.apply(fontSizeDelta: 6.0, fontWeightDelta: 50),)); + } + if (entity.attributes['media_content_type'] == "music") { + states.add(Text("${entity.attributes['media_artist'] ?? entity.attributes['app_name']}", style: style.apply(fontSizeDelta: 4.0),)); + } else if (entity.attributes['app_name'] != null) { + states.add(Text("${entity.attributes['app_name']}", style: style.apply(fontSizeDelta: 4.0),)); + } + return Padding( + padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, Sizes.rowPadding), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: states, + ), + ); + } + + Widget _buildImage(MediaPlayerEntity entity) { + String state = entity.state; + if (homeAssistantWebHost != null && entity.entityPicture != null && state != "off" && state != "unavailable" && state != "idle") { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image( + image: CachedNetworkImageProvider("$homeAssistantWebHost${entity.entityPicture}"), + height: 240.0, + width: 320.0, + fit: BoxFit.fitHeight, + ) + ], + ); + } else { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + MaterialDesignIcons.createIconDataFromIconName("mdi:movie"), + size: 150.0, + color: EntityColors.stateColor("$state"), + ) + ], + ); + /*return Container( + color: Colors.blue, + height: 80.0, + );*/ + } + } +} + +class MediaPlayerProgressWidget extends StatefulWidget { + @override + _MediaPlayerProgressWidgetState createState() => _MediaPlayerProgressWidgetState(); +} + +class _MediaPlayerProgressWidgetState extends State { + + Timer _timer; + + @override + Widget build(BuildContext context) { + final EntityModel entityModel = EntityModel.of(context); + final MediaPlayerEntity entity = entityModel.entity; + double progress; + try { + DateTime lastUpdated = DateTime.parse( + entity.attributes["media_position_updated_at"]).toLocal(); + Duration duration = Duration(seconds: entity._getIntAttributeValue("media_duration") ?? 1); + Duration position = Duration(seconds: entity._getIntAttributeValue("media_position") ?? 0); + int currentPosition = position.inSeconds; + if (entity.state == "playing") { + _timer?.cancel(); + _timer = Timer(Duration(seconds: 1), () { + setState(() { + }); + }); + int differenceInSeconds = DateTime + .now() + .difference(lastUpdated) + .inSeconds; + currentPosition = currentPosition + differenceInSeconds; + } else { + _timer?.cancel(); + } + progress = currentPosition / duration.inSeconds; + return LinearProgressIndicator( + value: progress, + backgroundColor: Colors.black45, + valueColor: AlwaysStoppedAnimation(EntityColors.stateColor("on")), + ); + } catch (e) { + _timer?.cancel(); + progress = 0.0; + } + return LinearProgressIndicator( + value: progress, + backgroundColor: Colors.black45, + ); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } + +} \ No newline at end of file diff --git a/lib/entity_widgets/entity_attributes_list.dart b/lib/entity_widgets/entity_attributes_list.dart index e515fb9..12a9c29 100644 --- a/lib/entity_widgets/entity_attributes_list.dart +++ b/lib/entity_widgets/entity_attributes_list.dart @@ -34,7 +34,7 @@ class EntityAttributesList extends StatelessWidget { Expanded( child: Padding( padding: EdgeInsets.fromLTRB( - Entity.leftWidgetPadding, Entity.rowPadding, 0.0, 0.0), + Sizes.leftWidgetPadding, Sizes.rowPadding, 0.0, 0.0), child: Text( "$name", textAlign: TextAlign.left, @@ -44,7 +44,7 @@ class EntityAttributesList extends StatelessWidget { Expanded( child: Padding( padding: EdgeInsets.fromLTRB( - 0.0, Entity.rowPadding, Entity.rightWidgetPadding, 0.0), + 0.0, Sizes.rowPadding, Sizes.rightWidgetPadding, 0.0), child: Text( "$value", textAlign: TextAlign.right, diff --git a/lib/entity_widgets/entity_icon.dart b/lib/entity_widgets/entity_icon.dart index 46d85f5..dba3c7c 100644 --- a/lib/entity_widgets/entity_icon.dart +++ b/lib/entity_widgets/entity_icon.dart @@ -7,10 +7,10 @@ class EntityIcon extends StatelessWidget { return GestureDetector( child: Padding( padding: EdgeInsets.fromLTRB( - Entity.leftWidgetPadding, 0.0, 12.0, 0.0), + Sizes.leftWidgetPadding, 0.0, 12.0, 0.0), child: MaterialDesignIcons.createIconWidgetFromEntityData( entityModel.entity, - Entity.iconSize, + Sizes.iconSize, EntityColors.stateColor(entityModel.entity.state) ), ), diff --git a/lib/entity_widgets/entity_name.dart b/lib/entity_widgets/entity_name.dart index d759988..3d74565 100644 --- a/lib/entity_widgets/entity_name.dart +++ b/lib/entity_widgets/entity_name.dart @@ -11,7 +11,7 @@ class EntityName extends StatelessWidget { "${entityModel.entity.displayName}", overflow: TextOverflow.ellipsis, softWrap: false, - style: TextStyle(fontSize: Entity.nameFontSize), + style: TextStyle(fontSize: Sizes.nameFontSize), ), ), onTap: () => diff --git a/lib/entity_widgets/history_chart/combined_history_chart.dart b/lib/entity_widgets/history_chart/combined_history_chart.dart index a6855da..b199442 100644 --- a/lib/entity_widgets/history_chart/combined_history_chart.dart +++ b/lib/entity_widgets/history_chart/combined_history_chart.dart @@ -69,7 +69,7 @@ class _CombinedHistoryChartWidgetState extends State selectionModels: [ new charts.SelectionModelConfig( type: charts.SelectionModelType.info, - listener: (model) => _onSelectionChanged(model), + changedListener: (model) => _onSelectionChanged(model), ) ], customSeriesRenderers: [ diff --git a/lib/entity_widgets/history_chart/entity_history.dart b/lib/entity_widgets/history_chart/entity_history.dart index 4a4aa9e..dfafeeb 100644 --- a/lib/entity_widgets/history_chart/entity_history.dart +++ b/lib/entity_widgets/history_chart/entity_history.dart @@ -83,7 +83,7 @@ class _EntityHistoryWidgetState extends State { } children.add(Divider()); return Padding( - padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, Entity.rowPadding), + padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, Sizes.rowPadding), child: Column( children: children, ), diff --git a/lib/entity_widgets/history_chart/numeric_state_history_chart.dart b/lib/entity_widgets/history_chart/numeric_state_history_chart.dart index 887de56..3ab4549 100644 --- a/lib/entity_widgets/history_chart/numeric_state_history_chart.dart +++ b/lib/entity_widgets/history_chart/numeric_state_history_chart.dart @@ -57,7 +57,7 @@ class _NumericStateHistoryChartWidgetState extends State _onSelectionChanged(model), + changedListener: (model) => _onSelectionChanged(model), ) ], ), diff --git a/lib/entity_widgets/history_chart/simple_state_history_chart.dart b/lib/entity_widgets/history_chart/simple_state_history_chart.dart index 7677a68..4152430 100644 --- a/lib/entity_widgets/history_chart/simple_state_history_chart.dart +++ b/lib/entity_widgets/history_chart/simple_state_history_chart.dart @@ -53,7 +53,7 @@ class _SimpleStateHistoryChartWidgetState extends State _onSelectionChanged(model), + changedListener: (model) => _onSelectionChanged(model), ) ], customSeriesRenderers: [ diff --git a/lib/entity_widgets/last_updated.dart b/lib/entity_widgets/last_updated.dart index d777777..51db486 100644 --- a/lib/entity_widgets/last_updated.dart +++ b/lib/entity_widgets/last_updated.dart @@ -6,12 +6,12 @@ class LastUpdatedWidget extends StatelessWidget { final entityModel = EntityModel.of(context); return Padding( padding: EdgeInsets.fromLTRB( - Entity.leftWidgetPadding, 0.0, 0.0, 0.0), + Sizes.leftWidgetPadding, 0.0, 0.0, 0.0), child: Text( '${entityModel.entity.lastUpdated}', textAlign: TextAlign.left, style: TextStyle( - fontSize: Entity.smallFontSize, color: Colors.black26), + fontSize: Sizes.smallFontSize, color: Colors.black26), ), ); } diff --git a/lib/entity_widgets/mode_selector.dart b/lib/entity_widgets/mode_selector.dart index 49de2c6..00feaef 100644 --- a/lib/entity_widgets/mode_selector.dart +++ b/lib/entity_widgets/mode_selector.dart @@ -27,7 +27,7 @@ class ModeSelectorWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("$caption", style: TextStyle( - fontSize: captionFontSize ?? Entity.stateFontSize + fontSize: captionFontSize ?? Sizes.stateFontSize )), Row( children: [ @@ -39,7 +39,7 @@ class ModeSelectorWidget extends StatelessWidget { iconSize: 30.0, isExpanded: true, style: TextStyle( - fontSize: valueFontSize ?? Entity.largeFontSize, + fontSize: valueFontSize ?? Sizes.largeFontSize, color: Colors.black, ), hint: Text("Select ${caption.toLowerCase()}"), @@ -55,7 +55,7 @@ class ModeSelectorWidget extends StatelessWidget { ) ], ), - Container(height: bottomPadding ?? Entity.rowPadding,) + Container(height: bottomPadding ?? Sizes.rowPadding,) ], ); } diff --git a/lib/entity_widgets/mode_swicth.dart b/lib/entity_widgets/mode_swicth.dart index e2fef6a..b8ef25d 100644 --- a/lib/entity_widgets/mode_swicth.dart +++ b/lib/entity_widgets/mode_swicth.dart @@ -23,7 +23,7 @@ class ModeSwitchWidget extends StatelessWidget { child: Text( "$caption", style: TextStyle( - fontSize: captionFontSize ?? Entity.stateFontSize + fontSize: captionFontSize ?? Sizes.stateFontSize ), ), ), diff --git a/lib/entity_widgets/state/button_state.dart b/lib/entity_widgets/state/button_state.dart index 9fea395..7c85a37 100644 --- a/lib/entity_widgets/state/button_state.dart +++ b/lib/entity_widgets/state/button_state.dart @@ -19,7 +19,7 @@ class ButtonStateWidget extends StatelessWidget { "EXECUTE", textAlign: TextAlign.right, style: - new TextStyle(fontSize: Entity.stateFontSize, color: Colors.blue), + new TextStyle(fontSize: Sizes.stateFontSize, color: Colors.blue), ), ) ); diff --git a/lib/entity_widgets/state/climate_state.dart b/lib/entity_widgets/state/climate_state.dart index 961ac8e..987753f 100644 --- a/lib/entity_widgets/state/climate_state.dart +++ b/lib/entity_widgets/state/climate_state.dart @@ -18,7 +18,7 @@ class ClimateStateWidget extends StatelessWidget { } return Padding( padding: EdgeInsets.fromLTRB( - 0.0, 0.0, Entity.rightWidgetPadding, 0.0), + 0.0, 0.0, Sizes.rightWidgetPadding, 0.0), child: GestureDetector( child: Column( crossAxisAlignment: CrossAxisAlignment.end, @@ -30,12 +30,12 @@ class ClimateStateWidget extends StatelessWidget { textAlign: TextAlign.right, style: new TextStyle( fontWeight: FontWeight.bold, - fontSize: Entity.stateFontSize, + fontSize: Sizes.stateFontSize, )), Text(" $targetTemp", textAlign: TextAlign.right, style: new TextStyle( - fontSize: Entity.stateFontSize, + fontSize: Sizes.stateFontSize, )) ], ), @@ -43,7 +43,7 @@ class ClimateStateWidget extends StatelessWidget { Text("Currently: ${entity.attributes["current_temperature"]}", textAlign: TextAlign.right, style: new TextStyle( - fontSize: Entity.stateFontSize, + fontSize: Sizes.stateFontSize, color: Colors.black45) ) : Container(height: 0.0,) diff --git a/lib/entity_widgets/state/cover_state.dart b/lib/entity_widgets/state/cover_state.dart index f565554..8c27607 100644 --- a/lib/entity_widgets/state/cover_state.dart +++ b/lib/entity_widgets/state/cover_state.dart @@ -25,36 +25,36 @@ class CoverStateWidget extends StatelessWidget { buttons.add(IconButton( icon: Icon( MaterialDesignIcons.createIconDataFromIconName("mdi:arrow-up"), - size: Entity.iconSize, + size: Sizes.iconSize, ), onPressed: entity.canBeOpened ? () => _open(entity) : null)); } else { buttons.add(Container( - width: Entity.iconSize + 20.0, + width: Sizes.iconSize + 20.0, )); } if (entity.supportStop) { buttons.add(IconButton( icon: Icon( MaterialDesignIcons.createIconDataFromIconName("mdi:stop"), - size: Entity.iconSize, + size: Sizes.iconSize, ), onPressed: () => _stop(entity))); } else { buttons.add(Container( - width: Entity.iconSize + 20.0, + width: Sizes.iconSize + 20.0, )); } if (entity.supportClose) { buttons.add(IconButton( icon: Icon( MaterialDesignIcons.createIconDataFromIconName("mdi:arrow-down"), - size: Entity.iconSize, + size: Sizes.iconSize, ), onPressed: entity.canBeClosed ? () => _close(entity) : null)); } else { buttons.add(Container( - width: Entity.iconSize + 20.0, + width: Sizes.iconSize + 20.0, )); } diff --git a/lib/entity_widgets/state/date_time_state.dart b/lib/entity_widgets/state/date_time_state.dart index 12a49a2..5c5d5cf 100644 --- a/lib/entity_widgets/state/date_time_state.dart +++ b/lib/entity_widgets/state/date_time_state.dart @@ -6,12 +6,12 @@ class DateTimeStateWidget extends StatelessWidget { final entityModel = EntityModel.of(context); final DateTimeEntity entity = entityModel.entity; return Padding( - padding: EdgeInsets.fromLTRB(0.0, 0.0, Entity.rightWidgetPadding, 0.0), + padding: EdgeInsets.fromLTRB(0.0, 0.0, Sizes.rightWidgetPadding, 0.0), child: GestureDetector( child: Text("${entity.formattedState}", textAlign: TextAlign.right, style: new TextStyle( - fontSize: Entity.stateFontSize, + fontSize: Sizes.stateFontSize, )), onTap: () => _handleStateTap(context, entity), )); diff --git a/lib/entity_widgets/state/simple_state.dart b/lib/entity_widgets/state/simple_state.dart index bed2ae6..4a815c6 100644 --- a/lib/entity_widgets/state/simple_state.dart +++ b/lib/entity_widgets/state/simple_state.dart @@ -10,13 +10,13 @@ class SimpleEntityState extends StatelessWidget { Widget build(BuildContext context) { final entityModel = EntityModel.of(context); Widget result = Padding( - padding: EdgeInsets.fromLTRB(0.0, 0.0, Entity.rightWidgetPadding, 0.0), + padding: EdgeInsets.fromLTRB(0.0, 0.0, Sizes.rightWidgetPadding, 0.0), child: GestureDetector( child: Text( "${entityModel.entity.state}${entityModel.entity.unitOfMeasurement}", textAlign: TextAlign.right, style: new TextStyle( - fontSize: Entity.stateFontSize, + fontSize: Sizes.stateFontSize, )), onTap: () => entityModel.handleTap ? eventBus.fire(new ShowEntityPageEvent(entityModel.entity)) diff --git a/lib/entity_widgets/state/switch_state.dart b/lib/entity_widgets/state/switch_state.dart index 702b989..3423c25 100644 --- a/lib/entity_widgets/state/switch_state.dart +++ b/lib/entity_widgets/state/switch_state.dart @@ -52,13 +52,13 @@ class _SwitchStateWidgetState extends State { onPressed: () => _setNewState(false, entity), icon: Icon(MaterialDesignIcons.createIconDataFromIconName("mdi:flash-off")), color: entity.assumedState == 'on' ? Colors.black : Colors.blue, - iconSize: Entity.iconSize, + iconSize: Sizes.iconSize, ), IconButton( onPressed: () => _setNewState(true, entity), icon: Icon(MaterialDesignIcons.createIconDataFromIconName("mdi:flash")), color: entity.assumedState == 'on' ? Colors.blue : Colors.black, - iconSize: Entity.iconSize + iconSize: Sizes.iconSize ) ], ), diff --git a/lib/main.dart b/lib/main.dart index e59543a..18113f2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -56,6 +56,7 @@ part 'entity_widgets/state/button_state.dart'; part 'entity_widgets/controls/climate_controls.dart'; part 'entity_widgets/controls/cover_controls.dart'; part 'entity_widgets/controls/light_controls.dart'; +part 'entity_widgets/controls/media_player_widget.dart'; part 'settings.page.dart'; part 'home_assistant.class.dart'; part 'log.page.dart'; @@ -66,6 +67,7 @@ part 'entity_collection.class.dart'; part 'ui_class/ui.dart'; 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/unsupported_card.dart'; diff --git a/lib/ui_class/sizes_class.dart b/lib/ui_class/sizes_class.dart new file mode 100644 index 0000000..b0f04a8 --- /dev/null +++ b/lib/ui_class/sizes_class.dart @@ -0,0 +1,14 @@ +part of '../main.dart'; + +class Sizes { + static const rightWidgetPadding = 14.0; + static const leftWidgetPadding = 8.0; + static const extendedWidgetHeight = 50.0; + static const iconSize = 28.0; + static const stateFontSize = 16.0; + static const nameFontSize = 16.0; + static const smallFontSize = 14.0; + static const largeFontSize = 24.0; + static const inputWidth = 160.0; + static const rowPadding = 10.0; +} \ No newline at end of file diff --git a/lib/ui_widgets/media_control_card.dart b/lib/ui_widgets/media_control_card.dart index 5f9867c..fa1c26c 100644 --- a/lib/ui_widgets/media_control_card.dart +++ b/lib/ui_widgets/media_control_card.dart @@ -14,126 +14,16 @@ class MediaControlCardWidget extends StatelessWidget { if ((card.linkedEntity == null) || (card.linkedEntity.isHidden)) { return Container(width: 0.0, height: 0.0,); } - List body = []; - body.add(Stack( - alignment: AlignmentDirectional.topEnd, - children: [ - _buildImage(), - Positioned( - bottom: 0.0, - left: 0.0, - right: 0.0, - child: Container( - color: Colors.black45, - child: _buildState(), - ), - ), - Positioned( - bottom: 0.0, - left: 0.0, - right: 0.0, - child: _buildProgress(), - ) - ], - )); + return Card( - child: Column( - //crossAxisAlignment: CrossAxisAlignment.center, - children: body + child: EntityModel( + entity: card.linkedEntity, + handleTap: null, + child: MediaPlayerWidget() ) ); } - Widget _buildProgress() { - double progress; - try { - DateTime lastUpdated = DateTime.parse( - card.linkedEntity.attributes["media_position_updated_at"]).toLocal(); - Duration duration = Duration(seconds: card.linkedEntity._getIntAttributeValue("media_duration") ?? 1); - Duration position = Duration(seconds: card.linkedEntity._getIntAttributeValue("media_position") ?? 0); - int currentPosition = position.inSeconds; - if (card.linkedEntity.state == "playing") { - int differenceInSeconds = DateTime - .now() - .difference(lastUpdated) - .inSeconds; - currentPosition = currentPosition + differenceInSeconds; - } - progress = currentPosition / duration.inSeconds; - return LinearProgressIndicator( - value: progress, - backgroundColor: Colors.black45, - valueColor: AlwaysStoppedAnimation(EntityColors.stateColor("on")), - ); - } catch (e) { - progress = 0.0; - } - return LinearProgressIndicator( - value: progress, - backgroundColor: Colors.black45, - ); - } - Widget _buildState() { - TextStyle style = TextStyle( - fontSize: 14.0, - color: Colors.white, - fontWeight: FontWeight.normal, - height: 1.2 - ); - List states = []; - states.add(Text("${card.linkedEntity.displayName}", style: style)); - String state = card.linkedEntity.state; - if (state == null || state == "off" || state == "unavailable" || state == "idle") { - states.add(Text("${card.linkedEntity.state}", style: style.apply(fontSizeDelta: 4.0),)); - } - if (card.linkedEntity.attributes['media_title'] != null) { - states.add(Text("${card.linkedEntity.attributes['media_title']}", style: style.apply(fontSizeDelta: 6.0, fontWeightDelta: 50),)); - } - if (card.linkedEntity.attributes['media_content_type'] == "music") { - states.add(Text("${card.linkedEntity.attributes['media_artist'] ?? card.linkedEntity.attributes['app_name']}", style: style.apply(fontSizeDelta: 4.0),)); - } else if (card.linkedEntity.attributes['app_name'] != null) { - states.add(Text("${card.linkedEntity.attributes['app_name']}", style: style.apply(fontSizeDelta: 4.0),)); - } - return Padding( - padding: EdgeInsets.fromLTRB(Entity.leftWidgetPadding, Entity.rowPadding, Entity.rightWidgetPadding, Entity.rowPadding), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: states, - ), - ); - } - - Widget _buildImage() { - String state = card.linkedEntity.state; - if (homeAssistantWebHost != null && card.linkedEntity.entityPicture != null && state != "off" && state != "unavailable" && state != "idle") { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image( - image: CachedNetworkImageProvider("$homeAssistantWebHost${card.linkedEntity.entityPicture}"), - height: 240.0, - width: 320.0, - fit: BoxFit.fitHeight, - ) - ], - ); - } else { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - MaterialDesignIcons.createIconDataFromIconName("mdi:movie"), - size: 150.0, - color: EntityColors.stateColor("$state"), - ) - ], - ); - /*return Container( - color: Colors.blue, - height: 80.0, - );*/ - } - } } \ No newline at end of file diff --git a/lib/ui_widgets/unsupported_card.dart b/lib/ui_widgets/unsupported_card.dart index 6bc784b..3ebd9c2 100644 --- a/lib/ui_widgets/unsupported_card.dart +++ b/lib/ui_widgets/unsupported_card.dart @@ -31,14 +31,14 @@ class UnsupportedCardWidget extends StatelessWidget { if (card.linkedEntity != null) { result.addAll([ Padding( - padding: EdgeInsets.fromLTRB(0.0, Entity.rowPadding, 0.0, Entity.rowPadding), + padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), child: card.linkedEntity.buildDefaultWidget(context), ) ]); } else { result.addAll([ Padding( - padding: EdgeInsets.fromLTRB(Entity.leftWidgetPadding, Entity.rowPadding, Entity.rightWidgetPadding, Entity.rowPadding), + padding: EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, Sizes.rowPadding), child: Text("'${card.type}' card is not supported yet"), ), ]); diff --git a/pubspec.lock b/pubspec.lock index badec13..a8caf7d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.32.4" + version: "0.33.0" archive: dependency: transitive description: @@ -42,7 +42,7 @@ packages: name: cached_network_image url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.5.0+1" charcode: dependency: transitive description: @@ -56,14 +56,14 @@ packages: name: charts_common url: "https://pub.dartlang.org" source: hosted - version: "0.4.0" + version: "0.5.0" charts_flutter: dependency: "direct main" description: name: charts_flutter url: "https://pub.dartlang.org" source: hosted - version: "0.4.0" + version: "0.5.0" collection: dependency: transitive description: @@ -91,7 +91,7 @@ packages: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.5" + version: "0.14.6" dart_config: dependency: transitive description: @@ -126,7 +126,7 @@ packages: name: flutter_cache_manager url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.2.0+1" flutter_colorpicker: dependency: "direct main" description: @@ -152,7 +152,7 @@ packages: name: front_end url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.6" glob: dependency: transitive description: @@ -173,7 +173,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+17" + version: "0.12.0" http_multi_server: dependency: transitive description: @@ -229,7 +229,7 @@ packages: name: kernel url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "0.3.6" logging: dependency: transitive description: @@ -285,7 +285,7 @@ packages: name: package_resolver url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.6" path: dependency: transitive description: @@ -395,7 +395,7 @@ packages: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.7" + version: "0.10.8" source_span: dependency: transitive description: @@ -444,7 +444,7 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.4" typed_data: dependency: transitive description: @@ -458,7 +458,7 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "3.0.3" + version: "4.0.1" utf: dependency: transitive description: @@ -516,5 +516,5 @@ packages: source: hosted version: "2.1.15" sdks: - dart: ">=2.0.0 <=2.1.0-dev.5.0.flutter-a2eb050044" - flutter: ">=0.1.4 <2.0.0" + dart: ">=2.0.0 <=2.1.0-dev.8.0.flutter-bf26f760b1" + flutter: ">=0.5.6 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index da5e844..d562e87 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,13 +10,13 @@ dependencies: flutter: sdk: flutter shared_preferences: any - progress_indicators: ^0.1.2 - event_bus: ^1.0.1 - cached_network_image: ^0.4.1 - url_launcher: ^3.0.3 - date_format: ^1.0.5 - flutter_colorpicker: ^0.1.0 - charts_flutter: ^0.4.0 + progress_indicators: any + event_bus: any + cached_network_image: any + url_launcher: any + date_format: any + flutter_colorpicker: any + charts_flutter: any # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. @@ -25,7 +25,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_launcher_icons: ^0.6.1 + flutter_launcher_icons: any flutter_icons: android: true