|
@@ -4,6 +4,9 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|
|
import 'package:hive/hive.dart';
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
import 'package:immich_mobile/constants/hive_box.dart';
|
|
|
+import 'package:immich_mobile/modules/asset_viewer/models/image_viewer_page_state.model.dart';
|
|
|
+import 'package:immich_mobile/modules/asset_viewer/providers/image_viewer_page_state.provider.dart';
|
|
|
+import 'package:immich_mobile/modules/asset_viewer/ui/download_loading_indicator.dart';
|
|
|
import 'package:immich_mobile/modules/asset_viewer/ui/exif_bottom_sheet.dart';
|
|
|
import 'package:immich_mobile/modules/asset_viewer/ui/top_control_app_bar.dart';
|
|
|
import 'package:immich_mobile/modules/home/services/asset.service.dart';
|
|
@@ -25,6 +28,7 @@ class ImageViewerPage extends HookConsumerWidget {
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
+ final downloadAssetStatus = ref.watch(imageViewerStateProvider).downloadAssetStatus;
|
|
|
var box = Hive.box(userInfoBox);
|
|
|
|
|
|
getAssetExif() async {
|
|
@@ -42,65 +46,77 @@ class ImageViewerPage extends HookConsumerWidget {
|
|
|
asset: asset,
|
|
|
onMoreInfoPressed: () {
|
|
|
showModalBottomSheet(
|
|
|
- backgroundColor: Colors.black,
|
|
|
- barrierColor: Colors.transparent,
|
|
|
- isScrollControlled: false,
|
|
|
- context: context,
|
|
|
- builder: (context) {
|
|
|
- return ExifBottomSheet(assetDetail: assetDetail!);
|
|
|
- });
|
|
|
+ backgroundColor: Colors.black,
|
|
|
+ barrierColor: Colors.transparent,
|
|
|
+ isScrollControlled: false,
|
|
|
+ context: context,
|
|
|
+ builder: (context) {
|
|
|
+ return ExifBottomSheet(assetDetail: assetDetail!);
|
|
|
+ },
|
|
|
+ );
|
|
|
+ },
|
|
|
+ onDownloadPressed: () {
|
|
|
+ ref.watch(imageViewerStateProvider.notifier).downloadAsset(asset, context);
|
|
|
},
|
|
|
),
|
|
|
body: SafeArea(
|
|
|
- child: Center(
|
|
|
- child: Hero(
|
|
|
- tag: heroTag,
|
|
|
- child: CachedNetworkImage(
|
|
|
- fit: BoxFit.cover,
|
|
|
- imageUrl: imageUrl,
|
|
|
- httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
|
|
|
- fadeInDuration: const Duration(milliseconds: 250),
|
|
|
- errorWidget: (context, url, error) => ConstrainedBox(
|
|
|
- constraints: const BoxConstraints(maxWidth: 300),
|
|
|
- child: Wrap(
|
|
|
- spacing: 32,
|
|
|
- runSpacing: 32,
|
|
|
- alignment: WrapAlignment.center,
|
|
|
- children: [
|
|
|
- const Text(
|
|
|
- "Failed To Render Image - Possibly Corrupted Data",
|
|
|
- textAlign: TextAlign.center,
|
|
|
- style: TextStyle(fontSize: 16, color: Colors.white),
|
|
|
+ child: Stack(
|
|
|
+ children: [
|
|
|
+ Center(
|
|
|
+ child: Hero(
|
|
|
+ tag: heroTag,
|
|
|
+ child: CachedNetworkImage(
|
|
|
+ fit: BoxFit.cover,
|
|
|
+ imageUrl: imageUrl,
|
|
|
+ httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
|
|
|
+ fadeInDuration: const Duration(milliseconds: 250),
|
|
|
+ errorWidget: (context, url, error) => ConstrainedBox(
|
|
|
+ constraints: const BoxConstraints(maxWidth: 300),
|
|
|
+ child: Wrap(
|
|
|
+ spacing: 32,
|
|
|
+ runSpacing: 32,
|
|
|
+ alignment: WrapAlignment.center,
|
|
|
+ children: [
|
|
|
+ const Text(
|
|
|
+ "Failed To Render Image - Possibly Corrupted Data",
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ style: TextStyle(fontSize: 16, color: Colors.white),
|
|
|
+ ),
|
|
|
+ SingleChildScrollView(
|
|
|
+ child: Text(
|
|
|
+ error.toString(),
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ style: TextStyle(fontSize: 12, color: Colors.grey[400]),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
),
|
|
|
- SingleChildScrollView(
|
|
|
- child: Text(
|
|
|
- error.toString(),
|
|
|
- textAlign: TextAlign.center,
|
|
|
- style: TextStyle(fontSize: 12, color: Colors.grey[400]),
|
|
|
+ ),
|
|
|
+ placeholder: (context, url) {
|
|
|
+ return CachedNetworkImage(
|
|
|
+ cacheKey: thumbnailUrl,
|
|
|
+ fit: BoxFit.cover,
|
|
|
+ imageUrl: thumbnailUrl,
|
|
|
+ httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
|
|
|
+ placeholderFadeInDuration: const Duration(milliseconds: 0),
|
|
|
+ progressIndicatorBuilder: (context, url, downloadProgress) => Transform.scale(
|
|
|
+ scale: 0.2,
|
|
|
+ child: CircularProgressIndicator(value: downloadProgress.progress),
|
|
|
),
|
|
|
- ),
|
|
|
- ],
|
|
|
+ errorWidget: (context, url, error) => Icon(
|
|
|
+ Icons.error,
|
|
|
+ color: Colors.grey[300],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ },
|
|
|
),
|
|
|
),
|
|
|
- placeholder: (context, url) {
|
|
|
- return CachedNetworkImage(
|
|
|
- cacheKey: thumbnailUrl,
|
|
|
- fit: BoxFit.cover,
|
|
|
- imageUrl: thumbnailUrl,
|
|
|
- httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
|
|
|
- placeholderFadeInDuration: const Duration(milliseconds: 0),
|
|
|
- progressIndicatorBuilder: (context, url, downloadProgress) => Transform.scale(
|
|
|
- scale: 0.2,
|
|
|
- child: CircularProgressIndicator(value: downloadProgress.progress),
|
|
|
- ),
|
|
|
- errorWidget: (context, url, error) => Icon(
|
|
|
- Icons.error,
|
|
|
- color: Colors.grey[300],
|
|
|
- ),
|
|
|
- );
|
|
|
- },
|
|
|
),
|
|
|
- ),
|
|
|
+ if (downloadAssetStatus == DownloadAssetStatus.loading)
|
|
|
+ const Center(
|
|
|
+ child: DownloadLoadingIndicator(),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
),
|
|
|
),
|
|
|
);
|