Resolves #530 Badges refactoring
This commit is contained in:
		@@ -10,17 +10,43 @@ class Badges extends StatelessWidget {
 | 
			
		||||
    List<EntityWrapper> entitiesToShow = badges.getEntitiesToShow();
 | 
			
		||||
    
 | 
			
		||||
    if (entitiesToShow.isNotEmpty) {
 | 
			
		||||
      return Wrap(
 | 
			
		||||
        alignment: WrapAlignment.center,
 | 
			
		||||
        spacing: 10.0,
 | 
			
		||||
        runSpacing: 1.0,
 | 
			
		||||
        children: entitiesToShow.map((entity) =>
 | 
			
		||||
            EntityModel(
 | 
			
		||||
              entityWrapper: entity,
 | 
			
		||||
              child: BadgeWidget(),
 | 
			
		||||
              handleTap: true,
 | 
			
		||||
            )).toList(),
 | 
			
		||||
      );
 | 
			
		||||
      if (ConnectionManager().scrollBadges) {
 | 
			
		||||
        return ConstrainedBox(
 | 
			
		||||
          constraints: BoxConstraints.tightFor(height: 112),
 | 
			
		||||
          child: SingleChildScrollView(
 | 
			
		||||
            scrollDirection: Axis.horizontal,
 | 
			
		||||
            child: Row(
 | 
			
		||||
              mainAxisSize: MainAxisSize.min,
 | 
			
		||||
              mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
              children: entitiesToShow.map((entity) =>
 | 
			
		||||
                EntityModel(
 | 
			
		||||
                  entityWrapper: entity,
 | 
			
		||||
                  child: Padding(
 | 
			
		||||
                    padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
 | 
			
		||||
                    child: BadgeWidget(),
 | 
			
		||||
                  ),
 | 
			
		||||
                  handleTap: true,
 | 
			
		||||
                )).toList()
 | 
			
		||||
            ),
 | 
			
		||||
          )
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        return Padding(
 | 
			
		||||
          padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
 | 
			
		||||
          child: Wrap(
 | 
			
		||||
            alignment: WrapAlignment.center,
 | 
			
		||||
            spacing: 10.0,
 | 
			
		||||
            runSpacing: 5,
 | 
			
		||||
            children: entitiesToShow.map((entity) =>
 | 
			
		||||
                EntityModel(
 | 
			
		||||
                  entityWrapper: entity,
 | 
			
		||||
                  child: BadgeWidget(),
 | 
			
		||||
                  handleTap: true,
 | 
			
		||||
                )).toList(),
 | 
			
		||||
          )
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return Container(height: 0.0, width: 0.0,);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -57,72 +57,73 @@ class BadgeWidget extends StatelessWidget {
 | 
			
		||||
      onBadgeText = Container(width: 0.0, height: 0.0);
 | 
			
		||||
    } else {
 | 
			
		||||
      onBadgeText = Container(
 | 
			
		||||
          padding: EdgeInsets.fromLTRB(6.0, 2.0, 6.0, 2.0),
 | 
			
		||||
          child: Text("$onBadgeTextValue",
 | 
			
		||||
              style: Theme.of(context).textTheme.overline.copyWith(
 | 
			
		||||
                color: HAClientTheme().getOnBadgeTextColor()
 | 
			
		||||
              ),
 | 
			
		||||
              textAlign: TextAlign.center,
 | 
			
		||||
              softWrap: false,
 | 
			
		||||
              overflow: TextOverflow.fade),
 | 
			
		||||
          decoration: new BoxDecoration(
 | 
			
		||||
            color: iconColor,
 | 
			
		||||
            borderRadius: BorderRadius.circular(9.0),
 | 
			
		||||
          ));
 | 
			
		||||
        constraints: BoxConstraints(maxWidth: 50),
 | 
			
		||||
        padding: EdgeInsets.fromLTRB(6.0, 2.0, 6.0, 2.0),
 | 
			
		||||
        child: Text("$onBadgeTextValue",
 | 
			
		||||
            style: Theme.of(context).textTheme.overline.copyWith(
 | 
			
		||||
              color: HAClientTheme().getOnBadgeTextColor()
 | 
			
		||||
            ),
 | 
			
		||||
            textAlign: TextAlign.center,
 | 
			
		||||
            softWrap: false,
 | 
			
		||||
            overflow: TextOverflow.ellipsis
 | 
			
		||||
          ),
 | 
			
		||||
        decoration: new BoxDecoration(
 | 
			
		||||
          color: iconColor,
 | 
			
		||||
          borderRadius: BorderRadius.circular(9.0),
 | 
			
		||||
        )
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    return GestureDetector(
 | 
			
		||||
        child: Column(
 | 
			
		||||
          mainAxisSize: MainAxisSize.min,
 | 
			
		||||
          children: <Widget>[
 | 
			
		||||
            Container(
 | 
			
		||||
              //margin: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
 | 
			
		||||
              width: 45,
 | 
			
		||||
              height: 45,
 | 
			
		||||
              decoration: new BoxDecoration(
 | 
			
		||||
                // Circle shape
 | 
			
		||||
                shape: BoxShape.circle,
 | 
			
		||||
                color: Theme.of(context).cardColor,
 | 
			
		||||
                // The border you want
 | 
			
		||||
                border: new Border.all(
 | 
			
		||||
                  width: 2.0,
 | 
			
		||||
                  color: iconColor,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              child: Stack(
 | 
			
		||||
                overflow: Overflow.visible,
 | 
			
		||||
                children: <Widget>[
 | 
			
		||||
                  Positioned(
 | 
			
		||||
                    width: 45,
 | 
			
		||||
                    height: 45,
 | 
			
		||||
                    top: 0.0,
 | 
			
		||||
                    left: 0.0,
 | 
			
		||||
                    child: FittedBox(
 | 
			
		||||
                      fit: BoxFit.contain,
 | 
			
		||||
                      alignment: Alignment.center,
 | 
			
		||||
                      child: badgeIcon,
 | 
			
		||||
            Stack(
 | 
			
		||||
              overflow: Overflow.visible,
 | 
			
		||||
              alignment: Alignment.center,
 | 
			
		||||
              children: <Widget>[
 | 
			
		||||
                Container(
 | 
			
		||||
                  width: 45,
 | 
			
		||||
                  height: 45,
 | 
			
		||||
                  decoration: new BoxDecoration(
 | 
			
		||||
                    // Circle shape
 | 
			
		||||
                    shape: BoxShape.circle,
 | 
			
		||||
                    color: Theme.of(context).cardColor,
 | 
			
		||||
                    // The border you want
 | 
			
		||||
                    border: Border.all(
 | 
			
		||||
                      width: 2.0,
 | 
			
		||||
                      color: iconColor,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                  Positioned(
 | 
			
		||||
                    bottom: -9.0,
 | 
			
		||||
                    left: -10.0,
 | 
			
		||||
                    right: -10.0,
 | 
			
		||||
                    child: Center(
 | 
			
		||||
                      child: onBadgeText,
 | 
			
		||||
                    )
 | 
			
		||||
                ),
 | 
			
		||||
                SizedBox(
 | 
			
		||||
                  width: 38,
 | 
			
		||||
                  height: 26,
 | 
			
		||||
                  child: FittedBox(
 | 
			
		||||
                    fit: BoxFit.contain,
 | 
			
		||||
                    alignment: Alignment.center,
 | 
			
		||||
                    child: badgeIcon,
 | 
			
		||||
                  )
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
                ),
 | 
			
		||||
                Positioned(
 | 
			
		||||
                  bottom: -6,
 | 
			
		||||
                  child: onBadgeText
 | 
			
		||||
                )
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
            Container(
 | 
			
		||||
              width: 60.0,
 | 
			
		||||
              constraints: BoxConstraints(maxWidth: 45),
 | 
			
		||||
              padding: EdgeInsets.only(top: 10),
 | 
			
		||||
              child: Text(
 | 
			
		||||
                "${entityModel.entityWrapper.displayName}",
 | 
			
		||||
                textAlign: TextAlign.center,
 | 
			
		||||
                style: Theme.of(context).textTheme.caption,
 | 
			
		||||
                style: Theme.of(context).textTheme.caption.copyWith(
 | 
			
		||||
                  fontSize: 10
 | 
			
		||||
                ),
 | 
			
		||||
                softWrap: true,
 | 
			
		||||
                maxLines: 3,
 | 
			
		||||
                overflow: TextOverflow.ellipsis,
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
        onTap: () => entityModel.entityWrapper.handleTap(),
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ class ConnectionManager {
 | 
			
		||||
  String oauthUrl;
 | 
			
		||||
  String webhookId;
 | 
			
		||||
  double haVersion;
 | 
			
		||||
  bool scrollBadges;
 | 
			
		||||
  String mobileAppDeviceName;
 | 
			
		||||
  bool settingsLoaded = false;
 | 
			
		||||
  int appIntegrationVersion;
 | 
			
		||||
@@ -48,6 +49,7 @@ class ConnectionManager {
 | 
			
		||||
      webhookId = prefs.getString('app-webhook-id');
 | 
			
		||||
      appIntegrationVersion = prefs.getInt('app-integration-version') ?? 0;
 | 
			
		||||
      mobileAppDeviceName = prefs.getString('app-integration-device-name');
 | 
			
		||||
      scrollBadges = prefs.getBool('scroll-badges') ?? true;
 | 
			
		||||
      displayHostname = "$_domain:$_port";
 | 
			
		||||
      _webSocketAPIEndpoint =
 | 
			
		||||
      "${prefs.getString('hassio-protocol')}://$_domain:$_port/api/websocket";
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ class LookAndFeelSettingsPage extends StatefulWidget {
 | 
			
		||||
class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> {
 | 
			
		||||
 | 
			
		||||
  AppTheme _currentTheme;
 | 
			
		||||
  bool _changed = false;
 | 
			
		||||
  bool _scrollBadges = false;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
@@ -26,13 +26,15 @@ class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> {
 | 
			
		||||
    SharedPreferences.getInstance().then((prefs) {
 | 
			
		||||
      setState(() {
 | 
			
		||||
        _currentTheme = AppTheme.values[prefs.getInt("app-theme") ?? AppTheme.defaultTheme.index];
 | 
			
		||||
        _scrollBadges = prefs.getBool('scroll-badges') ?? true;
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _saveSettings(AppTheme theme) {
 | 
			
		||||
  _saveTheme(AppTheme theme) {
 | 
			
		||||
    SharedPreferences.getInstance().then((prefs) {
 | 
			
		||||
      prefs.setInt('app-theme', theme.index);
 | 
			
		||||
      prefs.setBool('scroll-badges', _scrollBadges);
 | 
			
		||||
      setState(() {
 | 
			
		||||
        _currentTheme = theme;
 | 
			
		||||
        eventBus.fire(ChangeThemeEvent(_currentTheme));
 | 
			
		||||
@@ -40,6 +42,12 @@ class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future _saveOther() async {
 | 
			
		||||
    SharedPreferences prefs = await SharedPreferences.getInstance();
 | 
			
		||||
    ConnectionManager().scrollBadges = _scrollBadges;
 | 
			
		||||
    await prefs.setBool('scroll-badges', _scrollBadges);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Map appThemeName = {
 | 
			
		||||
    AppTheme.defaultTheme: 'Default',
 | 
			
		||||
    AppTheme.haTheme: 'Home Assistant theme',
 | 
			
		||||
@@ -59,15 +67,35 @@ class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> {
 | 
			
		||||
            iconSize: 30.0,
 | 
			
		||||
            isExpanded: true,
 | 
			
		||||
            style: Theme.of(context).textTheme.title,
 | 
			
		||||
            //hint: Text("Select ${caption.toLowerCase()}"),
 | 
			
		||||
            items: AppTheme.values.map((value) {
 | 
			
		||||
              return new DropdownMenuItem<AppTheme>(
 | 
			
		||||
                value: value,
 | 
			
		||||
                child: Text('${appThemeName[value]}'),
 | 
			
		||||
              );
 | 
			
		||||
            }).toList(),
 | 
			
		||||
            onChanged: (theme) => _saveSettings(theme),
 | 
			
		||||
          )
 | 
			
		||||
            onChanged: (theme) => _saveTheme(theme),
 | 
			
		||||
          ),
 | 
			
		||||
          Container(height: Sizes.doubleRowPadding),
 | 
			
		||||
          Text("Badges display:", style: Theme.of(context).textTheme.body2),
 | 
			
		||||
          Container(height: Sizes.rowPadding),
 | 
			
		||||
          DropdownButton<bool>(
 | 
			
		||||
            value: _scrollBadges,
 | 
			
		||||
            iconSize: 30.0,
 | 
			
		||||
            isExpanded: true,
 | 
			
		||||
            style: Theme.of(context).textTheme.title,
 | 
			
		||||
            items: [true, false].map((value) {
 | 
			
		||||
              return new DropdownMenuItem<bool>(
 | 
			
		||||
                value: value,
 | 
			
		||||
                child: Text('${value ? 'Horizontal scroll' : 'In rows'}'),
 | 
			
		||||
              );
 | 
			
		||||
            }).toList(),
 | 
			
		||||
            onChanged: (val) {
 | 
			
		||||
              setState(() {
 | 
			
		||||
                _scrollBadges = val;
 | 
			
		||||
              });
 | 
			
		||||
              _saveOther();
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
        ]
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ part of 'main.dart';
 | 
			
		||||
 | 
			
		||||
class HAView {
 | 
			
		||||
  List<CardData> cards = [];
 | 
			
		||||
  CardData badges;
 | 
			
		||||
  Entity linkedEntity;
 | 
			
		||||
  String name;
 | 
			
		||||
  String id;
 | 
			
		||||
@@ -16,10 +17,10 @@ class HAView {
 | 
			
		||||
    isPanel = rawData['panel'] ?? false;
 | 
			
		||||
 | 
			
		||||
    if (rawData['badges'] != null && !isPanel) {
 | 
			
		||||
        cards.add(CardData.parse({
 | 
			
		||||
        badges = CardData.parse({
 | 
			
		||||
          'type': CardType.BADGES,
 | 
			
		||||
          'badges': rawData['badges']
 | 
			
		||||
        }));
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      (rawData['cards'] ?? []).forEach((rawCardData) {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,12 @@ class ViewWidget extends StatelessWidget {
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      Widget cardsContainer;
 | 
			
		||||
      Widget badgesContainer;
 | 
			
		||||
      if (this.view.badges != null && this.view.badges is BadgesData) {
 | 
			
		||||
        badgesContainer = this.view.badges.buildCardWidget();
 | 
			
		||||
      } else {
 | 
			
		||||
        badgesContainer = Container(width: 0, height: 0);
 | 
			
		||||
      }
 | 
			
		||||
      if (this.view.cards.isNotEmpty) {
 | 
			
		||||
        cardsContainer = DynamicMultiColumnLayout(
 | 
			
		||||
          minColumnWidth: Sizes.minViewColumnWidth,
 | 
			
		||||
@@ -45,9 +51,14 @@ class ViewWidget extends StatelessWidget {
 | 
			
		||||
        cardsContainer = Container();
 | 
			
		||||
      }
 | 
			
		||||
      return SingleChildScrollView(
 | 
			
		||||
          scrollDirection: Axis.vertical,
 | 
			
		||||
          padding: EdgeInsets.all(0),
 | 
			
		||||
          child: cardsContainer
 | 
			
		||||
          child: Column(
 | 
			
		||||
            mainAxisSize: MainAxisSize.min,
 | 
			
		||||
            children: <Widget>[
 | 
			
		||||
              badgesContainer,
 | 
			
		||||
              cardsContainer
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -31,8 +31,8 @@ dependencies:
 | 
			
		||||
  workmanager: ^0.2.2
 | 
			
		||||
  battery: ^1.0.0
 | 
			
		||||
  firebase_crashlytics: ^0.1.3+3
 | 
			
		||||
  syncfusion_flutter_core: ^18.1.43
 | 
			
		||||
  syncfusion_flutter_gauges: ^18.1.43
 | 
			
		||||
  syncfusion_flutter_core: ^18.1.48
 | 
			
		||||
  syncfusion_flutter_gauges: ^18.1.48
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
dev_dependencies:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user