1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-28 06:31:58 +00:00

blurhash fade to thumb

This commit is contained in:
Marty Fuhry 2024-02-27 09:34:44 -05:00
parent ef2f605635
commit 45d4984fde
No known key found for this signature in database
GPG key ID: E2AB6392D894D900
4 changed files with 109 additions and 63 deletions

View file

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/ui/hooks/blurhash_hook.dart';
class BlurhashThumb extends HookWidget {
final double height;
final double width;
final Asset asset;
final EdgeInsets margin;
const BlurhashThumb({
super.key,
required this.height,
required this.width,
required this.asset,
required this.margin,
});
@override
Widget build(BuildContext context) {
final blurhash = useBlurHashRef(asset).value;
if (blurhash == null) {
return SizedBox(
height: height,
width: width,
);
}
return Padding(
padding: margin,
child: Image.memory(
blurhash,
gaplessPlayback: true,
frameBuilder: (
BuildContext context,
Widget child,
int? frame,
bool wasSynchronouslyLoaded,
) {
if (wasSynchronouslyLoaded) {
return child;
}
return AnimatedSwitcher(
duration: const Duration(milliseconds: 100),
child: frame != null
? child
: SizedBox(
height: height,
width: width,
),
);
},
fit: BoxFit.cover,
height: height,
width: width,
),
);
}
}

View file

@ -1,4 +1,5 @@
import 'dart:collection';
import 'dart:convert';
import 'dart:developer';
import 'dart:math';
@ -6,12 +7,15 @@ import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/collection_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/blurhash_thumb.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_placeholder.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/ui/hooks/blurhash_hook.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'asset_grid_data_structure.dart';
@ -325,32 +329,33 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
}
/// A single row of all placeholder widgets
class _PlaceholderRow extends StatelessWidget {
final int number;
class _PlaceholderRow extends HookWidget {
final double width;
final double height;
final double margin;
final List<Asset> assets;
const _PlaceholderRow({
super.key,
required this.number,
required this.width,
required this.height,
required this.margin,
required this.assets,
});
@override
Widget build(BuildContext context) {
return Row(
children: [
for (int i = 0; i < number; i++)
ThumbnailPlaceholder(
for (int i = 0; i < assets.length; i++)
BlurhashThumb(
key: ValueKey(i),
asset: assets[i],
width: width,
height: height,
margin: EdgeInsets.only(
bottom: margin,
right: i + 1 == number ? 0.0 : margin,
right: i + 1 == assets.length ? 0.0 : margin,
),
),
],
@ -401,9 +406,9 @@ class _Section extends StatelessWidget {
final width = constraints.maxWidth / assetsPerRow -
margin * (assetsPerRow - 1) / assetsPerRow;
final rows = (section.count + assetsPerRow - 1) ~/ assetsPerRow;
final List<Asset> assetsToRender = scrolling
? []
: renderList.loadAssets(section.offset, section.count);
final List<Asset> assetsToRender = //scrolling
//? []
renderList.loadAssets(section.offset, section.count);
return Column(
key: ValueKey(section.offset),
crossAxisAlignment: CrossAxisAlignment.start,
@ -422,18 +427,22 @@ class _Section extends StatelessWidget {
selectAssets: selectAssets,
deselectAssets: deselectAssets,
),
for (int i = 0; i < rows; i++)
scrolling
? _PlaceholderRow(
key: ValueKey(i),
number: i + 1 == rows
? section.count - i * assetsPerRow
: assetsPerRow,
width: width,
height: width,
margin: margin,
)
: _AssetRow(
Stack(
children: [
for (int i = 0; i < rows; i++)
_PlaceholderRow(
key: ValueKey('placeholder-$i'),
assets: assetsToRender.nestedSlice(
i * assetsPerRow,
min((i + 1) * assetsPerRow, section.count),
),
width: width,
height: width,
margin: margin,
),
if (!scrolling)
for (int i = 0; i < rows; i++)
_AssetRow(
key: ValueKey(i),
assets: assetsToRender.nestedSlice(
i * assetsPerRow,
@ -454,6 +463,8 @@ class _Section extends StatelessWidget {
onSelect: (asset) => selectAssets([asset]),
onDeselect: (asset) => deselectAssets([asset]),
),
],
),
],
);
},

View file

@ -23,8 +23,7 @@ OctoPlaceholderBuilder blurHashPlaceholderBuilder(
}) {
return (context) => blurhash == null
? const ThumbnailPlaceholder()
: FadeInPlaceholderImage(
placeholder: const ThumbnailPlaceholder(),
: Image(
image: MemoryImage(blurhash),
fit: fit ?? BoxFit.cover,
);

View file

@ -413,10 +413,10 @@ packages:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
version: "6.1.4"
file_selector_linux:
dependency: transitive
description:
@ -860,30 +860,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.8.1"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
@ -931,18 +907,18 @@ packages:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.5.0"
meta:
dependency: "direct overridden"
description:
@ -1026,10 +1002,10 @@ packages:
dependency: "direct main"
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.8.3"
path_provider:
dependency: "direct main"
description:
@ -1162,10 +1138,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
url: "https://pub.dev"
source: hosted
version: "3.1.4"
version: "3.1.2"
plugin_platform_interface:
dependency: transitive
description:
@ -1194,10 +1170,10 @@ packages:
dependency: transitive
description:
name: process
sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32"
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "4.2.4"
provider:
dependency: transitive
description:
@ -1663,10 +1639,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583
url: "https://pub.dev"
source: hosted
version: "13.0.0"
version: "11.10.0"
wakelock_plus:
dependency: "direct main"
description:
@ -1711,10 +1687,10 @@ packages:
dependency: transitive
description:
name: webdriver
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
version: "3.0.2"
win32:
dependency: transitive
description: