feat: birthday memory on mobile (#32113) * feat: birthday memory on mobile * chore: remove yellow bg colors * pr feedback (cherry picked from commit 82cfc4b28b55c660d9c2da00c57437a20585a47b) Co-authored-by: Alex <alex.tran1502@gmail.com>
102 lines
3.9 KiB
Dart
102 lines
3.9 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:auto_route/auto_route.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
|
import 'package:immich_mobile/generated/translations.g.dart';
|
|
import 'package:immich_mobile/presentation/pages/memory.page.dart';
|
|
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
|
import 'package:immich_mobile/presentation/widgets/memory/memory_title.widget.dart';
|
|
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
|
|
import 'package:immich_mobile/routing/router.dart';
|
|
|
|
@RoutePage()
|
|
class MemoryListPage extends ConsumerStatefulWidget {
|
|
const MemoryListPage({super.key});
|
|
|
|
@override
|
|
ConsumerState<MemoryListPage> createState() => _MemoryListPageState();
|
|
}
|
|
|
|
class _MemoryListPageState extends ConsumerState<MemoryListPage> {
|
|
bool _onlyFavorites = false;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final memories = ref.watch(allMemoriesProvider(_onlyFavorites));
|
|
|
|
return LayoutBuilder(
|
|
builder: (context, constraints) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(context.t.memories),
|
|
actions: [
|
|
IconButton(
|
|
icon: Icon(_onlyFavorites ? Icons.favorite : Icons.favorite_outline),
|
|
onPressed: () {
|
|
setState(() => _onlyFavorites = !_onlyFavorites);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
body: SafeArea(
|
|
child: memories.widgetWhen(
|
|
onData: (memories) {
|
|
return GridView.builder(
|
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: constraints.maxWidth > 600 ? 4 : 2,
|
|
childAspectRatio: 0.5625,
|
|
mainAxisSpacing: 16,
|
|
crossAxisSpacing: 16,
|
|
),
|
|
padding: const EdgeInsets.all(16),
|
|
itemCount: memories.length,
|
|
itemBuilder: (context, index) => GestureDetector(
|
|
onTap: () {
|
|
MemoryPage.setMemory(ref, memories[index]);
|
|
unawaited(context.pushRoute(MemoryRoute(memories: memories, memoryIndex: index)));
|
|
},
|
|
child: Stack(
|
|
children: [
|
|
ClipRRect(
|
|
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
|
child: ColorFiltered(
|
|
colorFilter: ColorFilter.mode(Colors.black.withValues(alpha: 0.2), BlendMode.darken),
|
|
child: AbsorbPointer(
|
|
child: Thumbnail.remote(
|
|
remoteId: memories[index].assets[0].id,
|
|
thumbhash: memories[index].assets[0].thumbHash ?? "",
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Positioned(
|
|
bottom: 16,
|
|
left: 16,
|
|
right: 16,
|
|
child: MemoryTitle(
|
|
memory: memories[index],
|
|
style: const TextStyle(fontWeight: FontWeight.w600, color: Colors.white, fontSize: 15),
|
|
),
|
|
),
|
|
if (memories[index].isSaved)
|
|
const Positioned(
|
|
top: 16,
|
|
right: 16,
|
|
child: Icon(Icons.favorite, color: Colors.white, size: 24),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|