1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

feat(mobile): Scroll to top when tapping photos while already on photo page (#1784)

* adds scroll to top when tapping photos while already on photo page

* unused import
This commit is contained in:
martyfuhry 2023-02-17 21:46:25 -05:00 committed by GitHub
parent bf6f94f69f
commit 6e9749d6c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 42 deletions

View File

@ -0,0 +1,9 @@
import 'package:flutter/material.dart';
final scrollToTopNotifierProvider = ScrollNotifier();
class ScrollNotifier with ChangeNotifier {
void scrollToTop() {
notifyListeners();
}
}

View File

@ -3,6 +3,7 @@ import 'dart:collection';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart';
import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/models/asset.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
@ -234,6 +235,30 @@ class ImmichAssetGridState extends State<ImmichAssetGrid> {
return true; return true;
} }
@override
void initState() {
super.initState();
scrollToTopNotifierProvider.addListener(_scrollToTop);
}
@override
void dispose() {
scrollToTopNotifierProvider.removeListener(_scrollToTop);
super.dispose();
}
void _scrollToTop() {
// for some reason, this is necessary as well in order
// to correctly reposition the drag thumb scroll bar
_itemScrollController.jumpTo(
index: 0,
);
_itemScrollController.scrollTo(
index: 0,
duration: const Duration(milliseconds: 200),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return WillPopScope( return WillPopScope(

View File

@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
import 'package:immich_mobile/modules/home/providers/multiselect.provider.dart'; import 'package:immich_mobile/modules/home/providers/multiselect.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
@ -16,6 +17,11 @@ class TabControllerPage extends ConsumerWidget {
labelType: NavigationRailLabelType.all, labelType: NavigationRailLabelType.all,
selectedIndex: tabsRouter.activeIndex, selectedIndex: tabsRouter.activeIndex,
onDestinationSelected: (index) { onDestinationSelected: (index) {
// Selected Photos while it is active
if (tabsRouter.activeIndex == 0 && index == 0) {
// Scroll to top
scrollToTopNotifierProvider.scrollToTop();
}
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
tabsRouter.setActiveIndex(index); tabsRouter.setActiveIndex(index);
}, },
@ -60,51 +66,14 @@ class TabControllerPage extends ConsumerWidget {
); );
} }
// ignore: unused_element
bottomNavigationBar(TabsRouter tabsRouter) { bottomNavigationBar(TabsRouter tabsRouter) {
return BottomNavigationBar(
selectedLabelStyle: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
),
unselectedLabelStyle: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
),
currentIndex: tabsRouter.activeIndex,
onTap: (index) {
HapticFeedback.selectionClick();
tabsRouter.setActiveIndex(index);
},
items: [
BottomNavigationBarItem(
label: 'tab_controller_nav_photos'.tr(),
icon: const Icon(Icons.photo_outlined),
activeIcon: const Icon(Icons.photo),
),
BottomNavigationBarItem(
label: 'tab_controller_nav_search'.tr(),
icon: const Icon(Icons.search_rounded),
activeIcon: const Icon(Icons.search),
),
BottomNavigationBarItem(
label: 'tab_controller_nav_sharing'.tr(),
icon: const Icon(Icons.group_outlined),
activeIcon: const Icon(Icons.group),
),
BottomNavigationBarItem(
label: 'tab_controller_nav_library'.tr(),
icon: const Icon(Icons.photo_album_outlined),
activeIcon: const Icon(Icons.photo_album_rounded),
)
],
);
}
experimentalNavigationBar(TabsRouter tabsRouter) {
return NavigationBar( return NavigationBar(
selectedIndex: tabsRouter.activeIndex, selectedIndex: tabsRouter.activeIndex,
onDestinationSelected: (index) { onDestinationSelected: (index) {
if (tabsRouter.activeIndex == 0 && index == 0) {
// Scroll to top
scrollToTopNotifierProvider.scrollToTop();
}
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
tabsRouter.setActiveIndex(index); tabsRouter.setActiveIndex(index);
}, },
@ -179,7 +148,7 @@ class TabControllerPage extends ConsumerWidget {
final Widget body; final Widget body;
if (constraints.maxWidth < medium) { if (constraints.maxWidth < medium) {
// Normal phone width // Normal phone width
bottom = experimentalNavigationBar(tabsRouter); bottom = bottomNavigationBar(tabsRouter);
body = FadeTransition( body = FadeTransition(
opacity: animation, opacity: animation,
child: child, child: child,