diff --git a/client/lib/app.dart b/client/lib/app.dart index 7f8e512c..1b7c263f 100644 --- a/client/lib/app.dart +++ b/client/lib/app.dart @@ -25,14 +25,12 @@ class PhylumApp extends StatefulWidget { StateNotifierProvider.value(value: account), StateNotifierProvider.value(value: account.actionQueue), StateNotifierProvider(create: (context) => DownloadManager(account)), - StateNotifierProvider.value(value: NavHistoryManager()), + StateNotifierProvider(create: (context) => NavHistoryManager()), + ChangeNotifierProvider(create: (context) => ActionQueueStatusNotifier(account.actionQueue)) ], - builder: (context, child) => ChangeNotifierProvider( - create: (context) => ActionQueueStatusNotifier(context), - child: PhylumApp._( - account: context.read(), - observer: context.read().navObserver, - ), + builder: (context, child) => PhylumApp._( + account: account, + observer: context.read().navObserver, ), ); @@ -61,7 +59,7 @@ class _PhylumAppState extends State { pageBuilder: (context, state) => NoTransitionPage( name: state.name, key: ValueKey(state.pathParameters['id']), - child: AppLayout(folderId: state.pathParameters['id']!), + child: AppLayout.create(state.pathParameters['id']!), arguments: state.pathParameters['id'], ), ), diff --git a/client/lib/ui/app/action_queue_status_notifier.dart b/client/lib/ui/app/action_queue_status_notifier.dart index 63570d08..f3f9e8b4 100644 --- a/client/lib/ui/app/action_queue_status_notifier.dart +++ b/client/lib/ui/app/action_queue_status_notifier.dart @@ -22,8 +22,8 @@ class ActionQueueStatusNotifier extends ChangeNotifier { return _failedActions!; } - ActionQueueStatusNotifier(BuildContext context) { - removeListenerCallback = context.read().addListener((state) { + ActionQueueStatusNotifier(PhylumActionQueue queue) { + removeListenerCallback = queue.addListener((state) { if (state.actions != last) { for (final action in state.actions) { if (!_listeners.containsKey(action)) { diff --git a/client/lib/ui/app/app_layout.dart b/client/lib/ui/app/app_layout.dart index f9d73c26..4eb59677 100644 --- a/client/lib/ui/app/app_layout.dart +++ b/client/lib/ui/app/app_layout.dart @@ -4,6 +4,54 @@ import 'package:phylum/ui/app/fab_action.dart'; import 'package:phylum/ui/app/nav_list.dart'; import 'package:phylum/ui/explorer/explorer_view.dart'; import 'package:phylum/ui/explorer/path_view.dart'; +import 'package:provider/provider.dart'; + +enum LayoutType { + collapsed, + expandedSmall, + expandedLarge; + + bool get isExpanded => this == LayoutType.expandedSmall || this == LayoutType.expandedLarge; +} + +class LayoutData extends ChangeNotifier { + LayoutType _type = LayoutType.collapsed; + LayoutType get type => _type; + bool _touchUi = true; + bool get touchUi => _touchUi; + + LayoutData(); + + void _update(TargetPlatform platform, Size size) { + final layout = size.width < 600 + ? LayoutType.collapsed + : size.width <= 1200 + ? LayoutType.expandedSmall + : LayoutType.expandedLarge; + final touchUi = platform == TargetPlatform.android || platform == TargetPlatform.iOS; + bool changed = false; + if (_type != layout) { + _type = layout; + changed = true; + } + if (_touchUi != touchUi) { + _touchUi = touchUi; + changed = true; + } + + if (changed) { + Future.delayed(const Duration(), notifyListeners); + } + } + + @override + bool operator ==(Object other) { + return other is LayoutData && other._type == _type && other._touchUi == _touchUi; + } + + @override + int get hashCode => _type.hashCode ^ _touchUi.hashCode; +} class AppLayout extends StatelessWidget { final String folderId; @@ -12,10 +60,28 @@ class AppLayout extends StatelessWidget { @override Widget build(BuildContext context) { - final width = MediaQuery.of(context).size.width; - return AppActions( - folderId: folderId, - child: width > 800 ? ExpandedAppLayout(folderId: folderId, xLarge: width > 1200) : CollapsedAppLayout(folderId: folderId), + return Builder(builder: (context) { + final layout = context.watch(); + return layout.type.isExpanded ? ExpandedAppLayout(folderId: folderId) : CollapsedAppLayout(folderId: folderId); + }); + } + + static Widget create(String folderId) { + return ChangeNotifierProvider( + create: (context) { + return LayoutData(); + }, + builder: (context, child) { + final platform = Theme.of(context).platform; + final size = MediaQuery.sizeOf(context); + context.read()._update(platform, size); + return child!; + }, + child: AppActions( + folderId: folderId, + child: AppLayout( + folderId: folderId, + )), ); } } @@ -64,12 +130,12 @@ class CollapsedAppLayout extends StatelessWidget { class ExpandedAppLayout extends StatelessWidget { final String folderId; - final bool xLarge; - const ExpandedAppLayout({super.key, required this.folderId, required this.xLarge}); + const ExpandedAppLayout({super.key, required this.folderId}); @override Widget build(BuildContext context) { + final layout = context.watch(); return AppActions( folderId: folderId, child: Scaffold( @@ -84,13 +150,14 @@ class ExpandedAppLayout extends StatelessWidget { body: Row( children: [ SizedBox( - width: xLarge ? 300 : 240, + width: layout.type == LayoutType.expandedLarge ? 300 : 240, child: NavList(showFab: true), ), Expanded( child: Padding( padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), - child: ExplorerView.create(folderId, xLarge ? ExplorerLayout.largeSidebar : ExplorerLayout.smallSidebar), + child: ExplorerView.create( + folderId, layout.type == LayoutType.expandedLarge ? ExplorerLayout.largeSidebar : ExplorerLayout.smallSidebar), ), ), ], diff --git a/client/lib/ui/explorer/path_view.dart b/client/lib/ui/explorer/path_view.dart index 2322cf52..bee881db 100644 --- a/client/lib/ui/explorer/path_view.dart +++ b/client/lib/ui/explorer/path_view.dart @@ -52,7 +52,7 @@ class _PathViewState extends State { sub?.cancel(); sub = context.read().db.parents(id).watch().listen((data) { SystemChrome.setApplicationSwitcherDescription(ApplicationSwitcherDescription( - label: "${data[0].name == "" ? "/" : data[0].name} | Phylum", + label: data.isEmpty ? 'Phylum' : "${data[0].name == "" ? "/" : data[0].name} | Phylum", )); setState(() { ancestors = data.reversed;