mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat(mobile): add album asset sync (#19522)
* feat(mobile): add album asset sync * add SyncAlbumToAssetDeleteV1 to openapi-spec * update delete queries to use where in statements * clear remote album when clear remote data * fix: bad merge * fix: bad merge * fix: _SyncAckV1 return type --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: wuzihao051119 <wuzihao051119@outlook.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
24a4cba953
commit
ea3a14ed25
39 changed files with 3059 additions and 100 deletions
|
|
@ -63,6 +63,9 @@ final _features = [
|
|||
final db = ref.read(driftProvider);
|
||||
await db.remoteAssetEntity.deleteAll();
|
||||
await db.remoteExifEntity.deleteAll();
|
||||
await db.remoteAlbumEntity.deleteAll();
|
||||
await db.remoteAlbumUserEntity.deleteAll();
|
||||
await db.remoteAlbumAssetEntity.deleteAll();
|
||||
},
|
||||
),
|
||||
_Feature(
|
||||
|
|
|
|||
|
|
@ -40,7 +40,10 @@ class _Summary extends StatelessWidget {
|
|||
} else if (snapshot.hasError) {
|
||||
subtitle = const Icon(Icons.error_rounded);
|
||||
} else {
|
||||
subtitle = Text('${snapshot.data ?? 0}');
|
||||
subtitle = Text(
|
||||
'${snapshot.data ?? 0}',
|
||||
style: ctx.textTheme.bodyLarge,
|
||||
);
|
||||
}
|
||||
return ListTile(
|
||||
leading: leading,
|
||||
|
|
@ -147,6 +150,10 @@ final _remoteStats = [
|
|||
name: 'Exif Entities',
|
||||
load: (db) => db.managers.remoteExifEntity.count(),
|
||||
),
|
||||
_Stat(
|
||||
name: 'Remote Albums',
|
||||
load: (db) => db.managers.remoteAlbumEntity.count(),
|
||||
),
|
||||
];
|
||||
|
||||
@RoutePage()
|
||||
|
|
@ -160,6 +167,7 @@ class RemoteMediaSummaryPage extends StatelessWidget {
|
|||
body: Consumer(
|
||||
builder: (ctx, ref, __) {
|
||||
final db = ref.watch(driftProvider);
|
||||
final albumsFuture = ref.watch(remoteAlbumRepository).getAll();
|
||||
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
|
|
@ -171,6 +179,49 @@ class RemoteMediaSummaryPage extends StatelessWidget {
|
|||
},
|
||||
itemCount: _remoteStats.length,
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Text(
|
||||
"Album summary",
|
||||
style: ctx.textTheme.titleMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
FutureBuilder(
|
||||
future: albumsFuture,
|
||||
builder: (_, snap) {
|
||||
final albums = snap.data ?? [];
|
||||
if (albums.isEmpty) {
|
||||
return const SliverToBoxAdapter(child: SizedBox.shrink());
|
||||
}
|
||||
|
||||
albums.sortBy((a) => a.name);
|
||||
return SliverList.builder(
|
||||
itemBuilder: (_, index) {
|
||||
final album = albums[index];
|
||||
final countFuture = db.managers.remoteAlbumAssetEntity
|
||||
.filter((f) => f.albumId.id.equals(album.id))
|
||||
.count();
|
||||
return _Summary(
|
||||
leading: const Icon(Icons.photo_album_rounded),
|
||||
name: album.name,
|
||||
countFuture: countFuture,
|
||||
onTap: () => context.router.push(
|
||||
RemoteTimelineRoute(albumId: album.id),
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: albums.length,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
|
|||
32
mobile/lib/presentation/pages/dev/remote_timeline.page.dart
Normal file
32
mobile/lib/presentation/pages/dev/remote_timeline.page.dart
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/presentation/widgets/timeline/timeline.widget.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
|
||||
@RoutePage()
|
||||
class RemoteTimelinePage extends StatelessWidget {
|
||||
final String albumId;
|
||||
|
||||
const RemoteTimelinePage({super.key, required this.albumId});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ProviderScope(
|
||||
overrides: [
|
||||
timelineServiceProvider.overrideWith(
|
||||
(ref) {
|
||||
final timelineService = ref
|
||||
.watch(timelineFactoryProvider)
|
||||
.remoteAlbum(albumId: albumId);
|
||||
ref.onDispose(() => unawaited(timelineService.dispose()));
|
||||
return timelineService;
|
||||
},
|
||||
),
|
||||
],
|
||||
child: const Timeline(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue