|
|
|
|
@ -19,6 +19,7 @@ import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider
|
|
|
|
|
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
|
|
|
|
import 'package:immich_mobile/providers/image/immich_remote_image_provider.dart';
|
|
|
|
|
import 'package:immich_mobile/services/app_settings.service.dart';
|
|
|
|
|
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
|
|
|
|
import 'package:immich_mobile/widgets/asset_viewer/advanced_bottom_sheet.dart';
|
|
|
|
|
import 'package:immich_mobile/widgets/asset_viewer/bottom_gallery_bar.dart';
|
|
|
|
|
import 'package:immich_mobile/widgets/asset_viewer/exif_sheet/exif_bottom_sheet.dart';
|
|
|
|
|
@ -34,17 +35,15 @@ import 'package:isar/isar.dart';
|
|
|
|
|
@RoutePage()
|
|
|
|
|
// ignore: must_be_immutable
|
|
|
|
|
class GalleryViewerPage extends HookConsumerWidget {
|
|
|
|
|
final Asset Function(int index) loadAsset;
|
|
|
|
|
final int totalAssets;
|
|
|
|
|
final int initialIndex;
|
|
|
|
|
final int heroOffset;
|
|
|
|
|
final bool showStack;
|
|
|
|
|
final RenderList renderList;
|
|
|
|
|
|
|
|
|
|
GalleryViewerPage({
|
|
|
|
|
super.key,
|
|
|
|
|
required this.initialIndex,
|
|
|
|
|
required this.loadAsset,
|
|
|
|
|
required this.totalAssets,
|
|
|
|
|
required this.renderList,
|
|
|
|
|
this.initialIndex = 0,
|
|
|
|
|
this.heroOffset = 0,
|
|
|
|
|
this.showStack = false,
|
|
|
|
|
}) : controller = PageController(initialPage: initialIndex);
|
|
|
|
|
@ -54,6 +53,8 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
|
|
final settings = ref.watch(appSettingsServiceProvider);
|
|
|
|
|
final loadAsset = renderList.loadAsset;
|
|
|
|
|
final totalAssets = useState(renderList.totalAssets);
|
|
|
|
|
final isLoadPreview = useState(AppSettingsEnum.loadPreview.defaultValue);
|
|
|
|
|
final isLoadOriginal = useState(AppSettingsEnum.loadOriginal.defaultValue);
|
|
|
|
|
final shouldLoopVideo = useState(AppSettingsEnum.loopVideo.defaultValue);
|
|
|
|
|
@ -62,6 +63,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|
|
|
|
final localPosition = useState<Offset?>(null);
|
|
|
|
|
final currentIndex = useState(initialIndex);
|
|
|
|
|
final currentAsset = loadAsset(currentIndex.value);
|
|
|
|
|
|
|
|
|
|
// Update is playing motion video
|
|
|
|
|
ref.listen(videoPlaybackValueProvider.select((v) => v.state), (_, state) {
|
|
|
|
|
isPlayingVideo.value = state == VideoPlaybackState.playing;
|
|
|
|
|
@ -112,7 +114,8 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|
|
|
|
debugPrint('Error precaching next image: $exception, $stackTrace');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (index < totalAssets && index >= 0) {
|
|
|
|
|
try {
|
|
|
|
|
if (index < totalAssets.value && index >= 0) {
|
|
|
|
|
final asset = loadAsset(index);
|
|
|
|
|
await precacheImage(
|
|
|
|
|
ImmichImage.imageProvider(asset: asset),
|
|
|
|
|
@ -120,6 +123,11 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|
|
|
|
onError: onError,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// swallow error silently
|
|
|
|
|
debugPrint('Error precaching next image: $e');
|
|
|
|
|
context.maybePop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void showInfo() {
|
|
|
|
|
@ -297,7 +305,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|
|
|
|
? const ScrollPhysics() // Use bouncing physics for iOS
|
|
|
|
|
: const ClampingScrollPhysics() // Use heavy physics for Android
|
|
|
|
|
),
|
|
|
|
|
itemCount: totalAssets,
|
|
|
|
|
itemCount: totalAssets.value,
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
onPageChanged: (value) async {
|
|
|
|
|
final next = currentIndex.value < value ? value + 1 : value - 1;
|
|
|
|
|
@ -406,11 +414,13 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
BottomGalleryBar(
|
|
|
|
|
renderList: renderList,
|
|
|
|
|
totalAssets: totalAssets,
|
|
|
|
|
controller: controller,
|
|
|
|
|
showStack: showStack,
|
|
|
|
|
stackIndex: stackIndex.value,
|
|
|
|
|
asset: asset,
|
|
|
|
|
assetIndex: currentIndex.value,
|
|
|
|
|
showVideoPlayerControls: !asset.isImage && !isMotionPhoto,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
|