mirror of
https://github.com/immich-app/immich.git
synced 2024-11-15 09:59:00 -07:00
refactor(mobile): Uses blurhash for memory card instead of blurred thumbnail (#7469)
* Uses blurhash for memory card instead of blurred thumbnail New blurred backdrop widget Comments * Fixes video placeholder image placement * unused import
This commit is contained in:
parent
908104299d
commit
b15eec7ca7
@ -40,7 +40,7 @@ class VideoViewerPage extends HookWidget {
|
|||||||
controlsSafeAreaMinimum: const EdgeInsets.only(
|
controlsSafeAreaMinimum: const EdgeInsets.only(
|
||||||
bottom: 100,
|
bottom: 100,
|
||||||
),
|
),
|
||||||
placeholder: placeholder,
|
placeholder: SizedBox.expand(child: placeholder),
|
||||||
showControls: showControls && !isMotionVideo,
|
showControls: showControls && !isMotionVideo,
|
||||||
hideControlsTimer: hideControlsTimer,
|
hideControlsTimer: hideControlsTimer,
|
||||||
customControls: const VideoPlayerControls(),
|
customControls: const VideoPlayerControls(),
|
||||||
@ -58,7 +58,7 @@ class VideoViewerPage extends HookWidget {
|
|||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
if (placeholder != null) placeholder!,
|
if (placeholder != null) SizedBox.expand(child: placeholder!),
|
||||||
const DelayedLoadingIndicator(
|
const DelayedLoadingIndicator(
|
||||||
fadeInDuration: Duration(milliseconds: 500),
|
fadeInDuration: Duration(milliseconds: 500),
|
||||||
),
|
),
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.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/views/video_viewer_page.dart';
|
import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/models/store.dart';
|
import 'package:immich_mobile/shared/ui/hooks/blurhash_hook.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';
|
|
||||||
|
|
||||||
class MemoryCard extends StatelessWidget {
|
class MemoryCard extends StatelessWidget {
|
||||||
final Asset asset;
|
final Asset asset;
|
||||||
@ -22,8 +22,6 @@ class MemoryCard extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
String get accessToken => Store.get(StoreKey.accessToken);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Card(
|
return Card(
|
||||||
@ -38,19 +36,8 @@ class MemoryCard extends StatelessWidget {
|
|||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
ImageFiltered(
|
SizedBox.expand(
|
||||||
imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
|
child: _BlurredBackdrop(asset: asset),
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image: ImmichThumbnail.imageProvider(
|
|
||||||
asset: asset,
|
|
||||||
),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Container(color: Colors.black.withOpacity(0.2)),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
LayoutBuilder(
|
LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
@ -113,3 +100,50 @@ class MemoryCard extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _BlurredBackdrop extends HookWidget {
|
||||||
|
final Asset asset;
|
||||||
|
|
||||||
|
const _BlurredBackdrop({required this.asset});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final blurhash = useBlurHashRef(asset).value;
|
||||||
|
if (blurhash != null) {
|
||||||
|
// Use a nice cheap blur hash image decoration
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: MemoryImage(
|
||||||
|
blurhash,
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
color: Colors.black.withOpacity(0.2),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Fall back to using a more expensive image filtered
|
||||||
|
// Since the ImmichImage is already precached, we can
|
||||||
|
// safely use that as the image provider
|
||||||
|
return ImageFiltered(
|
||||||
|
imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: ImmichImage.imageProvider(
|
||||||
|
asset: asset,
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
color: Colors.black.withOpacity(0.2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,7 +10,6 @@ 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/ui/immich_image.dart';
|
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
||||||
import 'package:immich_mobile/shared/ui/immich_thumbnail.dart';
|
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class MemoryPage extends HookConsumerWidget {
|
class MemoryPage extends HookConsumerWidget {
|
||||||
@ -110,24 +109,13 @@ class MemoryPage extends HookConsumerWidget {
|
|||||||
asset = memories[nextMemoryIndex].assets.first;
|
asset = memories[nextMemoryIndex].assets.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the thumbnail url and precaches it
|
// Precache the asset
|
||||||
final precaches = <Future<dynamic>>[];
|
await precacheImage(
|
||||||
|
ImmichImage.imageProvider(
|
||||||
precaches.addAll([
|
asset: asset,
|
||||||
precacheImage(
|
|
||||||
ImmichImage.imageProvider(
|
|
||||||
asset: asset,
|
|
||||||
),
|
|
||||||
context,
|
|
||||||
),
|
),
|
||||||
precacheImage(
|
context,
|
||||||
ImmichThumbnail.imageProvider(
|
);
|
||||||
asset: asset,
|
|
||||||
),
|
|
||||||
context,
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
await Future.wait(precaches);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precache the next page right away if we are on the first page
|
// Precache the next page right away if we are on the first page
|
||||||
|
Loading…
Reference in New Issue
Block a user