mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:29:32 -05: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(
 | 
			
		||||
        bottom: 100,
 | 
			
		||||
      ),
 | 
			
		||||
      placeholder: placeholder,
 | 
			
		||||
      placeholder: SizedBox.expand(child: placeholder),
 | 
			
		||||
      showControls: showControls && !isMotionVideo,
 | 
			
		||||
      hideControlsTimer: hideControlsTimer,
 | 
			
		||||
      customControls: const VideoPlayerControls(),
 | 
			
		||||
@ -58,7 +58,7 @@ class VideoViewerPage extends HookWidget {
 | 
			
		||||
            if (controller == null) {
 | 
			
		||||
              return Stack(
 | 
			
		||||
                children: [
 | 
			
		||||
                  if (placeholder != null) placeholder!,
 | 
			
		||||
                  if (placeholder != null) SizedBox.expand(child: placeholder!),
 | 
			
		||||
                  const DelayedLoadingIndicator(
 | 
			
		||||
                    fadeInDuration: Duration(milliseconds: 500),
 | 
			
		||||
                  ),
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
import 'dart:ui';
 | 
			
		||||
 | 
			
		||||
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/modules/asset_viewer/views/video_viewer_page.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_thumbnail.dart';
 | 
			
		||||
 | 
			
		||||
class MemoryCard extends StatelessWidget {
 | 
			
		||||
  final Asset asset;
 | 
			
		||||
@ -22,8 +22,6 @@ class MemoryCard extends StatelessWidget {
 | 
			
		||||
    super.key,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  String get accessToken => Store.get(StoreKey.accessToken);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Card(
 | 
			
		||||
@ -38,19 +36,8 @@ class MemoryCard extends StatelessWidget {
 | 
			
		||||
      clipBehavior: Clip.hardEdge,
 | 
			
		||||
      child: Stack(
 | 
			
		||||
        children: [
 | 
			
		||||
          ImageFiltered(
 | 
			
		||||
            imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
 | 
			
		||||
            child: Container(
 | 
			
		||||
              decoration: BoxDecoration(
 | 
			
		||||
                image: DecorationImage(
 | 
			
		||||
                  image: ImmichThumbnail.imageProvider(
 | 
			
		||||
                    asset: asset,
 | 
			
		||||
                  ),
 | 
			
		||||
                  fit: BoxFit.cover,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              child: Container(color: Colors.black.withOpacity(0.2)),
 | 
			
		||||
            ),
 | 
			
		||||
          SizedBox.expand(
 | 
			
		||||
            child: _BlurredBackdrop(asset: asset),
 | 
			
		||||
          ),
 | 
			
		||||
          LayoutBuilder(
 | 
			
		||||
            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/shared/models/asset.dart';
 | 
			
		||||
import 'package:immich_mobile/shared/ui/immich_image.dart';
 | 
			
		||||
import 'package:immich_mobile/shared/ui/immich_thumbnail.dart';
 | 
			
		||||
 | 
			
		||||
@RoutePage()
 | 
			
		||||
class MemoryPage extends HookConsumerWidget {
 | 
			
		||||
@ -110,24 +109,13 @@ class MemoryPage extends HookConsumerWidget {
 | 
			
		||||
        asset = memories[nextMemoryIndex].assets.first;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Gets the thumbnail url and precaches it
 | 
			
		||||
      final precaches = <Future<dynamic>>[];
 | 
			
		||||
 | 
			
		||||
      precaches.addAll([
 | 
			
		||||
        precacheImage(
 | 
			
		||||
      // Precache the asset
 | 
			
		||||
      await precacheImage(
 | 
			
		||||
        ImmichImage.imageProvider(
 | 
			
		||||
          asset: asset,
 | 
			
		||||
        ),
 | 
			
		||||
        context,
 | 
			
		||||
        ),
 | 
			
		||||
        precacheImage(
 | 
			
		||||
          ImmichThumbnail.imageProvider(
 | 
			
		||||
            asset: asset,
 | 
			
		||||
          ),
 | 
			
		||||
          context,
 | 
			
		||||
        ),
 | 
			
		||||
      ]);
 | 
			
		||||
      await Future.wait(precaches);
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Precache the next page right away if we are on the first page
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user