feat(mobile): haptic feedback setting (#8723)

* feat(mobile): haptic feedback testing

* linting
This commit is contained in:
Alex 2024-04-15 07:50:47 +02:00 committed by GitHub
parent 85df3f1e99
commit 3c7f70ec30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 136 additions and 29 deletions

View File

@ -511,5 +511,7 @@
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89", "version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89",
"viewer_remove_from_stack": "Remove from Stack", "viewer_remove_from_stack": "Remove from Stack",
"viewer_stack_use_as_main_asset": "Use as Main Asset", "viewer_stack_use_as_main_asset": "Use as Main Asset",
"viewer_unstack": "Un-Stack" "viewer_unstack": "Un-Stack",
} "haptic_feedback_title": "Haptic Feedback",
"haptic_feedback_switch": "Enable haptic feedback"
}

View File

@ -20,6 +20,7 @@ import 'package:immich_mobile/modules/asset_viewer/ui/gallery_app_bar.dart';
import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart'; import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart'; import 'package:immich_mobile/shared/ui/immich_image.dart';
import 'package:immich_mobile/shared/ui/immich_thumbnail.dart'; import 'package:immich_mobile/shared/ui/immich_thumbnail.dart';
import 'package:immich_mobile/shared/ui/photo_view/photo_view_gallery.dart'; import 'package:immich_mobile/shared/ui/photo_view/photo_view_gallery.dart';
@ -303,7 +304,9 @@ class GalleryViewerPage extends HookConsumerWidget {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
onPageChanged: (value) async { onPageChanged: (value) async {
final next = currentIndex.value < value ? value + 1 : value - 1; final next = currentIndex.value < value ? value + 1 : value - 1;
HapticFeedback.selectionClick();
ref.read(hapticFeedbackProvider.notifier).selectionClick();
currentIndex.value = value; currentIndex.value = value;
stackIndex.value = -1; stackIndex.value = -1;
isPlayingVideo.value = false; isPlayingVideo.value = false;

View File

@ -1,13 +1,13 @@
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.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:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/models/available_album.model.dart'; import 'package:immich_mobile/modules/backup/models/available_album.model.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/shared/ui/immich_toast.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart';
class AlbumInfoCard extends HookConsumerWidget { class AlbumInfoCard extends HookConsumerWidget {
@ -21,6 +21,7 @@ class AlbumInfoCard extends HookConsumerWidget {
ref.watch(backupProvider).selectedBackupAlbums.contains(album); ref.watch(backupProvider).selectedBackupAlbums.contains(album);
final bool isExcluded = final bool isExcluded =
ref.watch(backupProvider).excludedBackupAlbums.contains(album); ref.watch(backupProvider).excludedBackupAlbums.contains(album);
final isDarkTheme = context.isDarkTheme; final isDarkTheme = context.isDarkTheme;
ColorFilter selectedFilter = ColorFilter.mode( ColorFilter selectedFilter = ColorFilter.mode(
@ -78,7 +79,7 @@ class AlbumInfoCard extends HookConsumerWidget {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
HapticFeedback.selectionClick(); ref.read(hapticFeedbackProvider.notifier).selectionClick();
if (isSelected) { if (isSelected) {
ref.read(backupProvider.notifier).removeAlbumForBackup(album); ref.read(backupProvider.notifier).removeAlbumForBackup(album);
@ -87,7 +88,7 @@ class AlbumInfoCard extends HookConsumerWidget {
} }
}, },
onDoubleTap: () { onDoubleTap: () {
HapticFeedback.selectionClick(); ref.read(hapticFeedbackProvider.notifier).selectionClick();
if (isExcluded) { if (isExcluded) {
// Remove from exclude album list // Remove from exclude album list

View File

@ -1,6 +1,5 @@
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
@ -8,6 +7,7 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/models/available_album.model.dart'; import 'package:immich_mobile/modules/backup/models/available_album.model.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/shared/ui/immich_toast.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart';
class AlbumInfoListTile extends HookConsumerWidget { class AlbumInfoListTile extends HookConsumerWidget {
@ -68,7 +68,7 @@ class AlbumInfoListTile extends HookConsumerWidget {
return GestureDetector( return GestureDetector(
onDoubleTap: () { onDoubleTap: () {
HapticFeedback.selectionClick(); ref.watch(hapticFeedbackProvider.notifier).selectionClick();
if (isExcluded) { if (isExcluded) {
// Remove from exclude album list // Remove from exclude album list
@ -93,7 +93,7 @@ class AlbumInfoListTile extends HookConsumerWidget {
tileColor: buildTileColor(), tileColor: buildTileColor(),
contentPadding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), contentPadding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
onTap: () { onTap: () {
HapticFeedback.selectionClick(); ref.read(hapticFeedbackProvider.notifier).selectionClick();
if (isSelected) { if (isSelected) {
ref.read(backupProvider.notifier).removeAlbumForBackup(album); ref.read(backupProvider.notifier).removeAlbumForBackup(album);
} else { } else {

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structure.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structure.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
class GroupDividerTitle extends HookConsumerWidget { class GroupDividerTitle extends HookConsumerWidget {
const GroupDividerTitle({ const GroupDividerTitle({
@ -38,7 +38,7 @@ class GroupDividerTitle extends HookConsumerWidget {
); );
void handleTitleIconClick() { void handleTitleIconClick() {
HapticFeedback.heavyImpact(); ref.read(hapticFeedbackProvider.notifier).heavyImpact();
if (selected) { if (selected) {
onDeselect(); onDeselect();
} else { } else {

View File

@ -6,7 +6,7 @@ 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:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/collection_extensions.dart'; import 'package:immich_mobile/extensions/collection_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart'; import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
@ -15,6 +15,7 @@ import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_placeholder.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_placeholder.dart';
import 'package:immich_mobile/modules/home/ui/control_bottom_app_bar.dart'; import 'package:immich_mobile/modules/home/ui/control_bottom_app_bar.dart';
import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'asset_grid_data_structure.dart'; import 'asset_grid_data_structure.dart';
@ -27,7 +28,7 @@ typedef ImmichAssetGridSelectionListener = void Function(
Set<Asset>, Set<Asset>,
); );
class ImmichAssetGridView extends StatefulWidget { class ImmichAssetGridView extends ConsumerStatefulWidget {
final RenderList renderList; final RenderList renderList;
final int assetsPerRow; final int assetsPerRow;
final double margin; final double margin;
@ -69,12 +70,12 @@ class ImmichAssetGridView extends StatefulWidget {
}); });
@override @override
State<StatefulWidget> createState() { createState() {
return ImmichAssetGridViewState(); return ImmichAssetGridViewState();
} }
} }
class ImmichAssetGridViewState extends State<ImmichAssetGridView> { class ImmichAssetGridViewState extends ConsumerState<ImmichAssetGridView> {
final ItemScrollController _itemScrollController = ItemScrollController(); final ItemScrollController _itemScrollController = ItemScrollController();
final ScrollOffsetController _scrollOffsetController = final ScrollOffsetController _scrollOffsetController =
ScrollOffsetController(); ScrollOffsetController();
@ -314,7 +315,7 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
final now = Timeline.now; final now = Timeline.now;
if (now > (_hapticFeedbackTS + feedbackInterval)) { if (now > (_hapticFeedbackTS + feedbackInterval)) {
_hapticFeedbackTS = now; _hapticFeedbackTS = now;
HapticFeedback.mediumImpact(); ref.read(hapticFeedbackProvider.notifier).mediumImpact();
} }
} }
} }

View File

@ -1,14 +1,15 @@
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/shared/ui/immich_thumbnail.dart'; import 'package:immich_mobile/shared/ui/immich_thumbnail.dart';
import 'package:immich_mobile/utils/storage_indicator.dart'; import 'package:immich_mobile/utils/storage_indicator.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
class ThumbnailImage extends StatelessWidget { class ThumbnailImage extends ConsumerWidget {
final Asset asset; final Asset asset;
final int index; final int index;
final Asset Function(int index) loadAsset; final Asset Function(int index) loadAsset;
@ -37,7 +38,7 @@ class ThumbnailImage extends StatelessWidget {
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, WidgetRef ref) {
final assetContainerColor = context.isDarkTheme final assetContainerColor = context.isDarkTheme
? Colors.blueGrey ? Colors.blueGrey
: context.themeData.primaryColorLight; : context.themeData.primaryColorLight;
@ -186,7 +187,7 @@ class ThumbnailImage extends StatelessWidget {
}, },
onLongPress: () { onLongPress: () {
onSelect?.call(); onSelect?.call();
HapticFeedback.heavyImpact(); ref.read(hapticFeedbackProvider.notifier).heavyImpact();
}, },
child: Stack( child: Stack(
children: [ children: [

View File

@ -2,7 +2,6 @@ import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_udid/flutter_udid.dart'; import 'package:flutter_udid/flutter_udid.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/album/providers/album.provider.dart'; import 'package:immich_mobile/modules/album/providers/album.provider.dart';
@ -92,7 +91,6 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
serverUrl: serverUrl, serverUrl: serverUrl,
); );
} catch (e) { } catch (e) {
HapticFeedback.vibrate();
debugPrint("Error logging in $e"); debugPrint("Error logging in $e");
return false; return false;
} }

View File

@ -1,10 +1,10 @@
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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/home/ui/asset_grid/thumbnail_placeholder.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_placeholder.dart';
import 'package:immich_mobile/modules/memories/providers/memory.provider.dart'; import 'package:immich_mobile/modules/memories/providers/memory.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart'; import 'package:immich_mobile/shared/ui/immich_image.dart';
class MemoryLane extends HookConsumerWidget { class MemoryLane extends HookConsumerWidget {
@ -33,7 +33,9 @@ class MemoryLane extends HookConsumerWidget {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
HapticFeedback.heavyImpact(); ref
.read(hapticFeedbackProvider.notifier)
.heavyImpact();
context.pushRoute( context.pushRoute(
MemoryRoute( MemoryRoute(
memories: memories, memories: memories,

View File

@ -9,6 +9,7 @@ import 'package:immich_mobile/modules/memories/ui/memory_card.dart';
import 'package:immich_mobile/modules/memories/ui/memory_epilogue.dart'; import 'package:immich_mobile/modules/memories/ui/memory_epilogue.dart';
import 'package:immich_mobile/modules/memories/ui/memory_progress_indicator.dart'; import 'package:immich_mobile/modules/memories/ui/memory_progress_indicator.dart';
import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart'; import 'package:immich_mobile/shared/ui/immich_image.dart';
@RoutePage() @RoutePage()
@ -127,7 +128,7 @@ class MemoryPage extends HookConsumerWidget {
} }
Future<void> onAssetChanged(int otherIndex) async { Future<void> onAssetChanged(int otherIndex) async {
HapticFeedback.selectionClick(); ref.read(hapticFeedbackProvider.notifier).selectionClick();
currentAssetPage.value = otherIndex; currentAssetPage.value = otherIndex;
updateProgressText(); updateProgressText();
// Wait for page change animation to finish // Wait for page change animation to finish
@ -169,7 +170,7 @@ class MemoryPage extends HookConsumerWidget {
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
controller: memoryPageController, controller: memoryPageController,
onPageChanged: (pageNumber) { onPageChanged: (pageNumber) {
HapticFeedback.mediumImpact(); ref.read(hapticFeedbackProvider.notifier).mediumImpact();
if (pageNumber < memories.length) { if (pageNumber < memories.length) {
currentMemoryIndex.value = pageNumber; currentMemoryIndex.value = pageNumber;
currentMemory.value = memories[pageNumber]; currentMemory.value = memories[pageNumber];

View File

@ -58,6 +58,7 @@ enum AppSettingsEnum<T> {
null, null,
false, false,
), ),
enableHapticFeedback<bool>(StoreKey.enableHapticFeedback, null, true),
; ;
const AppSettingsEnum(this.storeKey, this.hiveKey, this.defaultValue); const AppSettingsEnum(this.storeKey, this.hiveKey, this.defaultValue);

View File

@ -0,0 +1,38 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/modules/settings/ui/settings_sub_title.dart';
import 'package:immich_mobile/modules/settings/ui/settings_switch_list_tile.dart';
import 'package:immich_mobile/modules/settings/utils/app_settings_update_hook.dart';
class HapticSetting extends HookConsumerWidget {
const HapticSetting({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final hapticFeedbackSetting =
useAppSettingsState(AppSettingsEnum.enableHapticFeedback);
final isHapticFeedbackEnabled =
useValueNotifier(hapticFeedbackSetting.value);
onHapticFeedbackChange(bool isEnabled) {
hapticFeedbackSetting.value = isEnabled;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SettingsSubTitle(title: "haptic_feedback_title".tr()),
SettingsSwitchListTile(
valueNotifier: isHapticFeedbackEnabled,
title: 'haptic_feedback_switch'.tr(),
onChanged: onHapticFeedbackChange,
),
],
);
}
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:immich_mobile/modules/settings/ui/preference_settings/haptic_setting.dart';
import 'package:immich_mobile/modules/settings/ui/preference_settings/theme_setting.dart'; import 'package:immich_mobile/modules/settings/ui/preference_settings/theme_setting.dart';
import 'package:immich_mobile/modules/settings/ui/settings_sub_page_scaffold.dart'; import 'package:immich_mobile/modules/settings/ui/settings_sub_page_scaffold.dart';
@ -11,6 +12,7 @@ class PreferenceSetting extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
const preferenceSettings = [ const preferenceSettings = [
ThemeSetting(), ThemeSetting(),
HapticSetting(),
]; ];
return const SettingsSubPageScaffold(settings: preferenceSettings); return const SettingsSubPageScaffold(settings: preferenceSettings);

View File

@ -191,6 +191,7 @@ enum StoreKey<T> {
selectedAlbumSortReverse<bool>(123, type: bool), selectedAlbumSortReverse<bool>(123, type: bool),
mapThemeMode<int>(124, type: int), mapThemeMode<int>(124, type: int),
mapwithPartners<bool>(125, type: bool), mapwithPartners<bool>(125, type: bool),
enableHapticFeedback<bool>(126, type: bool),
; ;
const StoreKey( const StoreKey(

View File

@ -0,0 +1,56 @@
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
final hapticFeedbackProvider =
StateNotifierProvider<HapticNotifier, void>((ref) {
return HapticNotifier(ref);
});
class HapticNotifier extends StateNotifier<void> {
void build() {}
final Ref _ref;
HapticNotifier(this._ref) : super(null);
selectionClick() {
if (_ref
.read(appSettingsServiceProvider)
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
HapticFeedback.selectionClick();
}
}
lightImpact() {
if (_ref
.read(appSettingsServiceProvider)
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
HapticFeedback.lightImpact();
}
}
mediumImpact() {
if (_ref
.read(appSettingsServiceProvider)
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
HapticFeedback.mediumImpact();
}
}
heavyImpact() {
if (_ref
.read(appSettingsServiceProvider)
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
HapticFeedback.heavyImpact();
}
}
vibrate() {
if (_ref
.read(appSettingsServiceProvider)
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
HapticFeedback.vibrate();
}
}
}

View File

@ -1,13 +1,13 @@
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.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:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.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';
import 'package:immich_mobile/shared/providers/asset.provider.dart'; import 'package:immich_mobile/shared/providers/asset.provider.dart';
import 'package:immich_mobile/shared/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/shared/providers/tab.provider.dart'; import 'package:immich_mobile/shared/providers/tab.provider.dart';
@RoutePage() @RoutePage()
@ -53,7 +53,7 @@ class TabControllerPage extends HookConsumerWidget {
scrollToTopNotifierProvider.scrollToTop(); scrollToTopNotifierProvider.scrollToTop();
} }
HapticFeedback.selectionClick(); ref.read(hapticFeedbackProvider.notifier).selectionClick();
tabsRouter.setActiveIndex(index); tabsRouter.setActiveIndex(index);
ref.read(tabProvider.notifier).state = TabEnum.values[index]; ref.read(tabProvider.notifier).state = TabEnum.values[index];
}, },
@ -107,7 +107,7 @@ class TabControllerPage extends HookConsumerWidget {
scrollToTopNotifierProvider.scrollToTop(); scrollToTopNotifierProvider.scrollToTop();
} }
HapticFeedback.selectionClick(); ref.read(hapticFeedbackProvider.notifier).selectionClick();
tabsRouter.setActiveIndex(index); tabsRouter.setActiveIndex(index);
ref.read(tabProvider.notifier).state = TabEnum.values[index]; ref.read(tabProvider.notifier).state = TabEnum.values[index];
}, },