mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
feat(mobile): drift archive page (#19740)
* feat(mobile): drift archive page * fix: lint * feat: include local indicator * remove join in bucket * remove showing local indicator in bucket --------- Co-authored-by: Alex <alex.tran1502@gmail.com> Co-authored-by: alex <alex@localhost-live.localdomain>
This commit is contained in:
parent
d5923241b5
commit
56756baea2
@ -53,6 +53,13 @@ class TimelineFactory {
|
||||
bucketSource: () =>
|
||||
_timelineRepository.watchRemoteBucket(albumId, groupBy: groupBy),
|
||||
);
|
||||
|
||||
TimelineService archive(String userId) => TimelineService(
|
||||
assetSource: (offset, count) => _timelineRepository
|
||||
.getArchiveBucketAssets(userId, offset: offset, count: count),
|
||||
bucketSource: () =>
|
||||
_timelineRepository.watchArchiveBucket(userId, groupBy: groupBy),
|
||||
);
|
||||
}
|
||||
|
||||
class TimelineService {
|
||||
|
@ -213,6 +213,58 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
|
||||
.map((row) => row.readTable(_db.remoteAssetEntity).toDto())
|
||||
.get();
|
||||
}
|
||||
|
||||
Stream<List<Bucket>> watchArchiveBucket(
|
||||
String userId, {
|
||||
GroupAssetsBy groupBy = GroupAssetsBy.day,
|
||||
}) {
|
||||
if (groupBy == GroupAssetsBy.none) {
|
||||
return _db.remoteAssetEntity
|
||||
.count(
|
||||
where: (row) =>
|
||||
row.visibility.equalsValue(AssetVisibility.archive) &
|
||||
row.ownerId.equals(userId),
|
||||
)
|
||||
.map(_generateBuckets)
|
||||
.watchSingle();
|
||||
}
|
||||
|
||||
final assetCountExp = _db.remoteAssetEntity.id.count();
|
||||
final dateExp = _db.remoteAssetEntity.createdAt.dateFmt(groupBy);
|
||||
|
||||
final query = _db.remoteAssetEntity.selectOnly()
|
||||
..addColumns([assetCountExp, dateExp])
|
||||
..where(
|
||||
_db.remoteAssetEntity.ownerId.equals(userId) &
|
||||
_db.remoteAssetEntity.visibility
|
||||
.equalsValue(AssetVisibility.archive),
|
||||
)
|
||||
..groupBy([dateExp])
|
||||
..orderBy([OrderingTerm.desc(dateExp)]);
|
||||
|
||||
return query.map((row) {
|
||||
final timeline = row.read(dateExp)!.dateFmt(groupBy);
|
||||
final assetCount = row.read(assetCountExp)!;
|
||||
return TimeBucket(date: timeline, assetCount: assetCount);
|
||||
}).watch();
|
||||
}
|
||||
|
||||
Future<List<BaseAsset>> getArchiveBucketAssets(
|
||||
String userId, {
|
||||
required int offset,
|
||||
required int count,
|
||||
}) {
|
||||
final query = _db.remoteAssetEntity.select()
|
||||
..where(
|
||||
(row) =>
|
||||
row.ownerId.equals(userId) &
|
||||
row.visibility.equalsValue(AssetVisibility.archive),
|
||||
)
|
||||
..orderBy([(row) => OrderingTerm.desc(row.createdAt)])
|
||||
..limit(count, offset: offset);
|
||||
|
||||
return query.map((row) => row.toDto()).get();
|
||||
}
|
||||
}
|
||||
|
||||
extension on Expression<DateTime> {
|
||||
|
33
mobile/lib/presentation/pages/dev/drift_archive.page.dart
Normal file
33
mobile/lib/presentation/pages/dev/drift_archive.page.dart
Normal file
@ -0,0 +1,33 @@
|
||||
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';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
|
||||
@RoutePage()
|
||||
class DriftArchivePage extends StatelessWidget {
|
||||
const DriftArchivePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ProviderScope(
|
||||
overrides: [
|
||||
timelineServiceProvider.overrideWith(
|
||||
(ref) {
|
||||
final user = ref.watch(currentUserProvider);
|
||||
if (user == null) {
|
||||
throw Exception('User must be logged in to access archive');
|
||||
}
|
||||
|
||||
final timelineService =
|
||||
ref.watch(timelineFactoryProvider).archive(user.id);
|
||||
ref.onDispose(timelineService.dispose);
|
||||
return timelineService;
|
||||
},
|
||||
),
|
||||
],
|
||||
child: const Timeline(),
|
||||
);
|
||||
}
|
||||
}
|
@ -99,6 +99,11 @@ final _features = [
|
||||
icon: Icons.timeline_rounded,
|
||||
onTap: (ctx, _) => ctx.pushRoute(const TabShellRoute()),
|
||||
),
|
||||
_Feature(
|
||||
name: 'Archive',
|
||||
icon: Icons.archive_outlined,
|
||||
onTap: (ctx, _) => ctx.pushRoute(const DriftArchiveRoute()),
|
||||
),
|
||||
];
|
||||
|
||||
@RoutePage()
|
||||
|
@ -66,6 +66,7 @@ import 'package:immich_mobile/pages/search/person_result.page.dart';
|
||||
import 'package:immich_mobile/pages/search/recently_taken.page.dart';
|
||||
import 'package:immich_mobile/pages/search/search.page.dart';
|
||||
import 'package:immich_mobile/pages/share_intent/share_intent.page.dart';
|
||||
import 'package:immich_mobile/presentation/pages/dev/drift_archive.page.dart';
|
||||
import 'package:immich_mobile/presentation/pages/dev/feat_in_development.page.dart';
|
||||
import 'package:immich_mobile/presentation/pages/dev/local_timeline.page.dart';
|
||||
import 'package:immich_mobile/presentation/pages/dev/main_timeline.page.dart';
|
||||
@ -392,7 +393,10 @@ class AppRouter extends RootStackRouter {
|
||||
page: DriftMemoryRoute.page,
|
||||
guards: [_authGuard, _duplicateGuard],
|
||||
),
|
||||
|
||||
AutoRoute(
|
||||
page: DriftArchiveRoute.page,
|
||||
guards: [_authGuard, _duplicateGuard],
|
||||
),
|
||||
// required to handle all deeplinks in deep_link.service.dart
|
||||
// auto_route_library#1722
|
||||
RedirectRoute(path: '*', redirectTo: '/'),
|
||||
|
@ -618,6 +618,22 @@ class DriftAlbumsRoute extends PageRouteInfo<void> {
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [DriftArchivePage]
|
||||
class DriftArchiveRoute extends PageRouteInfo<void> {
|
||||
const DriftArchiveRoute({List<PageRouteInfo>? children})
|
||||
: super(DriftArchiveRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'DriftArchiveRoute';
|
||||
|
||||
static PageInfo page = PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const DriftArchivePage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [DriftMemoryPage]
|
||||
class DriftMemoryRoute extends PageRouteInfo<DriftMemoryRouteArgs> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user