diff --git a/mobile/lib/pages/common/tab_controller.page.dart b/mobile/lib/pages/common/tab_controller.page.dart index 3d4b19cba0c56..1ba96500566bf 100644 --- a/mobile/lib/pages/common/tab_controller.page.dart +++ b/mobile/lib/pages/common/tab_controller.page.dart @@ -61,53 +61,6 @@ class TabControllerPage extends HookConsumerWidget { ref.read(tabProvider.notifier).state = TabEnum.values[index]; } - navigationRail(TabsRouter tabsRouter) { - return NavigationRail( - labelType: NavigationRailLabelType.all, - selectedIndex: tabsRouter.activeIndex, - onDestinationSelected: (index) => - onNavigationSelected(tabsRouter, index), - selectedIconTheme: IconThemeData( - color: context.primaryColor, - ), - selectedLabelTextStyle: TextStyle( - color: context.primaryColor, - ), - useIndicator: false, - destinations: [ - NavigationRailDestination( - padding: EdgeInsets.only( - top: MediaQuery.of(context).padding.top + 4, - left: 4, - right: 4, - bottom: 4, - ), - icon: const Icon(Icons.photo_library_outlined), - selectedIcon: const Icon(Icons.photo_library), - label: const Text('tab_controller_nav_photos').tr(), - ), - NavigationRailDestination( - padding: const EdgeInsets.all(4), - icon: const Icon(Icons.search_rounded), - selectedIcon: const Icon(Icons.search), - label: const Text('tab_controller_nav_search').tr(), - ), - NavigationRailDestination( - padding: const EdgeInsets.all(4), - icon: const Icon(Icons.photo_album_outlined), - selectedIcon: const Icon(Icons.photo_album), - label: const Text('albums').tr(), - ), - NavigationRailDestination( - padding: const EdgeInsets.all(4), - icon: const Icon(Icons.space_dashboard_outlined), - selectedIcon: const Icon(Icons.space_dashboard_rounded), - label: const Text('library').tr(), - ), - ], - ); - } - bottomNavigationBar(TabsRouter tabsRouter) { return NavigationBar( selectedIndex: tabsRouter.activeIndex, @@ -186,33 +139,13 @@ class TabControllerPage extends HookConsumerWidget { canPop: tabsRouter.activeIndex == 0, onPopInvokedWithResult: (didPop, _) => !didPop ? tabsRouter.setActiveIndex(0) : null, - child: LayoutBuilder( - builder: (context, constraints) { - const medium = 600; - final Widget? bottom; - final Widget body; - if (constraints.maxWidth < medium) { - // Normal phone width - bottom = bottomNavigationBar(tabsRouter); - body = child; - } else { - // Medium tablet width - bottom = null; - body = Row( - children: [ - navigationRail(tabsRouter), - Expanded(child: child), - ], - ); - } - return Scaffold( - body: HeroControllerScope( - controller: HeroController(), - child: body, - ), - bottomNavigationBar: multiselectEnabled ? null : bottom, - ); - }, + child: Scaffold( + body: HeroControllerScope( + controller: HeroController(), + child: child, + ), + bottomNavigationBar: + multiselectEnabled ? null : bottomNavigationBar(tabsRouter), ), ); }, diff --git a/mobile/lib/pages/library/library.page.dart b/mobile/lib/pages/library/library.page.dart index 3915ac3991460..48d2c685ba1e7 100644 --- a/mobile/lib/pages/library/library.page.dart +++ b/mobile/lib/pages/library/library.page.dart @@ -59,7 +59,7 @@ class LibraryPage extends ConsumerWidget { icon: Icons.link_outlined, label: 'shared_links'.tr(), ), - const SizedBox(width: 8), + SizedBox(width: trashEnabled ? 8 : 0), trashEnabled ? ActionButton( onPressed: () => context.pushRoute(const TrashRoute()), @@ -197,58 +197,65 @@ class PeopleCollectionCard extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final people = ref.watch(getAllPeopleProvider); - final size = MediaQuery.of(context).size.width * 0.5 - 20; - return GestureDetector( - onTap: () => context.pushRoute(const PeopleCollectionRoute()), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: size, - width: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - gradient: LinearGradient( - colors: [ - context.colorScheme.primary.withAlpha(30), - context.colorScheme.primary.withAlpha(25), - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - ), - child: people.widgetWhen( - onData: (people) { - return GridView.count( - crossAxisCount: 2, - padding: const EdgeInsets.all(12), - crossAxisSpacing: 8, - mainAxisSpacing: 8, - physics: const NeverScrollableScrollPhysics(), - children: people.take(4).map((person) { - return CircleAvatar( - backgroundImage: NetworkImage( - getFaceThumbnailUrl(person.id), - headers: ApiService.getRequestHeaders(), - ), + return LayoutBuilder( + builder: (context, constraints) { + final isTablet = constraints.maxWidth > 600; + final widthFactor = isTablet ? 0.25 : 0.5; + final size = MediaQuery.of(context).size.width * widthFactor - 20.0; + + return GestureDetector( + onTap: () => context.pushRoute(const PeopleCollectionRoute()), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: size, + width: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + gradient: LinearGradient( + colors: [ + context.colorScheme.primary.withAlpha(30), + context.colorScheme.primary.withAlpha(25), + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: people.widgetWhen( + onData: (people) { + return GridView.count( + crossAxisCount: 2, + padding: const EdgeInsets.all(12), + crossAxisSpacing: 8, + mainAxisSpacing: 8, + physics: const NeverScrollableScrollPhysics(), + children: people.take(4).map((person) { + return CircleAvatar( + backgroundImage: NetworkImage( + getFaceThumbnailUrl(person.id), + headers: ApiService.getRequestHeaders(), + ), + ); + }).toList(), ); - }).toList(), - ); - }, - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - 'people'.tr(), - style: context.textTheme.titleSmall?.copyWith( - color: context.colorScheme.onSurface, - fontWeight: FontWeight.w500, + }, + ), ), - ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'people'.tr(), + style: context.textTheme.titleSmall?.copyWith( + color: context.colorScheme.onSurface, + fontWeight: FontWeight.w500, + ), + ), + ), + ], ), - ], - ), + ); + }, ); } } @@ -260,55 +267,61 @@ class LocalAlbumsCollectionCard extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final albums = ref.watch(localAlbumsProvider); - final size = MediaQuery.of(context).size.width * 0.5 - 20; + return LayoutBuilder( + builder: (context, constraints) { + final isTablet = constraints.maxWidth > 600; + final widthFactor = isTablet ? 0.25 : 0.5; + final size = MediaQuery.of(context).size.width * widthFactor - 20.0; - return GestureDetector( - onTap: () => context.pushRoute( - const LocalAlbumsRoute(), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: size, - width: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - gradient: LinearGradient( - colors: [ - context.colorScheme.primary.withAlpha(30), - context.colorScheme.primary.withAlpha(25), - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - ), - child: GridView.count( - crossAxisCount: 2, - padding: const EdgeInsets.all(12), - crossAxisSpacing: 8, - mainAxisSpacing: 8, - physics: const NeverScrollableScrollPhysics(), - children: albums.take(4).map((album) { - return AlbumThumbnailCard( - album: album, - showTitle: false, - ); - }).toList(), - ), + return GestureDetector( + onTap: () => context.pushRoute( + const LocalAlbumsRoute(), ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - 'on_this_device'.tr(), - style: context.textTheme.titleSmall?.copyWith( - color: context.colorScheme.onSurface, - fontWeight: FontWeight.w500, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: size, + width: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + gradient: LinearGradient( + colors: [ + context.colorScheme.primary.withAlpha(30), + context.colorScheme.primary.withAlpha(25), + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: GridView.count( + crossAxisCount: 2, + padding: const EdgeInsets.all(12), + crossAxisSpacing: 8, + mainAxisSpacing: 8, + physics: const NeverScrollableScrollPhysics(), + children: albums.take(4).map((album) { + return AlbumThumbnailCard( + album: album, + showTitle: false, + ); + }).toList(), + ), ), - ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'on_this_device'.tr(), + style: context.textTheme.titleSmall?.copyWith( + color: context.colorScheme.onSurface, + fontWeight: FontWeight.w500, + ), + ), + ), + ], ), - ], - ), + ); + }, ); } } @@ -317,44 +330,51 @@ class PlacesCollectionCard extends StatelessWidget { const PlacesCollectionCard({super.key}); @override Widget build(BuildContext context) { - final size = MediaQuery.of(context).size.width * 0.5 - 20; - return GestureDetector( - onTap: () => context.pushRoute(const PlacesCollectionRoute()), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: size, - width: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: context.colorScheme.secondaryContainer.withAlpha(100), - ), - child: IgnorePointer( - child: MapThumbnail( - zoom: 8, - centre: const LatLng( - 21.44950, - -157.91959, + return LayoutBuilder( + builder: (context, constraints) { + final isTablet = constraints.maxWidth > 600; + final widthFactor = isTablet ? 0.25 : 0.5; + final size = MediaQuery.of(context).size.width * widthFactor - 20.0; + + return GestureDetector( + onTap: () => context.pushRoute(const PlacesCollectionRoute()), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: size, + width: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: context.colorScheme.secondaryContainer.withAlpha(100), + ), + child: IgnorePointer( + child: MapThumbnail( + zoom: 8, + centre: const LatLng( + 21.44950, + -157.91959, + ), + showAttribution: false, + themeMode: + context.isDarkTheme ? ThemeMode.dark : ThemeMode.light, + ), ), - showAttribution: false, - themeMode: - context.isDarkTheme ? ThemeMode.dark : ThemeMode.light, ), - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - 'places'.tr(), - style: context.textTheme.titleSmall?.copyWith( - color: context.colorScheme.onSurface, - fontWeight: FontWeight.w500, + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'places'.tr(), + style: context.textTheme.titleSmall?.copyWith( + color: context.colorScheme.onSurface, + fontWeight: FontWeight.w500, + ), + ), ), - ), + ], ), - ], - ), + ); + }, ); } } diff --git a/mobile/lib/pages/library/people/people_collection.page.dart b/mobile/lib/pages/library/people/people_collection.page.dart index b3f688280810c..ad78e27a41a77 100644 --- a/mobile/lib/pages/library/people/people_collection.page.dart +++ b/mobile/lib/pages/library/people/people_collection.page.dart @@ -29,76 +29,86 @@ class PeopleCollectionPage extends HookConsumerWidget { ); } - return Scaffold( - appBar: AppBar( - title: Text('people'.tr()), - ), - body: people.when( - data: (people) { - return GridView.builder( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - childAspectRatio: 0.85, - ), - padding: const EdgeInsets.symmetric(vertical: 32), - itemCount: people.length, - itemBuilder: (context, index) { - final person = people[index]; + return LayoutBuilder( + builder: (context, constraints) { + final isTablet = constraints.maxWidth > 600; + final isPortrait = + MediaQuery.of(context).orientation == Orientation.portrait; - return Column( - children: [ - GestureDetector( - onTap: () { - context.pushRoute( - PersonResultRoute( - personId: person.id, - personName: person.name, - ), - ); - }, - child: Material( - shape: const CircleBorder(side: BorderSide.none), - elevation: 3, - child: CircleAvatar( - maxRadius: 96 / 2, - backgroundImage: NetworkImage( - getFaceThumbnailUrl(person.id), - headers: headers, - ), - ), - ), - ), - const SizedBox(height: 12), - GestureDetector( - onTap: () => showNameEditModel(person.id, person.name), - child: person.name.isEmpty - ? Text( - 'add_a_name'.tr(), - style: context.textTheme.titleSmall?.copyWith( - fontWeight: FontWeight.w500, - color: context.colorScheme.primary, + return Scaffold( + appBar: AppBar( + title: Text('people'.tr()), + ), + body: people.when( + data: (people) { + return GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: isTablet ? 6 : 3, + childAspectRatio: 0.85, + mainAxisSpacing: isPortrait && isTablet ? 36 : 0, + ), + padding: const EdgeInsets.symmetric(vertical: 32), + itemCount: people.length, + itemBuilder: (context, index) { + final person = people[index]; + + return Column( + children: [ + GestureDetector( + onTap: () { + context.pushRoute( + PersonResultRoute( + personId: person.id, + personName: person.name, ), - ) - : Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16.0), - child: Text( - person.name, - overflow: TextOverflow.ellipsis, - style: context.textTheme.titleSmall?.copyWith( - fontWeight: FontWeight.w500, - ), + ); + }, + child: Material( + shape: const CircleBorder(side: BorderSide.none), + elevation: 3, + child: CircleAvatar( + maxRadius: isTablet ? 120 / 2 : 96 / 2, + backgroundImage: NetworkImage( + getFaceThumbnailUrl(person.id), + headers: headers, ), ), - ), - ], + ), + ), + const SizedBox(height: 12), + GestureDetector( + onTap: () => showNameEditModel(person.id, person.name), + child: person.name.isEmpty + ? Text( + 'add_a_name'.tr(), + style: context.textTheme.titleSmall?.copyWith( + fontWeight: FontWeight.w500, + color: context.colorScheme.primary, + ), + ) + : Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + ), + child: Text( + person.name, + overflow: TextOverflow.ellipsis, + style: context.textTheme.titleSmall?.copyWith( + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ], + ); + }, ); }, - ); - }, - error: (error, stack) => const Text("error"), - loading: () => const CircularProgressIndicator(), - ), + error: (error, stack) => const Text("error"), + loading: () => const CircularProgressIndicator(), + ), + ); + }, ); } }