mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	chore: refactor show view in timeline button (#22894)
* chore: refactor show view in timeline button This refactor includes changes to notify asset viewer about where an asset was shown from. * chore: realized I could just pull from the timelineProvider instead of storing it in the asset viewer state * chore: rename enum to TimelineOrigin and update members * fix: update isOwner condition --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
		
							parent
							
								
									d778286777
								
							
						
					
					
						commit
						b484a52252
					
				@ -16,7 +16,24 @@ typedef TimelineAssetSource = Future<List<BaseAsset>> Function(int index, int co
 | 
			
		||||
 | 
			
		||||
typedef TimelineBucketSource = Stream<List<Bucket>> Function();
 | 
			
		||||
 | 
			
		||||
typedef TimelineQuery = ({TimelineAssetSource assetSource, TimelineBucketSource bucketSource});
 | 
			
		||||
typedef TimelineQuery = ({TimelineAssetSource assetSource, TimelineBucketSource bucketSource, TimelineOrigin origin});
 | 
			
		||||
 | 
			
		||||
enum TimelineOrigin {
 | 
			
		||||
  main,
 | 
			
		||||
  localAlbum,
 | 
			
		||||
  remoteAlbum,
 | 
			
		||||
  remoteAssets,
 | 
			
		||||
  favorite,
 | 
			
		||||
  trash,
 | 
			
		||||
  archive,
 | 
			
		||||
  lockedFolder,
 | 
			
		||||
  video,
 | 
			
		||||
  place,
 | 
			
		||||
  person,
 | 
			
		||||
  map,
 | 
			
		||||
  search,
 | 
			
		||||
  deepLink,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class TimelineFactory {
 | 
			
		||||
  final DriftTimelineRepository _timelineRepository;
 | 
			
		||||
@ -57,7 +74,8 @@ class TimelineFactory {
 | 
			
		||||
  TimelineService person(String userId, String personId) =>
 | 
			
		||||
      TimelineService(_timelineRepository.person(userId, personId, groupBy));
 | 
			
		||||
 | 
			
		||||
  TimelineService fromAssets(List<BaseAsset> assets) => TimelineService(_timelineRepository.fromAssets(assets));
 | 
			
		||||
  TimelineService fromAssets(List<BaseAsset> assets, TimelineOrigin type) =>
 | 
			
		||||
      TimelineService(_timelineRepository.fromAssets(assets, type));
 | 
			
		||||
 | 
			
		||||
  TimelineService map(String userId, LatLngBounds bounds) =>
 | 
			
		||||
      TimelineService(_timelineRepository.map(userId, bounds, groupBy));
 | 
			
		||||
@ -66,6 +84,7 @@ class TimelineFactory {
 | 
			
		||||
class TimelineService {
 | 
			
		||||
  final TimelineAssetSource _assetSource;
 | 
			
		||||
  final TimelineBucketSource _bucketSource;
 | 
			
		||||
  final TimelineOrigin origin;
 | 
			
		||||
  final AsyncMutex _mutex = AsyncMutex();
 | 
			
		||||
  int _bufferOffset = 0;
 | 
			
		||||
  List<BaseAsset> _buffer = [];
 | 
			
		||||
@ -74,10 +93,14 @@ class TimelineService {
 | 
			
		||||
  int _totalAssets = 0;
 | 
			
		||||
  int get totalAssets => _totalAssets;
 | 
			
		||||
 | 
			
		||||
  TimelineService(TimelineQuery query) : this._(assetSource: query.assetSource, bucketSource: query.bucketSource);
 | 
			
		||||
  TimelineService(TimelineQuery query)
 | 
			
		||||
    : this._(assetSource: query.assetSource, bucketSource: query.bucketSource, origin: query.origin);
 | 
			
		||||
 | 
			
		||||
  TimelineService._({required TimelineAssetSource assetSource, required TimelineBucketSource bucketSource})
 | 
			
		||||
    : _assetSource = assetSource,
 | 
			
		||||
  TimelineService._({
 | 
			
		||||
    required TimelineAssetSource assetSource,
 | 
			
		||||
    required TimelineBucketSource bucketSource,
 | 
			
		||||
    required this.origin,
 | 
			
		||||
  }) : _assetSource = assetSource,
 | 
			
		||||
       _bucketSource = bucketSource {
 | 
			
		||||
    _bucketSubscription = _bucketSource().listen((buckets) {
 | 
			
		||||
      _mutex.run(() async {
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
  TimelineQuery main(List<String> userIds, GroupAssetsBy groupBy) => (
 | 
			
		||||
    bucketSource: () => _watchMainBucket(userIds, groupBy: groupBy),
 | 
			
		||||
    assetSource: (offset, count) => _getMainBucketAssets(userIds, offset: offset, count: count),
 | 
			
		||||
    origin: TimelineOrigin.main,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  Stream<List<Bucket>> _watchMainBucket(List<String> userIds, {GroupAssetsBy groupBy = GroupAssetsBy.day}) {
 | 
			
		||||
@ -91,6 +92,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
  TimelineQuery localAlbum(String albumId, GroupAssetsBy groupBy) => (
 | 
			
		||||
    bucketSource: () => _watchLocalAlbumBucket(albumId, groupBy: groupBy),
 | 
			
		||||
    assetSource: (offset, count) => _getLocalAlbumBucketAssets(albumId, offset: offset, count: count),
 | 
			
		||||
    origin: TimelineOrigin.localAlbum,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  Stream<List<Bucket>> _watchLocalAlbumBucket(String albumId, {GroupAssetsBy groupBy = GroupAssetsBy.day}) {
 | 
			
		||||
@ -156,6 +158,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
  TimelineQuery remoteAlbum(String albumId, GroupAssetsBy groupBy) => (
 | 
			
		||||
    bucketSource: () => _watchRemoteAlbumBucket(albumId, groupBy: groupBy),
 | 
			
		||||
    assetSource: (offset, count) => _getRemoteAlbumBucketAssets(albumId, offset: offset, count: count),
 | 
			
		||||
    origin: TimelineOrigin.remoteAlbum,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  Stream<List<Bucket>> _watchRemoteAlbumBucket(String albumId, {GroupAssetsBy groupBy = GroupAssetsBy.day}) {
 | 
			
		||||
@ -244,15 +247,17 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
        .get();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TimelineQuery fromAssets(List<BaseAsset> assets) => (
 | 
			
		||||
  TimelineQuery fromAssets(List<BaseAsset> assets, TimelineOrigin origin) => (
 | 
			
		||||
    bucketSource: () => Stream.value(_generateBuckets(assets.length)),
 | 
			
		||||
    assetSource: (offset, count) => Future.value(assets.skip(offset).take(count).toList(growable: false)),
 | 
			
		||||
    origin: origin,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  TimelineQuery remote(String ownerId, GroupAssetsBy groupBy) => _remoteQueryBuilder(
 | 
			
		||||
    filter: (row) =>
 | 
			
		||||
        row.deletedAt.isNull() & row.visibility.equalsValue(AssetVisibility.timeline) & row.ownerId.equals(ownerId),
 | 
			
		||||
    groupBy: groupBy,
 | 
			
		||||
    origin: TimelineOrigin.remoteAssets,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  TimelineQuery favorite(String userId, GroupAssetsBy groupBy) => _remoteQueryBuilder(
 | 
			
		||||
@ -262,11 +267,13 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
        row.ownerId.equals(userId) &
 | 
			
		||||
        row.visibility.equalsValue(AssetVisibility.timeline),
 | 
			
		||||
    groupBy: groupBy,
 | 
			
		||||
    origin: TimelineOrigin.favorite,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  TimelineQuery trash(String userId, GroupAssetsBy groupBy) => _remoteQueryBuilder(
 | 
			
		||||
    filter: (row) => row.deletedAt.isNotNull() & row.ownerId.equals(userId),
 | 
			
		||||
    groupBy: groupBy,
 | 
			
		||||
    origin: TimelineOrigin.trash,
 | 
			
		||||
    joinLocal: true,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
@ -274,11 +281,13 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
    filter: (row) =>
 | 
			
		||||
        row.deletedAt.isNull() & row.ownerId.equals(userId) & row.visibility.equalsValue(AssetVisibility.archive),
 | 
			
		||||
    groupBy: groupBy,
 | 
			
		||||
    origin: TimelineOrigin.archive,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  TimelineQuery locked(String userId, GroupAssetsBy groupBy) => _remoteQueryBuilder(
 | 
			
		||||
    filter: (row) =>
 | 
			
		||||
        row.deletedAt.isNull() & row.visibility.equalsValue(AssetVisibility.locked) & row.ownerId.equals(userId),
 | 
			
		||||
    origin: TimelineOrigin.lockedFolder,
 | 
			
		||||
    groupBy: groupBy,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
@ -288,17 +297,20 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
        row.type.equalsValue(AssetType.video) &
 | 
			
		||||
        row.visibility.equalsValue(AssetVisibility.timeline) &
 | 
			
		||||
        row.ownerId.equals(userId),
 | 
			
		||||
    origin: TimelineOrigin.video,
 | 
			
		||||
    groupBy: groupBy,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  TimelineQuery place(String place, GroupAssetsBy groupBy) => (
 | 
			
		||||
    bucketSource: () => _watchPlaceBucket(place, groupBy: groupBy),
 | 
			
		||||
    assetSource: (offset, count) => _getPlaceBucketAssets(place, offset: offset, count: count),
 | 
			
		||||
    origin: TimelineOrigin.place,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  TimelineQuery person(String userId, String personId, GroupAssetsBy groupBy) => (
 | 
			
		||||
    bucketSource: () => _watchPersonBucket(userId, personId, groupBy: groupBy),
 | 
			
		||||
    assetSource: (offset, count) => _getPersonBucketAssets(userId, personId, offset: offset, count: count),
 | 
			
		||||
    origin: TimelineOrigin.person,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  Stream<List<Bucket>> _watchPlaceBucket(String place, {GroupAssetsBy groupBy = GroupAssetsBy.day}) {
 | 
			
		||||
@ -434,6 +446,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
  TimelineQuery map(String userId, LatLngBounds bounds, GroupAssetsBy groupBy) => (
 | 
			
		||||
    bucketSource: () => _watchMapBucket(userId, bounds, groupBy: groupBy),
 | 
			
		||||
    assetSource: (offset, count) => _getMapBucketAssets(userId, bounds, offset: offset, count: count),
 | 
			
		||||
    origin: TimelineOrigin.map,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  Stream<List<Bucket>> _watchMapBucket(
 | 
			
		||||
@ -502,6 +515,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
  @pragma('vm:prefer-inline')
 | 
			
		||||
  TimelineQuery _remoteQueryBuilder({
 | 
			
		||||
    required Expression<bool> Function($RemoteAssetEntityTable row) filter,
 | 
			
		||||
    required TimelineOrigin origin,
 | 
			
		||||
    GroupAssetsBy groupBy = GroupAssetsBy.day,
 | 
			
		||||
    bool joinLocal = false,
 | 
			
		||||
  }) {
 | 
			
		||||
@ -509,6 +523,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
 | 
			
		||||
      bucketSource: () => _watchRemoteBucket(filter: filter, groupBy: groupBy),
 | 
			
		||||
      assetSource: (offset, count) =>
 | 
			
		||||
          _getRemoteAssets(filter: filter, offset: offset, count: count, joinLocal: joinLocal),
 | 
			
		||||
      origin: origin,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
			
		||||
import 'package:immich_mobile/constants/enums.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/person.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
 | 
			
		||||
import 'package:immich_mobile/entities/asset.entity.dart';
 | 
			
		||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
 | 
			
		||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
 | 
			
		||||
@ -624,7 +625,7 @@ class _SearchResultGrid extends ConsumerWidget {
 | 
			
		||||
        child: ProviderScope(
 | 
			
		||||
          overrides: [
 | 
			
		||||
            timelineServiceProvider.overrideWith((ref) {
 | 
			
		||||
              final timelineService = ref.watch(timelineFactoryProvider).fromAssets(assets);
 | 
			
		||||
              final timelineService = ref.watch(timelineFactoryProvider).fromAssets(assets, TimelineOrigin.search);
 | 
			
		||||
              ref.onDispose(timelineService.dispose);
 | 
			
		||||
              return timelineService;
 | 
			
		||||
            }),
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
			
		||||
import 'package:immich_mobile/constants/enums.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/utils/event_stream.dart';
 | 
			
		||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
 | 
			
		||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
 | 
			
		||||
@ -17,8 +18,8 @@ import 'package:immich_mobile/providers/cast.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/routes.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/tab.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/user.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/routing/router.dart';
 | 
			
		||||
 | 
			
		||||
@ -39,13 +40,13 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget {
 | 
			
		||||
    final isInLockedView = ref.watch(inLockedViewProvider);
 | 
			
		||||
    final isReadonlyModeEnabled = ref.watch(readonlyModeProvider);
 | 
			
		||||
 | 
			
		||||
    final previousRouteName = ref.watch(previousRouteNameProvider);
 | 
			
		||||
    final tabRoute = ref.watch(tabProvider);
 | 
			
		||||
    final timelineOrigin = ref.read(timelineServiceProvider).origin;
 | 
			
		||||
    final showViewInTimelineButton =
 | 
			
		||||
        (previousRouteName != TabShellRoute.name || tabRoute == TabEnum.search) &&
 | 
			
		||||
        previousRouteName != AssetViewerRoute.name &&
 | 
			
		||||
        previousRouteName != null &&
 | 
			
		||||
        previousRouteName != LocalTimelineRoute.name &&
 | 
			
		||||
        timelineOrigin != TimelineOrigin.main &&
 | 
			
		||||
        timelineOrigin != TimelineOrigin.deepLink &&
 | 
			
		||||
        timelineOrigin != TimelineOrigin.trash &&
 | 
			
		||||
        timelineOrigin != TimelineOrigin.archive &&
 | 
			
		||||
        timelineOrigin != TimelineOrigin.localAlbum &&
 | 
			
		||||
        isOwner;
 | 
			
		||||
 | 
			
		||||
    final isShowingSheet = ref.watch(assetViewerProvider.select((state) => state.showingBottomSheet));
 | 
			
		||||
 | 
			
		||||
@ -8,8 +8,8 @@ import 'package:immich_mobile/entities/store.entity.dart';
 | 
			
		||||
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.page.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/album/current_album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart' as beta_asset_provider;
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart' as beta_asset_provider;
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
 | 
			
		||||
@ -150,7 +150,10 @@ class DeepLinkService {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      AssetViewer.setAsset(ref, asset);
 | 
			
		||||
      return AssetViewerRoute(initialIndex: 0, timelineService: _betaTimelineFactory.fromAssets([asset]));
 | 
			
		||||
      return AssetViewerRoute(
 | 
			
		||||
        initialIndex: 0,
 | 
			
		||||
        timelineService: _betaTimelineFactory.fromAssets([asset], TimelineOrigin.deepLink),
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      // TODO: Remove this when beta is default
 | 
			
		||||
      final asset = await _assetService.getAssetByRemoteId(assetId);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user