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:
shenlong 2025-06-26 19:20:39 +05:30 committed by GitHub
parent 24a4cba953
commit ea3a14ed25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 3059 additions and 100 deletions

View file

@ -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,
);
},
),
],
);
},