mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
migrate viewer config
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:immich_mobile/domain/models/config/image_config.dart';
|
|||||||
import 'package:immich_mobile/domain/models/config/map_config.dart';
|
import 'package:immich_mobile/domain/models/config/map_config.dart';
|
||||||
import 'package:immich_mobile/domain/models/config/theme_config.dart';
|
import 'package:immich_mobile/domain/models/config/theme_config.dart';
|
||||||
import 'package:immich_mobile/domain/models/config/timeline_config.dart';
|
import 'package:immich_mobile/domain/models/config/timeline_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/viewer_config.dart';
|
||||||
|
|
||||||
class AppConfig {
|
class AppConfig {
|
||||||
final ThemeConfig theme;
|
final ThemeConfig theme;
|
||||||
@@ -10,6 +11,7 @@ class AppConfig {
|
|||||||
final MapConfig map;
|
final MapConfig map;
|
||||||
final TimelineConfig timeline;
|
final TimelineConfig timeline;
|
||||||
final ImageConfig image;
|
final ImageConfig image;
|
||||||
|
final ViewerConfig viewer;
|
||||||
|
|
||||||
const AppConfig({
|
const AppConfig({
|
||||||
this.theme = const .new(),
|
this.theme = const .new(),
|
||||||
@@ -17,6 +19,7 @@ class AppConfig {
|
|||||||
this.map = const .new(),
|
this.map = const .new(),
|
||||||
this.timeline = const .new(),
|
this.timeline = const .new(),
|
||||||
this.image = const .new(),
|
this.image = const .new(),
|
||||||
|
this.viewer = const .new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
AppConfig copyWith({
|
AppConfig copyWith({
|
||||||
@@ -25,12 +28,14 @@ class AppConfig {
|
|||||||
MapConfig? map,
|
MapConfig? map,
|
||||||
TimelineConfig? timeline,
|
TimelineConfig? timeline,
|
||||||
ImageConfig? image,
|
ImageConfig? image,
|
||||||
|
ViewerConfig? viewer,
|
||||||
}) => .new(
|
}) => .new(
|
||||||
theme: theme ?? this.theme,
|
theme: theme ?? this.theme,
|
||||||
cleanup: cleanup ?? this.cleanup,
|
cleanup: cleanup ?? this.cleanup,
|
||||||
map: map ?? this.map,
|
map: map ?? this.map,
|
||||||
timeline: timeline ?? this.timeline,
|
timeline: timeline ?? this.timeline,
|
||||||
image: image ?? this.image,
|
image: image ?? this.image,
|
||||||
|
viewer: viewer ?? this.viewer,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -41,11 +46,13 @@ class AppConfig {
|
|||||||
other.cleanup == cleanup &&
|
other.cleanup == cleanup &&
|
||||||
other.map == map &&
|
other.map == map &&
|
||||||
other.timeline == timeline &&
|
other.timeline == timeline &&
|
||||||
other.image == image);
|
other.image == image &&
|
||||||
|
other.viewer == viewer);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(theme, cleanup, map, timeline, image);
|
int get hashCode => Object.hash(theme, cleanup, map, timeline, image, viewer);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AppConfig(theme: $theme, cleanup: $cleanup, map: $map, timeline: $timeline, image: $image)';
|
String toString() =>
|
||||||
|
'AppConfig(theme: $theme, cleanup: $cleanup, map: $map, timeline: $timeline, image: $image, viewer: $viewer)';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
class ViewerConfig {
|
||||||
|
final bool loopVideo;
|
||||||
|
final bool loadOriginalVideo;
|
||||||
|
final bool autoPlayVideo;
|
||||||
|
final bool tapToNavigate;
|
||||||
|
|
||||||
|
const ViewerConfig({
|
||||||
|
this.loopVideo = true,
|
||||||
|
this.loadOriginalVideo = false,
|
||||||
|
this.autoPlayVideo = true,
|
||||||
|
this.tapToNavigate = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ViewerConfig copyWith({bool? loopVideo, bool? loadOriginalVideo, bool? autoPlayVideo, bool? tapToNavigate}) =>
|
||||||
|
ViewerConfig(
|
||||||
|
loopVideo: loopVideo ?? this.loopVideo,
|
||||||
|
loadOriginalVideo: loadOriginalVideo ?? this.loadOriginalVideo,
|
||||||
|
autoPlayVideo: autoPlayVideo ?? this.autoPlayVideo,
|
||||||
|
tapToNavigate: tapToNavigate ?? this.tapToNavigate,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is ViewerConfig &&
|
||||||
|
other.loopVideo == loopVideo &&
|
||||||
|
other.loadOriginalVideo == loadOriginalVideo &&
|
||||||
|
other.autoPlayVideo == autoPlayVideo &&
|
||||||
|
other.tapToNavigate == tapToNavigate);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(loopVideo, loadOriginalVideo, autoPlayVideo, tapToNavigate);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'ViewerConfig(loopVideo: $loopVideo, loadOriginalVideo: $loadOriginalVideo, autoPlayVideo: $autoPlayVideo, tapToNavigate: $tapToNavigate)';
|
||||||
|
}
|
||||||
@@ -28,6 +28,12 @@ enum MetadataKey<T extends Object> {
|
|||||||
imagePreferRemote<bool>(.appConfig, 'image.preferRemote', false),
|
imagePreferRemote<bool>(.appConfig, 'image.preferRemote', false),
|
||||||
imageLoadOriginal<bool>(.appConfig, 'image.loadOriginal', false),
|
imageLoadOriginal<bool>(.appConfig, 'image.loadOriginal', false),
|
||||||
|
|
||||||
|
// Viewer
|
||||||
|
viewerLoopVideo<bool>(.appConfig, 'viewer.loopVideo', true),
|
||||||
|
viewerLoadOriginalVideo<bool>(.appConfig, 'viewer.loadOriginalVideo', false),
|
||||||
|
viewerAutoPlayVideo<bool>(.appConfig, 'viewer.autoPlayVideo', true),
|
||||||
|
viewerTapToNavigate<bool>(.appConfig, 'viewer.tapToNavigate', false),
|
||||||
|
|
||||||
// Timeline
|
// Timeline
|
||||||
timelineTilesPerRow<int>(.appConfig, 'timeline.tilesPerRow', 4),
|
timelineTilesPerRow<int>(.appConfig, 'timeline.tilesPerRow', 4),
|
||||||
timelineGroupAssetsBy<GroupAssetsBy>(
|
timelineGroupAssetsBy<GroupAssetsBy>(
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
|
|
||||||
enum Setting<T> {
|
enum Setting<T> {
|
||||||
loadOriginalVideo<bool>(StoreKey.loadOriginalVideo, false),
|
|
||||||
autoPlayVideo<bool>(StoreKey.autoPlayVideo, true),
|
|
||||||
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, false),
|
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, false),
|
||||||
enableBackup<bool>(StoreKey.enableBackup, false);
|
enableBackup<bool>(StoreKey.enableBackup, false);
|
||||||
|
|
||||||
|
|||||||
@@ -39,12 +39,6 @@ enum StoreKey<T> {
|
|||||||
readonlyModeEnabled<bool>._(138),
|
readonlyModeEnabled<bool>._(138),
|
||||||
albumGridView<bool>._(140),
|
albumGridView<bool>._(140),
|
||||||
|
|
||||||
// Image viewer navigation settings
|
|
||||||
loopVideo<bool>._(117),
|
|
||||||
loadOriginalVideo<bool>._(136),
|
|
||||||
autoPlayVideo<bool>._(139),
|
|
||||||
tapToNavigate<bool>._(141),
|
|
||||||
|
|
||||||
// Experimental stuff
|
// Experimental stuff
|
||||||
enableBackup<bool>._(1003),
|
enableBackup<bool>._(1003),
|
||||||
useWifiForUploadVideos<bool>._(1004),
|
useWifiForUploadVideos<bool>._(1004),
|
||||||
@@ -52,6 +46,10 @@ enum StoreKey<T> {
|
|||||||
syncMigrationStatus<String>._(1013),
|
syncMigrationStatus<String>._(1013),
|
||||||
|
|
||||||
// Legacy keys that have been migrated to the new metadata store
|
// Legacy keys that have been migrated to the new metadata store
|
||||||
|
legacyLoopVideo<bool>._(117),
|
||||||
|
legacyLoadOriginalVideo<bool>._(136),
|
||||||
|
legacyAutoPlayVideo<bool>._(139),
|
||||||
|
legacyTapToNavigate<bool>._(141),
|
||||||
legacyPreferRemoteImage<bool>._(116),
|
legacyPreferRemoteImage<bool>._(116),
|
||||||
legacyLoadOriginal<bool>._(101),
|
legacyLoadOriginal<bool>._(101),
|
||||||
legacyPrimaryColor<String>._(128),
|
legacyPrimaryColor<String>._(128),
|
||||||
|
|||||||
@@ -127,6 +127,12 @@ extension<T extends Object> on MetadataDomain<T> {
|
|||||||
storageIndicator: repo._read(.timelineStorageIndicator),
|
storageIndicator: repo._read(.timelineStorageIndicator),
|
||||||
),
|
),
|
||||||
image: .new(preferRemote: repo._read(.imagePreferRemote), loadOriginal: repo._read(.imageLoadOriginal)),
|
image: .new(preferRemote: repo._read(.imagePreferRemote), loadOriginal: repo._read(.imageLoadOriginal)),
|
||||||
|
viewer: .new(
|
||||||
|
loopVideo: repo._read(.viewerLoopVideo),
|
||||||
|
loadOriginalVideo: repo._read(.viewerLoadOriginalVideo),
|
||||||
|
autoPlayVideo: repo._read(.viewerAutoPlayVideo),
|
||||||
|
tapToNavigate: repo._read(.viewerTapToNavigate),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
case .systemConfig:
|
case .systemConfig:
|
||||||
repo._systemConfig = .new(logLevel: repo._read(.logLevel));
|
repo._systemConfig = .new(logLevel: repo._read(.logLevel));
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'
|
|||||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/video_viewer.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/video_viewer.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart';
|
||||||
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
|
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
|
||||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart';
|
import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart';
|
||||||
import 'package:immich_mobile/widgets/photo_view/photo_view.dart';
|
import 'package:immich_mobile/widgets/photo_view/photo_view.dart';
|
||||||
@@ -217,7 +216,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||||||
void _onTapUp(BuildContext context, TapUpDetails details, PhotoViewControllerValue controllerValue) {
|
void _onTapUp(BuildContext context, TapUpDetails details, PhotoViewControllerValue controllerValue) {
|
||||||
if (_showingDetails || _dragStart != null) return;
|
if (_showingDetails || _dragStart != null) return;
|
||||||
|
|
||||||
final tapToNavigate = ref.read(appSettingsServiceProvider).getSetting<bool>(AppSettingsEnum.tapToNavigate);
|
final tapToNavigate = MetadataRepository.instance.appConfig.viewer.tapToNavigate;
|
||||||
if (!tapToNavigate) {
|
if (!tapToNavigate) {
|
||||||
_viewer.toggleControls();
|
_viewer.toggleControls();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -3,21 +3,17 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/setting.model.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/setting.service.dart';
|
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/extensions/platform_extensions.dart';
|
import 'package:immich_mobile/extensions/platform_extensions.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||||
import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart';
|
import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart';
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
|
||||||
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
|
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
|
||||||
import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart';
|
import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart';
|
||||||
import 'package:immich_mobile/providers/cast.provider.dart';
|
import 'package:immich_mobile/providers/cast.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/setting.provider.dart';
|
|
||||||
import 'package:immich_mobile/services/api.service.dart';
|
import 'package:immich_mobile/services/api.service.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:native_video_player/native_video_player.dart';
|
import 'package:native_video_player/native_video_player.dart';
|
||||||
|
|
||||||
@@ -120,7 +116,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
|||||||
final remoteId = (videoAsset as RemoteAsset).id;
|
final remoteId = (videoAsset as RemoteAsset).id;
|
||||||
|
|
||||||
final serverEndpoint = Store.get(StoreKey.serverEndpoint);
|
final serverEndpoint = Store.get(StoreKey.serverEndpoint);
|
||||||
final isOriginalVideo = ref.read(settingsProvider).get<bool>(Setting.loadOriginalVideo);
|
final isOriginalVideo = MetadataRepository.instance.appConfig.viewer.loadOriginalVideo;
|
||||||
final String postfixUrl = isOriginalVideo ? 'original' : 'video/playback';
|
final String postfixUrl = isOriginalVideo ? 'original' : 'video/playback';
|
||||||
final String videoUrl = videoAsset.livePhotoVideoId != null
|
final String videoUrl = videoAsset.livePhotoVideoId != null
|
||||||
? '$serverEndpoint/assets/${videoAsset.livePhotoVideoId}/$postfixUrl'
|
? '$serverEndpoint/assets/${videoAsset.livePhotoVideoId}/$postfixUrl'
|
||||||
@@ -147,7 +143,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
|||||||
|
|
||||||
if (ref.read(assetViewerProvider).showingDetails) return;
|
if (ref.read(assetViewerProvider).showingDetails) return;
|
||||||
|
|
||||||
final autoPlayVideo = AppSetting.get(Setting.autoPlayVideo);
|
final autoPlayVideo = MetadataRepository.instance.appConfig.viewer.autoPlayVideo;
|
||||||
if (autoPlayVideo || widget.asset.isMotionPhoto) await _notifier.play();
|
if (autoPlayVideo || widget.asset.isMotionPhoto) await _notifier.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +182,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
|||||||
if (source == null || !mounted) return;
|
if (source == null || !mounted) return;
|
||||||
|
|
||||||
await _notifier.load(source);
|
await _notifier.load(source);
|
||||||
final loopVideo = ref.read(appSettingsServiceProvider).getSetting<bool>(AppSettingsEnum.loopVideo);
|
final loopVideo = MetadataRepository.instance.appConfig.viewer.loopVideo;
|
||||||
await _notifier.setLoop(!widget.asset.isMotionPhoto && loopVideo);
|
await _notifier.setLoop(!widget.asset.isMotionPhoto && loopVideo);
|
||||||
await _notifier.setVolume(1);
|
await _notifier.setVolume(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ enum AppSettingsEnum<T> {
|
|||||||
selectedAlbumSortOrder<int>(StoreKey.selectedAlbumSortOrder, "selectedAlbumSortOrder", 2),
|
selectedAlbumSortOrder<int>(StoreKey.selectedAlbumSortOrder, "selectedAlbumSortOrder", 2),
|
||||||
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, null, false),
|
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, null, false),
|
||||||
manageLocalMediaAndroid<bool>(StoreKey.manageLocalMediaAndroid, null, false),
|
manageLocalMediaAndroid<bool>(StoreKey.manageLocalMediaAndroid, null, false),
|
||||||
loopVideo<bool>(StoreKey.loopVideo, "loopVideo", true),
|
|
||||||
loadOriginalVideo<bool>(StoreKey.loadOriginalVideo, "loadOriginalVideo", false),
|
|
||||||
autoPlayVideo<bool>(StoreKey.autoPlayVideo, "autoPlayVideo", true),
|
|
||||||
tapToNavigate<bool>(StoreKey.tapToNavigate, "tapToNavigate", false),
|
|
||||||
allowSelfSignedSSLCert<bool>(StoreKey.selfSignedCert, null, false),
|
allowSelfSignedSSLCert<bool>(StoreKey.selfSignedCert, null, false),
|
||||||
selectedAlbumSortReverse<bool>(StoreKey.selectedAlbumSortReverse, null, true),
|
selectedAlbumSortReverse<bool>(StoreKey.selectedAlbumSortReverse, null, true),
|
||||||
enableHapticFeedback<bool>(StoreKey.enableHapticFeedback, null, true),
|
enableHapticFeedback<bool>(StoreKey.enableHapticFeedback, null, true),
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ Future<void> _migrateTo26(Drift drift) async {
|
|||||||
// Image
|
// Image
|
||||||
await migrator.migrateBool(StoreKey.legacyPreferRemoteImage, MetadataKey.imagePreferRemote);
|
await migrator.migrateBool(StoreKey.legacyPreferRemoteImage, MetadataKey.imagePreferRemote);
|
||||||
await migrator.migrateBool(StoreKey.legacyLoadOriginal, MetadataKey.imageLoadOriginal);
|
await migrator.migrateBool(StoreKey.legacyLoadOriginal, MetadataKey.imageLoadOriginal);
|
||||||
|
// Viewer
|
||||||
|
await migrator.migrateBool(StoreKey.legacyLoopVideo, MetadataKey.viewerLoopVideo);
|
||||||
|
await migrator.migrateBool(StoreKey.legacyLoadOriginalVideo, MetadataKey.viewerLoadOriginalVideo);
|
||||||
|
await migrator.migrateBool(StoreKey.legacyAutoPlayVideo, MetadataKey.viewerAutoPlayVideo);
|
||||||
|
await migrator.migrateBool(StoreKey.legacyTapToNavigate, MetadataKey.viewerTapToNavigate);
|
||||||
await migrator.complete();
|
await migrator.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -1,18 +1,20 @@
|
|||||||
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_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
|
||||||
import 'package:immich_mobile/widgets/settings/settings_sub_title.dart';
|
import 'package:immich_mobile/widgets/settings/settings_sub_title.dart';
|
||||||
import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart';
|
import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart';
|
||||||
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
|
|
||||||
|
|
||||||
class ImageViewerTapToNavigateSetting extends HookConsumerWidget {
|
class ImageViewerTapToNavigateSetting extends HookConsumerWidget {
|
||||||
const ImageViewerTapToNavigateSetting({super.key});
|
const ImageViewerTapToNavigateSetting({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final tapToNavigate = useAppSettingsState(AppSettingsEnum.tapToNavigate);
|
final tapToNavigate = useState(ref.read(appConfigProvider).viewer.tapToNavigate);
|
||||||
|
useValueChanged<bool, void>(tapToNavigate.value, (_, __) {
|
||||||
|
ref.read(metadataProvider).write(.viewerTapToNavigate, tapToNavigate.value);
|
||||||
|
});
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@@ -22,7 +24,6 @@ class ImageViewerTapToNavigateSetting extends HookConsumerWidget {
|
|||||||
valueNotifier: tapToNavigate,
|
valueNotifier: tapToNavigate,
|
||||||
title: "setting_image_navigation_enable_title".tr(),
|
title: "setting_image_navigation_enable_title".tr(),
|
||||||
subtitle: "setting_image_navigation_enable_subtitle".tr(),
|
subtitle: "setting_image_navigation_enable_subtitle".tr(),
|
||||||
onChanged: (_) => ref.invalidate(appSettingsServiceProvider),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
|
||||||
import 'package:immich_mobile/widgets/settings/setting_group_title.dart';
|
import 'package:immich_mobile/widgets/settings/setting_group_title.dart';
|
||||||
import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart';
|
import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart';
|
||||||
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
|
|
||||||
|
|
||||||
class VideoViewerSettings extends HookConsumerWidget {
|
class VideoViewerSettings extends HookConsumerWidget {
|
||||||
const VideoViewerSettings({super.key});
|
const VideoViewerSettings({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final useLoopVideo = useAppSettingsState(AppSettingsEnum.loopVideo);
|
final viewer = ref.read(appConfigProvider).viewer;
|
||||||
final useOriginalVideo = useAppSettingsState(AppSettingsEnum.loadOriginalVideo);
|
final useAutoPlayVideo = useState(viewer.autoPlayVideo);
|
||||||
final useAutoPlayVideo = useAppSettingsState(AppSettingsEnum.autoPlayVideo);
|
final useLoopVideo = useState(viewer.loopVideo);
|
||||||
|
final useOriginalVideo = useState(viewer.loadOriginalVideo);
|
||||||
|
|
||||||
|
useValueChanged<bool, void>(useAutoPlayVideo.value, (_, __) {
|
||||||
|
ref.read(metadataProvider).write(.viewerAutoPlayVideo, useAutoPlayVideo.value);
|
||||||
|
});
|
||||||
|
useValueChanged<bool, void>(useLoopVideo.value, (_, __) {
|
||||||
|
ref.read(metadataProvider).write(.viewerLoopVideo, useLoopVideo.value);
|
||||||
|
});
|
||||||
|
useValueChanged<bool, void>(useOriginalVideo.value, (_, __) {
|
||||||
|
ref.read(metadataProvider).write(.viewerLoadOriginalVideo, useOriginalVideo.value);
|
||||||
|
});
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@@ -27,19 +37,16 @@ class VideoViewerSettings extends HookConsumerWidget {
|
|||||||
valueNotifier: useAutoPlayVideo,
|
valueNotifier: useAutoPlayVideo,
|
||||||
title: "setting_video_viewer_auto_play_title".t(context: context),
|
title: "setting_video_viewer_auto_play_title".t(context: context),
|
||||||
subtitle: "setting_video_viewer_auto_play_subtitle".t(context: context),
|
subtitle: "setting_video_viewer_auto_play_subtitle".t(context: context),
|
||||||
onChanged: (_) => ref.invalidate(appSettingsServiceProvider),
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile(
|
SettingsSwitchListTile(
|
||||||
valueNotifier: useLoopVideo,
|
valueNotifier: useLoopVideo,
|
||||||
title: "setting_video_viewer_looping_title".t(context: context),
|
title: "setting_video_viewer_looping_title".t(context: context),
|
||||||
subtitle: "loop_videos_description".t(context: context),
|
subtitle: "loop_videos_description".t(context: context),
|
||||||
onChanged: (_) => ref.invalidate(appSettingsServiceProvider),
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile(
|
SettingsSwitchListTile(
|
||||||
valueNotifier: useOriginalVideo,
|
valueNotifier: useOriginalVideo,
|
||||||
title: "setting_video_viewer_original_video_title".t(context: context),
|
title: "setting_video_viewer_original_video_title".t(context: context),
|
||||||
subtitle: "setting_video_viewer_original_video_subtitle".t(context: context),
|
subtitle: "setting_video_viewer_original_video_subtitle".t(context: context),
|
||||||
onChanged: (_) => ref.invalidate(appSettingsServiceProvider),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ void main() {
|
|||||||
expect(sut.appConfig.theme.mode, ThemeMode.system);
|
expect(sut.appConfig.theme.mode, ThemeMode.system);
|
||||||
|
|
||||||
await MetadataRepository.refresh();
|
await MetadataRepository.refresh();
|
||||||
|
|
||||||
expect(sut.appConfig.theme.mode, ThemeMode.dark);
|
expect(sut.appConfig.theme.mode, ThemeMode.dark);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -90,7 +89,6 @@ void main() {
|
|||||||
expect(sut.appConfig.theme.mode, ThemeMode.dark);
|
expect(sut.appConfig.theme.mode, ThemeMode.dark);
|
||||||
|
|
||||||
await MetadataRepository.refresh();
|
await MetadataRepository.refresh();
|
||||||
|
|
||||||
expect(sut.appConfig.theme.mode, ThemeMode.system);
|
expect(sut.appConfig.theme.mode, ThemeMode.system);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -135,5 +133,4 @@ void main() {
|
|||||||
await expectation;
|
await expectation;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user