From 1575cc4aec6116f0f904c0109facc0464456d40c Mon Sep 17 00:00:00 2001 From: Tommy Chow <54859075+tommyxchow@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:49:21 -0400 Subject: [PATCH] Redesign settings screen (#100) * Add FAQ link (#99) * Add reset settings button & tweak icons (#92) * Tweak settings casings, subtitles & defaults (#92) * Add SVG logo & reset all settings warning (#92) * Minor settings tweaks (#92) * Reorder settings & fixes (#92) * Add Twitch logo to login & profile tweaks (#92) --- assets/icons/TwitchGlitchWhite.png | Bin 0 -> 41204 bytes assets/icons/logo.svg | 19 ++ .../settings/sections/account_settings.dart | 2 +- .../settings/sections/chat_settings.dart | 144 ++++++------- .../settings/sections/general_settings.dart | 6 +- .../settings/sections/other_settings.dart | 56 +++++- .../settings/sections/video_settings.dart | 16 +- lib/screens/settings/settings.dart | 1 + .../settings/stores/settings_store.dart | 189 ++++++++++++------ .../settings/stores/settings_store.g.dart | 52 +++-- .../settings/widgets/profile_card.dart | 38 +++- lib/widgets/section_header.dart | 2 +- pubspec.yaml | 3 +- 13 files changed, 357 insertions(+), 171 deletions(-) create mode 100644 assets/icons/TwitchGlitchWhite.png create mode 100644 assets/icons/logo.svg diff --git a/assets/icons/TwitchGlitchWhite.png b/assets/icons/TwitchGlitchWhite.png new file mode 100644 index 0000000000000000000000000000000000000000..298d79bd1a28f089121f4284b172dca48d2d62cb GIT binary patch literal 41204 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 biS9lBTyWXw?{?JTwW$+lR%|*cwer6Jte*9D literal 0 HcmV?d00001 diff --git a/assets/icons/logo.svg b/assets/icons/logo.svg new file mode 100644 index 00000000..c34811be --- /dev/null +++ b/assets/icons/logo.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/lib/screens/settings/sections/account_settings.dart b/lib/screens/settings/sections/account_settings.dart index 0c967fff..2701a0fe 100644 --- a/lib/screens/settings/sections/account_settings.dart +++ b/lib/screens/settings/sections/account_settings.dart @@ -20,7 +20,7 @@ class AccountSettings extends StatelessWidget { Widget build(BuildContext context) { return Observer( builder: (context) => ExpansionTile( - leading: const Icon(Icons.manage_accounts), + leading: const Icon(Icons.account_circle), title: const Text( 'Account', style: TextStyle( diff --git a/lib/screens/settings/sections/chat_settings.dart b/lib/screens/settings/sections/chat_settings.dart index b646cc0d..7da6adca 100644 --- a/lib/screens/settings/sections/chat_settings.dart +++ b/lib/screens/settings/sections/chat_settings.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:frosty/constants/constants.dart'; import 'package:frosty/screens/settings/stores/settings_store.dart'; -import 'package:frosty/widgets/section_header.dart'; class ChatSettings extends StatefulWidget { final SettingsStore settingsStore; @@ -35,40 +34,43 @@ class _ChatSettingsState extends State { ), children: [ SwitchListTile.adaptive( - title: const Text('Show bottom bar'), + title: const Text('Bottom Bar'), + subtitle: const Text('Displays the bottom text field bar.'), value: settingsStore.showBottomBar, onChanged: (newValue) => settingsStore.showBottomBar = newValue, ), SwitchListTile.adaptive( - title: const Text('Show deleted messages'), - value: settingsStore.showDeletedMessages, - onChanged: (newValue) => settingsStore.showDeletedMessages = newValue, + isThreeLine: true, + title: const Text('Readable Name Colors'), + subtitle: const Text('Adjusts the lightness value of overly bright/dark names.'), + value: settingsStore.useReadableColors, + onChanged: (newValue) => settingsStore.useReadableColors = newValue, ), SwitchListTile.adaptive( isThreeLine: true, - title: const Text('Show zero-width emotes'), - subtitle: const Text('Makes "stacked" emotes from BetterTTV and 7TV visible in chat messages.'), + title: const Text('Zero-Width Emotes'), + subtitle: const Text('Displays "stacked" emotes from BetterTTV and 7TV.'), value: settingsStore.showZeroWidth, onChanged: (newValue) => settingsStore.showZeroWidth = newValue, ), SwitchListTile.adaptive( isThreeLine: true, - title: const Text('Show message dividers'), - subtitle: const Text('Displays a subtle divider between each chat message.'), - value: settingsStore.showChatMessageDividers, - onChanged: (newValue) => settingsStore.showChatMessageDividers = newValue, + title: const Text('Show Deleted Messages'), + subtitle: const Text('Restores the original message of deleted messages.'), + value: settingsStore.showDeletedMessages, + onChanged: (newValue) => settingsStore.showDeletedMessages = newValue, ), SwitchListTile.adaptive( isThreeLine: true, - title: const Text('Use readable colors for chat names'), - subtitle: const Text('Adjusts the lightness value of overly bright/dark names in chat.'), - value: settingsStore.useReadableColors, - onChanged: (newValue) => settingsStore.useReadableColors = newValue, + title: const Text('Message Dividers'), + subtitle: const Text('Displays a subtle divider between each message.'), + value: settingsStore.showChatMessageDividers, + onChanged: (newValue) => settingsStore.showChatMessageDividers = newValue, ), ListTile( isThreeLine: true, - title: const Text('Message timestamps'), - subtitle: const Text('Displays timestamps for when a chat message was sent.'), + title: const Text('Message Timestamps'), + subtitle: const Text('Displays timestamps for when a message was sent.'), trailing: DropdownButton( value: settingsStore.timestampType, onChanged: (TimestampType? newTimestamp) => settingsStore.timestampType = newTimestamp!, @@ -81,7 +83,13 @@ class _ChatSettingsState extends State { ), ), const SizedBox(height: 10.0), - const SectionHeader('Message Appearance'), + const Padding( + padding: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 5.0), + child: Text( + 'Message Appearance', + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0), + ), + ), Container( width: double.infinity, padding: const EdgeInsets.all(20.0), @@ -136,55 +144,7 @@ class _ChatSettingsState extends State { ListTile( title: Row( children: [ - const Text('Message scale'), - const Spacer(), - Text('${settingsStore.messageScale.toStringAsFixed(2)}x'), - ], - ), - subtitle: Slider.adaptive( - value: settingsStore.messageScale, - min: 0.5, - max: 2.0, - divisions: 6, - onChanged: (newValue) => settingsStore.messageScale = newValue, - ), - ), - ListTile( - title: Row( - children: [ - const Text('Message spacing'), - const Spacer(), - Text(settingsStore.messageSpacing.toStringAsFixed(0).toString()), - ], - ), - subtitle: Slider.adaptive( - value: settingsStore.messageSpacing, - min: 0.0, - max: 30.0, - divisions: 6, - onChanged: (newValue) => settingsStore.messageSpacing = newValue, - ), - ), - ListTile( - title: Row( - children: [ - const Text('Font size'), - const Spacer(), - Text(settingsStore.fontSize.toInt().toString()), - ], - ), - subtitle: Slider.adaptive( - value: settingsStore.fontSize, - min: 5, - max: 20, - divisions: 15, - onChanged: (newValue) => settingsStore.fontSize = newValue, - ), - ), - ListTile( - title: Row( - children: [ - const Text('Badge scale'), + const Text('Badge Scale'), const Spacer(), Text('${settingsStore.badgeScale.toStringAsFixed(2)}x'), ], @@ -200,7 +160,7 @@ class _ChatSettingsState extends State { ListTile( title: Row( children: [ - const Text('Emote scale'), + const Text('Emote Scale'), const Spacer(), Text('${settingsStore.emoteScale.toStringAsFixed(2)}x'), ], @@ -213,6 +173,54 @@ class _ChatSettingsState extends State { onChanged: (newValue) => settingsStore.emoteScale = newValue, ), ), + ListTile( + title: Row( + children: [ + const Text('Message Scale'), + const Spacer(), + Text('${settingsStore.messageScale.toStringAsFixed(2)}x'), + ], + ), + subtitle: Slider.adaptive( + value: settingsStore.messageScale, + min: 0.5, + max: 2.0, + divisions: 6, + onChanged: (newValue) => settingsStore.messageScale = newValue, + ), + ), + ListTile( + title: Row( + children: [ + const Text('Message Spacing'), + const Spacer(), + Text(settingsStore.messageSpacing.toStringAsFixed(0).toString()), + ], + ), + subtitle: Slider.adaptive( + value: settingsStore.messageSpacing, + min: 0.0, + max: 30.0, + divisions: 6, + onChanged: (newValue) => settingsStore.messageSpacing = newValue, + ), + ), + ListTile( + title: Row( + children: [ + const Text('Font Size'), + const Spacer(), + Text(settingsStore.fontSize.toInt().toString()), + ], + ), + subtitle: Slider.adaptive( + value: settingsStore.fontSize, + min: 5, + max: 20, + divisions: 15, + onChanged: (newValue) => settingsStore.fontSize = newValue, + ), + ), ], ), ); diff --git a/lib/screens/settings/sections/general_settings.dart b/lib/screens/settings/sections/general_settings.dart index 3ae34300..7a474353 100644 --- a/lib/screens/settings/sections/general_settings.dart +++ b/lib/screens/settings/sections/general_settings.dart @@ -13,7 +13,7 @@ class GeneralSettings extends StatelessWidget { return Observer( builder: (context) => ExpansionTile( - leading: const Icon(Icons.app_settings_alt), + leading: const Icon(Icons.settings), title: const Text( 'General', style: TextStyle( @@ -36,7 +36,9 @@ class GeneralSettings extends StatelessWidget { ), ), SwitchListTile.adaptive( - title: const Text('Show stream uptime on thumbnails'), + isThreeLine: true, + title: const Text('Stream Uptime on Thumbnails'), + subtitle: const Text('Displays the uptime of the stream in the HH:MM:SS format.'), value: settingsStore.showThumbnailUptime, onChanged: (newValue) => settingsStore.showThumbnailUptime = newValue, ), diff --git a/lib/screens/settings/sections/other_settings.dart b/lib/screens/settings/sections/other_settings.dart index 007985bc..1ecd4193 100644 --- a/lib/screens/settings/sections/other_settings.dart +++ b/lib/screens/settings/sections/other_settings.dart @@ -1,10 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:frosty/constants/constants.dart'; import 'package:frosty/screens/settings/stores/settings_store.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:url_launcher/url_launcher.dart'; class OtherSettings extends StatelessWidget { final SettingsStore settingsStore; @@ -13,10 +15,40 @@ class OtherSettings extends StatelessWidget { required this.settingsStore, }) : super(key: key); + Future _showConfirmDialog(BuildContext context) { + return showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Reset All Settings'), + content: const Text('Are you sure you want to reset all settings?'), + actions: [ + TextButton( + onPressed: Navigator.of(context).pop, + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + settingsStore.reset(); + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Settings reset!'), + behavior: SnackBarBehavior.floating, + ), + ); + }, + child: const Text('Yes'), + style: TextButton.styleFrom(primary: Colors.red), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { return ExpansionTile( - leading: const Icon(Icons.miscellaneous_services), + leading: const Icon(Icons.help), title: const Text( 'Other', style: TextStyle( @@ -33,15 +65,24 @@ class OtherSettings extends StatelessWidget { showAboutDialog( context: context, + applicationIcon: SvgPicture.asset( + 'assets/icons/logo.svg', + height: 80, + ), applicationName: packageInfo.appName, applicationVersion: 'Version ${packageInfo.version} (${packageInfo.buildNumber})', applicationLegalese: '\u{a9} 2022 Tommy Chow', ); }, ), + ListTile( + leading: const Icon(Icons.launch), + title: const Text('FAQ'), + onTap: () => launch('https://github.com/tommyxchow/frosty#faq'), + ), Observer( builder: (_) => SwitchListTile.adaptive( - title: const Text('Send anonymous crash logs'), + title: const Text('Send Anonymous Crash Logs'), value: settingsStore.sendCrashLogs, onChanged: (newValue) { if (newValue == true) { @@ -54,7 +95,7 @@ class OtherSettings extends StatelessWidget { ), ), Container( - padding: const EdgeInsets.all(10.0), + padding: const EdgeInsets.symmetric(horizontal: 10.0), width: double.infinity, child: ElevatedButton.icon( icon: const Icon(Icons.delete_sweep), @@ -70,6 +111,15 @@ class OtherSettings extends StatelessWidget { }, ), ), + Container( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + width: double.infinity, + child: ElevatedButton.icon( + icon: const Icon(Icons.restore), + label: const Text('Reset All Settings'), + onPressed: () => _showConfirmDialog(context), + ), + ), ], ); } diff --git a/lib/screens/settings/sections/video_settings.dart b/lib/screens/settings/sections/video_settings.dart index f65ee14a..a2280088 100644 --- a/lib/screens/settings/sections/video_settings.dart +++ b/lib/screens/settings/sections/video_settings.dart @@ -13,7 +13,7 @@ class VideoSettings extends StatelessWidget { Widget build(BuildContext context) { return Observer( builder: (context) => ExpansionTile( - leading: const Icon(Icons.video_settings), + leading: const Icon(Icons.ondemand_video), title: const Text( 'Video', style: TextStyle( @@ -23,27 +23,29 @@ class VideoSettings extends StatelessWidget { ), children: [ SwitchListTile.adaptive( - title: const Text('Show video'), + title: const Text('Video'), value: settingsStore.showVideo, onChanged: (newValue) => settingsStore.showVideo = newValue, ), SwitchListTile.adaptive( isThreeLine: true, - title: const Text('Use custom video overlay'), - subtitle: const Text('Replaces the default video overlay with a mobile-friendly version.'), + title: const Text('Custom Overlay'), + subtitle: const Text('Replaces Twitch\'s default overlay with a mobile-friendly version.'), value: settingsStore.showOverlay, onChanged: settingsStore.showVideo ? (newValue) => settingsStore.showOverlay = newValue : null, ), if (Platform.isIOS) SwitchListTile.adaptive( isThreeLine: true, - title: const Text('Picture-in-picture button (experimental)'), - subtitle: const Text('Adds a button to enter PiP mode on the bottom right of the overlay. May cause freezes/crashes.'), + title: const Text('Picture-in-Picture Button (experimental)'), + subtitle: const Text('Adds a button to enter PiP mode on the bottom right of the overlay. MAY CAUSE freezes/crashes.'), value: settingsStore.pictureInPicture, onChanged: settingsStore.showVideo && settingsStore.showOverlay ? (newValue) => settingsStore.pictureInPicture = newValue : null, ), SwitchListTile.adaptive( - title: const Text('Long-press player to toggle overlay'), + isThreeLine: true, + title: const Text('Long-Press Player to Toggle Overlay'), + subtitle: const Text('Allows switching between Twitch\'s default overlay and the custom overlay.'), value: settingsStore.toggleableOverlay, onChanged: settingsStore.showVideo ? (newValue) => settingsStore.toggleableOverlay = newValue : null, ), diff --git a/lib/screens/settings/settings.dart b/lib/screens/settings/settings.dart index 1f15235a..860fbe22 100644 --- a/lib/screens/settings/settings.dart +++ b/lib/screens/settings/settings.dart @@ -43,6 +43,7 @@ class Settings extends StatelessWidget { bottom: false, child: ListView( children: [ + const SizedBox(height: 10.0), AccountSettings( settingsStore: settingsStore, authStore: context.read(), diff --git a/lib/screens/settings/stores/settings_store.dart b/lib/screens/settings/stores/settings_store.dart index c2ee9ca0..de8197f9 100644 --- a/lib/screens/settings/stores/settings_store.dart +++ b/lib/screens/settings/stores/settings_store.dart @@ -12,90 +12,163 @@ class SettingsStore extends _SettingsStoreBase with _$SettingsStore { } abstract class _SettingsStoreBase with Store { - //General Settings - @JsonKey(defaultValue: ThemeType.system, unknownEnumValue: ThemeType.system) - @observable - var themeType = ThemeType.system; + // * General Settings + static const defaultThemeType = ThemeType.system; - @JsonKey(defaultValue: false) - @observable - var showThumbnailUptime = false; + static const defaultShowThumbnailUptime = false; - // Video Settings - @JsonKey(defaultValue: true) + @JsonKey(defaultValue: defaultThemeType, unknownEnumValue: ThemeType.system) @observable - var showVideo = true; + var themeType = defaultThemeType; - @JsonKey(defaultValue: true) + @JsonKey(defaultValue: defaultShowThumbnailUptime) @observable - var showOverlay = true; + var showThumbnailUptime = defaultShowThumbnailUptime; - @JsonKey(defaultValue: false) - @observable - var toggleableOverlay = false; + // * Video Settings + static const defaultShowVideo = true; - @JsonKey(defaultValue: false) - @observable - var pictureInPicture = false; + static const defaultShowOverlay = true; - // Chat Settings - @JsonKey(defaultValue: true) - @observable - var showBottomBar = true; + static const defaultToggleableOverlay = false; - @JsonKey(defaultValue: false) - @observable - var showDeletedMessages = false; + static const defaultPictureInPicture = false; - @JsonKey(defaultValue: false) + @JsonKey(defaultValue: defaultShowVideo) @observable - var showZeroWidth = false; + var showVideo = defaultShowVideo; - @JsonKey(defaultValue: false) + @JsonKey(defaultValue: defaultShowOverlay) @observable - var showChatMessageDividers = false; + var showOverlay = defaultShowOverlay; - @JsonKey(defaultValue: TimestampType.disabled, unknownEnumValue: TimestampType.disabled) + @JsonKey(defaultValue: defaultToggleableOverlay) @observable - var timestampType = TimestampType.disabled; + var toggleableOverlay = defaultToggleableOverlay; - @JsonKey(defaultValue: true) + @JsonKey(defaultValue: defaultPictureInPicture) @observable - var useReadableColors = true; + var pictureInPicture = defaultPictureInPicture; - @JsonKey(defaultValue: 1.0) - @observable - var messageScale = 1.0; + // * Chat Settings + static const defaultShowBottomBar = true; - @JsonKey(defaultValue: 14.0) - @observable - var fontSize = 14.0; + static const defaultShowDeletedMessages = false; - @JsonKey(defaultValue: 10.0) - @observable - var messageSpacing = 10.0; + static const defaultShowZeroWidth = false; - @JsonKey(defaultValue: 1.0) - @observable - var badgeScale = 1.0; + static const defaultShowChatMessageDividers = false; - @JsonKey(defaultValue: 1.0) - @observable - var emoteScale = 1.0; + static const defaultTimestampType = TimestampType.disabled; - // Other settings - @JsonKey(defaultValue: true) - @observable - var sendCrashLogs = true; + static const defaultUseReadableColors = true; - // Global configs - @JsonKey(defaultValue: false) - @observable - var fullScreen = false; + static const defaultMessageScale = 1.0; - @JsonKey(defaultValue: true) + static const defaultFontSize = 12.0; + + static const defaultMessageSpacing = 10.0; + + static const defaultBadgeScale = 1.0; + + static const defaultEmoteScale = 1.0; + + @JsonKey(defaultValue: defaultShowBottomBar) @observable - var expandInfo = true; + var showBottomBar = defaultShowBottomBar; + + @JsonKey(defaultValue: defaultShowDeletedMessages) + @observable + var showDeletedMessages = defaultShowDeletedMessages; + + @JsonKey(defaultValue: defaultShowZeroWidth) + @observable + var showZeroWidth = defaultShowZeroWidth; + + @JsonKey(defaultValue: defaultShowChatMessageDividers) + @observable + var showChatMessageDividers = defaultShowChatMessageDividers; + + @JsonKey(defaultValue: defaultTimestampType, unknownEnumValue: TimestampType.disabled) + @observable + var timestampType = defaultTimestampType; + + @JsonKey(defaultValue: defaultUseReadableColors) + @observable + var useReadableColors = defaultUseReadableColors; + + @JsonKey(defaultValue: defaultFontSize) + @observable + var fontSize = defaultFontSize; + + @JsonKey(defaultValue: defaultMessageSpacing) + @observable + var messageSpacing = defaultMessageSpacing; + + @JsonKey(defaultValue: defaultMessageScale) + @observable + var messageScale = defaultMessageScale; + + @JsonKey(defaultValue: defaultBadgeScale) + @observable + var badgeScale = defaultBadgeScale; + + @JsonKey(defaultValue: defaultEmoteScale) + @observable + var emoteScale = defaultEmoteScale; + + // * Other settings + static const defaultSendCrashLogs = true; + + @JsonKey(defaultValue: defaultSendCrashLogs) + @observable + var sendCrashLogs = defaultSendCrashLogs; + + // * Global configs + static const defaultFullScreen = false; + + static const defaultExpandInfo = true; + + @JsonKey(defaultValue: defaultFullScreen) + @observable + var fullScreen = defaultFullScreen; + + @JsonKey(defaultValue: defaultExpandInfo) + @observable + var expandInfo = defaultExpandInfo; + + @action + void reset() { + // * General Settings + themeType = defaultThemeType; + showThumbnailUptime = defaultShowThumbnailUptime; + + // * Video Settings + showVideo = defaultShowVideo; + showOverlay = defaultShowOverlay; + toggleableOverlay = defaultToggleableOverlay; + pictureInPicture = defaultPictureInPicture; + + // * Chat Settings + showBottomBar = defaultShowBottomBar; + showDeletedMessages = defaultShowDeletedMessages; + showZeroWidth = defaultShowZeroWidth; + showChatMessageDividers = defaultShowChatMessageDividers; + timestampType = defaultTimestampType; + useReadableColors = defaultUseReadableColors; + messageScale = defaultMessageScale; + fontSize = defaultFontSize; + messageSpacing = defaultMessageSpacing; + badgeScale = defaultBadgeScale; + emoteScale = defaultEmoteScale; + + // * Other settings + sendCrashLogs = defaultSendCrashLogs; + + // * Global configs + fullScreen = defaultFullScreen; + expandInfo = defaultExpandInfo; + } } enum ThemeType { diff --git a/lib/screens/settings/stores/settings_store.g.dart b/lib/screens/settings/stores/settings_store.g.dart index 6eaecbb6..ec3688ef 100644 --- a/lib/screens/settings/stores/settings_store.g.dart +++ b/lib/screens/settings/stores/settings_store.g.dart @@ -26,9 +26,9 @@ SettingsStore _$SettingsStoreFromJson(Map json) => unknownValue: TimestampType.disabled) ?? TimestampType.disabled ..useReadableColors = json['useReadableColors'] as bool? ?? true - ..messageScale = (json['messageScale'] as num?)?.toDouble() ?? 1.0 - ..fontSize = (json['fontSize'] as num?)?.toDouble() ?? 14.0 + ..fontSize = (json['fontSize'] as num?)?.toDouble() ?? 12.0 ..messageSpacing = (json['messageSpacing'] as num?)?.toDouble() ?? 10.0 + ..messageScale = (json['messageScale'] as num?)?.toDouble() ?? 1.0 ..badgeScale = (json['badgeScale'] as num?)?.toDouble() ?? 1.0 ..emoteScale = (json['emoteScale'] as num?)?.toDouble() ?? 1.0 ..sendCrashLogs = json['sendCrashLogs'] as bool? ?? true @@ -49,9 +49,9 @@ Map _$SettingsStoreToJson(SettingsStore instance) => 'showChatMessageDividers': instance.showChatMessageDividers, 'timestampType': _$TimestampTypeEnumMap[instance.timestampType], 'useReadableColors': instance.useReadableColors, - 'messageScale': instance.messageScale, 'fontSize': instance.fontSize, 'messageSpacing': instance.messageSpacing, + 'messageScale': instance.messageScale, 'badgeScale': instance.badgeScale, 'emoteScale': instance.emoteScale, 'sendCrashLogs': instance.sendCrashLogs, @@ -266,21 +266,6 @@ mixin _$SettingsStore on _SettingsStoreBase, Store { }); } - final _$messageScaleAtom = Atom(name: '_SettingsStoreBase.messageScale'); - - @override - double get messageScale { - _$messageScaleAtom.reportRead(); - return super.messageScale; - } - - @override - set messageScale(double value) { - _$messageScaleAtom.reportWrite(value, super.messageScale, () { - super.messageScale = value; - }); - } - final _$fontSizeAtom = Atom(name: '_SettingsStoreBase.fontSize'); @override @@ -311,6 +296,21 @@ mixin _$SettingsStore on _SettingsStoreBase, Store { }); } + final _$messageScaleAtom = Atom(name: '_SettingsStoreBase.messageScale'); + + @override + double get messageScale { + _$messageScaleAtom.reportRead(); + return super.messageScale; + } + + @override + set messageScale(double value) { + _$messageScaleAtom.reportWrite(value, super.messageScale, () { + super.messageScale = value; + }); + } + final _$badgeScaleAtom = Atom(name: '_SettingsStoreBase.badgeScale'); @override @@ -386,6 +386,20 @@ mixin _$SettingsStore on _SettingsStoreBase, Store { }); } + final _$_SettingsStoreBaseActionController = + ActionController(name: '_SettingsStoreBase'); + + @override + void reset() { + final _$actionInfo = _$_SettingsStoreBaseActionController.startAction( + name: '_SettingsStoreBase.reset'); + try { + return super.reset(); + } finally { + _$_SettingsStoreBaseActionController.endAction(_$actionInfo); + } + } + @override String toString() { return ''' @@ -401,9 +415,9 @@ showZeroWidth: ${showZeroWidth}, showChatMessageDividers: ${showChatMessageDividers}, timestampType: ${timestampType}, useReadableColors: ${useReadableColors}, -messageScale: ${messageScale}, fontSize: ${fontSize}, messageSpacing: ${messageSpacing}, +messageScale: ${messageScale}, badgeScale: ${badgeScale}, emoteScale: ${emoteScale}, sendCrashLogs: ${sendCrashLogs}, diff --git a/lib/screens/settings/widgets/profile_card.dart b/lib/screens/settings/widgets/profile_card.dart index 67aeb571..891341ec 100644 --- a/lib/screens/settings/widgets/profile_card.dart +++ b/lib/screens/settings/widgets/profile_card.dart @@ -12,18 +12,28 @@ class ProfileCard extends StatelessWidget { return showDialog( context: context, builder: (context) => SimpleDialog( - title: const Text('Log In With'), children: [ ColoredBox( color: const Color.fromRGBO(145, 70, 255, 0.8), child: SimpleDialogOption( padding: const EdgeInsets.all(24.0), - child: const Text( - 'Twitch Account', - style: TextStyle( - fontSize: 16, - color: Colors.white, - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/icons/TwitchGlitchWhite.png', + height: 30, + ), + const SizedBox(width: 10), + const Text( + 'Connect with Twitch', + style: TextStyle( + fontSize: 16, + color: Colors.white, + fontWeight: FontWeight.w600, + ), + ), + ], ), onPressed: () { authStore.login(); @@ -32,9 +42,16 @@ class ProfileCard extends StatelessWidget { ), ), const SizedBox(height: 20.0), - const Center(child: Text('Or')), + const Center( + child: Text( + 'Or', + style: TextStyle(fontStyle: FontStyle.italic), + ), + ), + const SizedBox(height: 5.0), SimpleDialogOption( child: TextField( + textAlign: TextAlign.center, decoration: const InputDecoration( hintText: 'Token', ), @@ -80,7 +97,7 @@ class ProfileCard extends StatelessWidget { builder: (context) { if (authStore.error != null) { return ListTile( - title: const Text('Failed to connect'), + title: const Text('Failed to Connect'), trailing: OutlinedButton( onPressed: authStore.init, child: const Text('Try Again'), @@ -90,7 +107,6 @@ class ProfileCard extends StatelessWidget { if (authStore.isLoggedIn && authStore.user.details != null) { return ListTile( leading: CircleAvatar( - backgroundColor: const Color(0xFFFFFFFF), foregroundImage: CachedNetworkImageProvider(authStore.user.details!.profileImageUrl), ), title: Text(authStore.user.details!.displayName), @@ -109,7 +125,7 @@ class ProfileCard extends StatelessWidget { size: 40, ), title: const Text('Anonymous User'), - subtitle: const Text('Log in to view your followed streams, send chat messages, and more.'), + subtitle: const Text('Log in to chat, view followed streams, and more.'), trailing: OutlinedButton( onPressed: () => _showLoginDialog(context), child: const Text('Log In'), diff --git a/lib/widgets/section_header.dart b/lib/widgets/section_header.dart index e2f90ec9..8c407653 100644 --- a/lib/widgets/section_header.dart +++ b/lib/widgets/section_header.dart @@ -8,7 +8,7 @@ class SectionHeader extends StatelessWidget { const SectionHeader( this.text, { Key? key, - this.padding = const EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 5.0), + this.padding = const EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 5.0), this.fontSize = 18.0, }) : super(key: key); diff --git a/pubspec.yaml b/pubspec.yaml index aaa20540..419d1e53 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -99,7 +99,8 @@ flutter: # - images/a_dot_ham.jpeg assets: - - assets/icons/logo.png + - assets/icons/logo.svg + - assets/icons/TwitchGlitchWhite.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware.