import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/entities/album.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; import 'package:immich_mobile/interfaces/timeline.interface.dart'; import 'package:immich_mobile/providers/db.provider.dart'; import 'package:immich_mobile/repositories/database.repository.dart'; import 'package:immich_mobile/utils/hash.dart'; import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart'; import 'package:isar/isar.dart'; final timelineRepositoryProvider = Provider((ref) => TimelineRepository(ref.watch(dbProvider))); class TimelineRepository extends DatabaseRepository implements ITimelineRepository { TimelineRepository(super.db); @override Future> getTimelineUserIds(String id) { return db.users .filter() .inTimelineEqualTo(true) .or() .idEqualTo(id) .idProperty() .findAll(); } @override Stream> watchTimelineUsers(String id) { return db.users .filter() .inTimelineEqualTo(true) .or() .idEqualTo(id) .idProperty() .watch(); } @override Stream watchArchiveTimeline(String userId) { final query = db.assets .where() .ownerIdEqualToAnyChecksum(fastHash(userId)) .filter() .isArchivedEqualTo(true) .isTrashedEqualTo(false) .sortByFileCreatedAtDesc(); return _watchRenderList(query, GroupAssetsBy.none); } @override Stream watchFavoriteTimeline(String userId) { final query = db.assets .where() .ownerIdEqualToAnyChecksum(fastHash(userId)) .filter() .isFavoriteEqualTo(true) .isTrashedEqualTo(false) .sortByFileCreatedAtDesc(); return _watchRenderList(query, GroupAssetsBy.none); } @override Stream watchAlbumTimeline( Album album, GroupAssetsBy groupAssetByOption, ) { final query = album.assets.filter().isTrashedEqualTo(false); final withSortedOption = switch (album.sortOrder) { SortOrder.asc => query.sortByFileCreatedAt(), SortOrder.desc => query.sortByFileCreatedAtDesc(), }; return _watchRenderList(withSortedOption, groupAssetByOption); } @override Stream watchTrashTimeline(String userId) { final query = db.assets .filter() .ownerIdEqualTo(fastHash(userId)) .isTrashedEqualTo(true) .sortByFileCreatedAtDesc(); return _watchRenderList(query, GroupAssetsBy.none); } @override Stream watchAllVideosTimeline() { final query = db.assets .filter() .isArchivedEqualTo(false) .isTrashedEqualTo(false) .typeEqualTo(AssetType.video) .sortByFileCreatedAtDesc(); return _watchRenderList(query, GroupAssetsBy.none); } @override Stream watchHomeTimeline( String userId, GroupAssetsBy groupAssetByOption, ) { final query = db.assets .where() .ownerIdEqualToAnyChecksum(fastHash(userId)) .filter() .isArchivedEqualTo(false) .isTrashedEqualTo(false) .stackPrimaryAssetIdIsNull() .sortByFileCreatedAtDesc(); return _watchRenderList(query, groupAssetByOption); } @override Stream watchMultiUsersTimeline( List userIds, GroupAssetsBy groupAssetByOption, ) { final isarUserIds = userIds.map(fastHash).toList(); final query = db.assets .where() .anyOf(isarUserIds, (qb, id) => qb.ownerIdEqualToAnyChecksum(id)) .filter() .isArchivedEqualTo(false) .isTrashedEqualTo(false) .stackPrimaryAssetIdIsNull() .sortByFileCreatedAtDesc(); return _watchRenderList(query, groupAssetByOption); } @override Future getTimelineFromAssets( List assets, GroupAssetsBy getGroupByOption, ) { return RenderList.fromAssets(assets, getGroupByOption); } @override Stream watchAssetSelectionTimeline(String userId) { final query = db.assets .where() .remoteIdIsNotNull() .filter() .ownerIdEqualTo(fastHash(userId)) .isTrashedEqualTo(false) .stackPrimaryAssetIdIsNull() .sortByFileCreatedAtDesc(); return _watchRenderList(query, GroupAssetsBy.none); } Stream _watchRenderList( QueryBuilder query, GroupAssetsBy groupAssetsBy, ) async* { yield await RenderList.fromQuery(query, groupAssetsBy); await for (final _ in query.watchLazy()) { yield await RenderList.fromQuery(query, groupAssetsBy); } } }