diff --git a/lib/screens/channel/channel.dart b/lib/screens/channel/channel.dart index 63f5c94d..bda8b7b7 100644 --- a/lib/screens/channel/channel.dart +++ b/lib/screens/channel/channel.dart @@ -10,12 +10,12 @@ import 'package:frosty/screens/channel/video/stream_info_bar.dart'; import 'package:frosty/screens/channel/video/video.dart'; import 'package:frosty/screens/channel/video/video_overlay.dart'; import 'package:frosty/screens/channel/video/video_store.dart'; +import 'package:frosty/screens/settings/stores/settings_store.dart'; import 'package:frosty/theme.dart'; import 'package:frosty/utils/context_extensions.dart'; import 'package:frosty/widgets/blurred_container.dart'; import 'package:frosty/widgets/draggable_divider.dart'; import 'package:frosty/widgets/frosty_notification.dart'; -import 'package:native_device_orientation/native_device_orientation.dart'; import 'package:provider/provider.dart'; import 'package:simple_pip_mode/actions/pip_actions_layout.dart'; import 'package:simple_pip_mode/pip_widget.dart'; @@ -536,37 +536,17 @@ class _VideoChatState extends State ), ], ) - : NativeDeviceOrientationReader( - builder: (context) { - final orientation = - NativeDeviceOrientationReader.orientation( - context, - ); - - // Determine which edges to fill based on orientation - // Auto mode fills the physical bottom (opposite of notch): - // landscapeLeft = notch on left -> fill right - // landscapeRight = notch on right -> fill left - final bool fillLeft; - final bool fillRight; - - if (settingsStore.landscapeFillAllEdges) { - fillLeft = true; - fillRight = true; - } else { - fillLeft = - orientation == - NativeDeviceOrientation.landscapeRight; - fillRight = - orientation == - NativeDeviceOrientation.landscapeLeft; - } - - return SafeArea( - bottom: false, - left: !fillLeft, - right: !fillRight, - child: LayoutBuilder( + : SafeArea( + bottom: false, + left: settingsStore.landscapeCutout != + LandscapeCutoutType.left && + settingsStore.landscapeCutout != + LandscapeCutoutType.both, + right: settingsStore.landscapeCutout != + LandscapeCutoutType.right && + settingsStore.landscapeCutout != + LandscapeCutoutType.both, + child: LayoutBuilder( builder: (context, constraints) { final availableWidth = constraints.maxWidth; @@ -667,9 +647,7 @@ class _VideoChatState extends State ); }, ), - ); - }, - ) + ) : SafeArea(child: chat), ); } diff --git a/lib/screens/settings/chat_settings.dart b/lib/screens/settings/chat_settings.dart index 604a8160..9bc24f19 100644 --- a/lib/screens/settings/chat_settings.dart +++ b/lib/screens/settings/chat_settings.dart @@ -232,14 +232,17 @@ class _ChatSettingsState extends State { onChanged: (newValue) => settingsStore.landscapeForceVerticalChat = newValue, ), - SettingsListSwitch( - title: 'Fill all edges', - subtitle: const Text( - 'Fills both edges instead of just the bottom edge.', - ), - value: settingsStore.landscapeFillAllEdges, - onChanged: (newValue) => - settingsStore.landscapeFillAllEdges = newValue, + SettingsListSelect( + title: 'Fill notch side', + subtitle: + 'Overrides and fills the available space in devices with a display notch.', + selectedOption: + landscapeCutoutNames[settingsStore.landscapeCutout.index], + options: landscapeCutoutNames, + onChanged: (newValue) => settingsStore.landscapeCutout = + LandscapeCutoutType.values[landscapeCutoutNames.indexOf( + newValue, + )], ), SettingsListSlider( title: 'Chat overlay opacity', diff --git a/lib/screens/settings/stores/settings_store.dart b/lib/screens/settings/stores/settings_store.dart index 3a04ab3a..d28006bd 100644 --- a/lib/screens/settings/stores/settings_store.dart +++ b/lib/screens/settings/stores/settings_store.dart @@ -135,7 +135,7 @@ abstract class _SettingsStoreBase with Store { // Landscape mode defaults static const defaultLandscapeChatLeftSide = false; static const defaultLandscapeForceVerticalChat = false; - static const defaultLandscapeFillAllEdges = false; + static const defaultLandscapeCutout = LandscapeCutoutType.none; static const defaultChatWidth = 0.2; static const defaultFullScreenChatOverlayOpacity = 0.5; @@ -231,9 +231,9 @@ abstract class _SettingsStoreBase with Store { @observable var landscapeForceVerticalChat = defaultLandscapeForceVerticalChat; - @JsonKey(defaultValue: defaultLandscapeFillAllEdges) + @JsonKey(defaultValue: defaultLandscapeCutout) @observable - var landscapeFillAllEdges = defaultLandscapeFillAllEdges; + var landscapeCutout = defaultLandscapeCutout; @JsonKey(defaultValue: defaultChatWidth) @observable @@ -321,7 +321,7 @@ abstract class _SettingsStoreBase with Store { landscapeChatLeftSide = defaultLandscapeChatLeftSide; landscapeForceVerticalChat = defaultLandscapeForceVerticalChat; - landscapeFillAllEdges = defaultLandscapeFillAllEdges; + landscapeCutout = defaultLandscapeCutout; chatWidth = defaultChatWidth; fullScreenChatOverlayOpacity = defaultFullScreenChatOverlayOpacity; @@ -398,3 +398,7 @@ const timestampNames = ['Disabled', '12-hour', '24-hour']; enum TimestampType { disabled, twelve, twentyFour } +const landscapeCutoutNames = ['None', 'Left', 'Right', 'Both']; + +enum LandscapeCutoutType { none, left, right, both } + diff --git a/lib/screens/settings/stores/settings_store.g.dart b/lib/screens/settings/stores/settings_store.g.dart index 5561cfc1..bcf06d8a 100644 --- a/lib/screens/settings/stores/settings_store.g.dart +++ b/lib/screens/settings/stores/settings_store.g.dart @@ -49,7 +49,12 @@ SettingsStore _$SettingsStoreFromJson( ..landscapeChatLeftSide = json['landscapeChatLeftSide'] as bool? ?? false ..landscapeForceVerticalChat = json['landscapeForceVerticalChat'] as bool? ?? false - ..landscapeFillAllEdges = json['landscapeFillAllEdges'] as bool? ?? false + ..landscapeCutout = + $enumDecodeNullable( + _$LandscapeCutoutTypeEnumMap, + json['landscapeCutout'], + ) ?? + LandscapeCutoutType.none ..chatWidth = (json['chatWidth'] as num?)?.toDouble() ?? 0.2 ..fullScreenChatOverlayOpacity = (json['fullScreenChatOverlayOpacity'] as num?)?.toDouble() ?? 0.5 @@ -84,55 +89,56 @@ SettingsStore _$SettingsStoreFromJson( .toList() ?? []; -Map _$SettingsStoreToJson(SettingsStore instance) => - { - 'themeType': _$ThemeTypeEnumMap[instance.themeType]!, - 'accentColor': instance.accentColor, - 'showThumbnails': instance.showThumbnails, - 'largeStreamCard': instance.largeStreamCard, - 'launchUrlExternal': instance.launchUrlExternal, - 'showVideo': instance.showVideo, - 'defaultToHighestQuality': instance.defaultToHighestQuality, - 'useTextureRendering': instance.useTextureRendering, - 'showOverlay': instance.showOverlay, - 'toggleableOverlay': instance.toggleableOverlay, - 'showLatency': instance.showLatency, - 'badgeScale': instance.badgeScale, - 'emoteScale': instance.emoteScale, - 'messageScale': instance.messageScale, - 'messageSpacing': instance.messageSpacing, - 'fontSize': instance.fontSize, - 'showDeletedMessages': instance.showDeletedMessages, - 'showChatMessageDividers': instance.showChatMessageDividers, - 'timestampType': _$TimestampTypeEnumMap[instance.timestampType]!, - 'autoSyncChatDelay': instance.autoSyncChatDelay, - 'chatDelay': instance.chatDelay, - 'highlightFirstTimeChatter': instance.highlightFirstTimeChatter, - 'showUserNotices': instance.showUserNotices, - 'emoteMenuButtonOnLeft': instance.emoteMenuButtonOnLeft, - 'landscapeChatLeftSide': instance.landscapeChatLeftSide, - 'landscapeForceVerticalChat': instance.landscapeForceVerticalChat, - 'landscapeFillAllEdges': instance.landscapeFillAllEdges, - 'chatWidth': instance.chatWidth, - 'fullScreenChatOverlayOpacity': instance.fullScreenChatOverlayOpacity, - 'autocomplete': instance.autocomplete, - 'showTwitchEmotes': instance.showTwitchEmotes, - 'showTwitchBadges': instance.showTwitchBadges, - 'show7TVEmotes': instance.show7TVEmotes, - 'showBTTVEmotes': instance.showBTTVEmotes, - 'showBTTVBadges': instance.showBTTVBadges, - 'showFFZEmotes': instance.showFFZEmotes, - 'showFFZBadges': instance.showFFZBadges, - 'showRecentMessages': instance.showRecentMessages, - 'persistChatTabs': instance.persistChatTabs, - 'secondaryTabs': instance.secondaryTabs, - 'mutedWords': instance.mutedWords, - 'matchWholeWord': instance.matchWholeWord, - 'shareCrashLogsAndAnalytics': instance.shareCrashLogsAndAnalytics, - 'fullScreen': instance.fullScreen, - 'fullScreenChatOverlay': instance.fullScreenChatOverlay, - 'pinnedChannelIds': instance.pinnedChannelIds, - }; +Map _$SettingsStoreToJson( + SettingsStore instance, +) => { + 'themeType': _$ThemeTypeEnumMap[instance.themeType]!, + 'accentColor': instance.accentColor, + 'showThumbnails': instance.showThumbnails, + 'largeStreamCard': instance.largeStreamCard, + 'launchUrlExternal': instance.launchUrlExternal, + 'showVideo': instance.showVideo, + 'defaultToHighestQuality': instance.defaultToHighestQuality, + 'useTextureRendering': instance.useTextureRendering, + 'showOverlay': instance.showOverlay, + 'toggleableOverlay': instance.toggleableOverlay, + 'showLatency': instance.showLatency, + 'badgeScale': instance.badgeScale, + 'emoteScale': instance.emoteScale, + 'messageScale': instance.messageScale, + 'messageSpacing': instance.messageSpacing, + 'fontSize': instance.fontSize, + 'showDeletedMessages': instance.showDeletedMessages, + 'showChatMessageDividers': instance.showChatMessageDividers, + 'timestampType': _$TimestampTypeEnumMap[instance.timestampType]!, + 'autoSyncChatDelay': instance.autoSyncChatDelay, + 'chatDelay': instance.chatDelay, + 'highlightFirstTimeChatter': instance.highlightFirstTimeChatter, + 'showUserNotices': instance.showUserNotices, + 'emoteMenuButtonOnLeft': instance.emoteMenuButtonOnLeft, + 'landscapeChatLeftSide': instance.landscapeChatLeftSide, + 'landscapeForceVerticalChat': instance.landscapeForceVerticalChat, + 'landscapeCutout': _$LandscapeCutoutTypeEnumMap[instance.landscapeCutout]!, + 'chatWidth': instance.chatWidth, + 'fullScreenChatOverlayOpacity': instance.fullScreenChatOverlayOpacity, + 'autocomplete': instance.autocomplete, + 'showTwitchEmotes': instance.showTwitchEmotes, + 'showTwitchBadges': instance.showTwitchBadges, + 'show7TVEmotes': instance.show7TVEmotes, + 'showBTTVEmotes': instance.showBTTVEmotes, + 'showBTTVBadges': instance.showBTTVBadges, + 'showFFZEmotes': instance.showFFZEmotes, + 'showFFZBadges': instance.showFFZBadges, + 'showRecentMessages': instance.showRecentMessages, + 'persistChatTabs': instance.persistChatTabs, + 'secondaryTabs': instance.secondaryTabs, + 'mutedWords': instance.mutedWords, + 'matchWholeWord': instance.matchWholeWord, + 'shareCrashLogsAndAnalytics': instance.shareCrashLogsAndAnalytics, + 'fullScreen': instance.fullScreen, + 'fullScreenChatOverlay': instance.fullScreenChatOverlay, + 'pinnedChannelIds': instance.pinnedChannelIds, +}; const _$ThemeTypeEnumMap = { ThemeType.system: 'system', @@ -146,6 +152,13 @@ const _$TimestampTypeEnumMap = { TimestampType.twentyFour: 'twentyFour', }; +const _$LandscapeCutoutTypeEnumMap = { + LandscapeCutoutType.none: 'none', + LandscapeCutoutType.left: 'left', + LandscapeCutoutType.right: 'right', + LandscapeCutoutType.both: 'both', +}; + // ************************************************************************** // StoreGenerator // ************************************************************************** @@ -645,26 +658,22 @@ mixin _$SettingsStore on _SettingsStoreBase, Store { ); } - late final _$landscapeFillAllEdgesAtom = Atom( - name: '_SettingsStoreBase.landscapeFillAllEdges', + late final _$landscapeCutoutAtom = Atom( + name: '_SettingsStoreBase.landscapeCutout', context: context, ); @override - bool get landscapeFillAllEdges { - _$landscapeFillAllEdgesAtom.reportRead(); - return super.landscapeFillAllEdges; + LandscapeCutoutType get landscapeCutout { + _$landscapeCutoutAtom.reportRead(); + return super.landscapeCutout; } @override - set landscapeFillAllEdges(bool value) { - _$landscapeFillAllEdgesAtom.reportWrite( - value, - super.landscapeFillAllEdges, - () { - super.landscapeFillAllEdges = value; - }, - ); + set landscapeCutout(LandscapeCutoutType value) { + _$landscapeCutoutAtom.reportWrite(value, super.landscapeCutout, () { + super.landscapeCutout = value; + }); } late final _$chatWidthAtom = Atom( @@ -1127,7 +1136,7 @@ showUserNotices: ${showUserNotices}, emoteMenuButtonOnLeft: ${emoteMenuButtonOnLeft}, landscapeChatLeftSide: ${landscapeChatLeftSide}, landscapeForceVerticalChat: ${landscapeForceVerticalChat}, -landscapeFillAllEdges: ${landscapeFillAllEdges}, +landscapeCutout: ${landscapeCutout}, chatWidth: ${chatWidth}, fullScreenChatOverlayOpacity: ${fullScreenChatOverlayOpacity}, autocomplete: ${autocomplete},