Add support for landscape orientation on desktop and tablets.

This commit is contained in:
Shawn 2022-11-05 02:06:51 -06:00
parent 0a8b113cfb
commit c967be4d82
8 changed files with 30 additions and 18 deletions

View File

@ -1,9 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'package:desktop_window/desktop_window.dart'; import 'package:desktop_window/desktop_window.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:wonders/common_libs.dart'; import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/platform_info.dart';
import 'package:wonders/ui/common/utils/page_routes.dart'; import 'package:wonders/ui/common/utils/page_routes.dart';
class AppLogic { class AppLogic {
@ -11,6 +11,17 @@ class AppLogic {
/// The router will use this to prevent redirects while bootstrapping. /// The router will use this to prevent redirects while bootstrapping.
bool isBootstrapComplete = false; bool isBootstrapComplete = false;
bool get isDesktopOrTablet => PlatformInfo.isDesktopOrWeb || deviceSize.shortestSide > 500;
/// Support portrait and landscape on desktop, web and tablets. Stick to portrait for phones.
/// A return value of null indicated both orientations are supported.
Axis? get supportedOrientations => isDesktopOrTablet ? null : Axis.vertical;
Size get deviceSize {
final w = WidgetsBinding.instance.platformDispatcher.views.first;
return w.physicalSize / w.devicePixelRatio;
}
/// Initialize the app and all main actors. /// Initialize the app and all main actors.
/// Loads settings, sets up services etc. /// Loads settings, sets up services etc.
Future<void> bootstrap() async { Future<void> bootstrap() async {
@ -18,16 +29,18 @@ class AppLogic {
FlutterError.onError = _handleFlutterError; FlutterError.onError = _handleFlutterError;
// Set min-sizes for desktop apps // Set min-sizes for desktop apps
await DesktopWindow.setMinWindowSize($styles.sizes.minAppSize); if (PlatformInfo.isDesktop) {
await DesktopWindow.setMinWindowSize($styles.sizes.minAppSize);
}
// Load any bitmaps the views might need // Load any bitmaps the views might need
await AppBitmaps.init(); await AppBitmaps.init();
// Default to only allowing portrait mode // Set the initial supported orientations
setDeviceOrientation(Axis.vertical); setDeviceOrientation(supportedOrientations);
// Set preferred refresh rate to the max possible (the OS may ignore this) // Set preferred refresh rate to the max possible (the OS may ignore this)
if (defaultTargetPlatform == TargetPlatform.android) { if (PlatformInfo.isAndroid) {
await FlutterDisplayMode.setHighRefreshRate(); await FlutterDisplayMode.setHighRefreshRate();
} }

View File

@ -9,6 +9,7 @@ class PlatformInfo {
static const _mobilePlatforms = [TargetPlatform.android, TargetPlatform.iOS]; static const _mobilePlatforms = [TargetPlatform.android, TargetPlatform.iOS];
static bool get isDesktop => _desktopPlatforms.contains(defaultTargetPlatform); static bool get isDesktop => _desktopPlatforms.contains(defaultTargetPlatform);
static bool get isDesktopOrWeb => isDesktop || kIsWeb;
static bool get isMobile => _mobilePlatforms.contains(defaultTargetPlatform); static bool get isMobile => _mobilePlatforms.contains(defaultTargetPlatform);
static double get pixelRatio => WidgetsBinding.instance.window.devicePixelRatio; static double get pixelRatio => WidgetsBinding.instance.window.devicePixelRatio;

View File

@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:wonders/_tools/unsplash_download_service.dart'; import 'package:wonders/_tools/unsplash_download_service.dart';
import 'package:wonders/logic/common/platform_info.dart'; import 'package:wonders/logic/common/platform_info.dart';
@ -27,10 +26,7 @@ class UnsplashPhotoData {
size = 1200; size = 1200;
break; break;
} }
bool isDesktop = defaultTargetPlatform == TargetPlatform.windows || if (PlatformInfo.pixelRatio >= 1.5 || PlatformInfo.isDesktop) {
defaultTargetPlatform == TargetPlatform.macOS ||
defaultTargetPlatform == TargetPlatform.linux;
if (PlatformInfo.pixelRatio >= 1.5 || isDesktop) {
size *= 2; size *= 2;
} }
return 'https://wonderous.info/unsplash/$id-$size.jpg'; return 'https://wonderous.info/unsplash/$id-$size.jpg';

View File

@ -1,5 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:wonders/common_libs.dart'; import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/platform_info.dart';
import 'package:wonders/logic/common/save_load_mixin.dart'; import 'package:wonders/logic/common/save_load_mixin.dart';
class SettingsLogic with ThrottledSaveLoadMixin { class SettingsLogic with ThrottledSaveLoadMixin {
@ -10,7 +10,7 @@ class SettingsLogic with ThrottledSaveLoadMixin {
late final hasDismissedSearchMessage = ValueNotifier<bool>(false)..addListener(scheduleSave); late final hasDismissedSearchMessage = ValueNotifier<bool>(false)..addListener(scheduleSave);
late final currentLocale = ValueNotifier<String?>(null)..addListener(scheduleSave); late final currentLocale = ValueNotifier<String?>(null)..addListener(scheduleSave);
final bool useBlurs = defaultTargetPlatform != TargetPlatform.android; final bool useBlurs = !PlatformInfo.isAndroid;
@override @override
void copyFromJson(Map<String, dynamic> value) { void copyFromJson(Map<String, dynamic> value) {

View File

@ -1,6 +1,6 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:wonders/logic/common/platform_info.dart';
/// Add mouse drag on desktop for easier responsive testing /// Add mouse drag on desktop for easier responsive testing
class AppScrollBehavior extends ScrollBehavior { class AppScrollBehavior extends ScrollBehavior {
@ -15,7 +15,7 @@ class AppScrollBehavior extends ScrollBehavior {
@override @override
Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) { Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) {
return child; return child;
return defaultTargetPlatform == TargetPlatform.android return PlatformInfo.isAndroid
? RawScrollbar(controller: details.controller, child: child) ? RawScrollbar(controller: details.controller, child: child)
: CupertinoScrollbar(controller: details.controller, child: child); : CupertinoScrollbar(controller: details.controller, child: child);
} }

View File

@ -24,7 +24,8 @@ class _FullscreenVideoPageState extends State<FullscreenVideoPage> {
@override @override
void dispose() { void dispose() {
appLogic.setDeviceOrientation(Axis.vertical); // when view closes, restore the supported orientations
appLogic.setDeviceOrientation(appLogic.supportedOrientations);
super.dispose(); super.dispose();
} }

View File

@ -2,6 +2,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:wonders/common_libs.dart'; import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/platform_info.dart';
class AppHaptics { class AppHaptics {
// note: system sounds are pretty buggy on Android: https://github.com/flutter/flutter/issues/57531 // note: system sounds are pretty buggy on Android: https://github.com/flutter/flutter/issues/57531
@ -11,7 +12,7 @@ class AppHaptics {
static void buttonPress() { static void buttonPress() {
// Android/Fuchsia expect haptics on all button presses, iOS does not. // Android/Fuchsia expect haptics on all button presses, iOS does not.
if (defaultTargetPlatform != TargetPlatform.android || defaultTargetPlatform != TargetPlatform.fuchsia) { if (PlatformInfo.isAndroid) {
lightImpact(); lightImpact();
} }
} }

View File

@ -1,8 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:wonders/common_libs.dart'; import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/platform_info.dart';
import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/logic/data/wonder_data.dart';
import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/app_icons.dart';
import 'package:wonders/ui/common/controls/checkbox.dart'; import 'package:wonders/ui/common/controls/checkbox.dart';
@ -142,7 +142,7 @@ class _WallpaperPhotoScreenState extends State<WallpaperPhotoScreen> {
Padding( Padding(
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0, right: 16.0), padding: const EdgeInsets.only(top: 10.0, bottom: 10.0, right: 16.0),
child: CircleIconBtn( child: CircleIconBtn(
icon: defaultTargetPlatform == TargetPlatform.iOS ? AppIcons.share_ios : AppIcons.share_android, icon: PlatformInfo.isIOS ? AppIcons.share_ios : AppIcons.share_android,
bgColor: $styles.colors.offWhite, bgColor: $styles.colors.offWhite,
color: $styles.colors.black, color: $styles.colors.black,
onPressed: () => _handleSharePhoto(context, wonderData.title), onPressed: () => _handleSharePhoto(context, wonderData.title),