mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	fix(mobile): stack count reset when navigating to library (#4647)
Co-authored-by: shalong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									cb0e37e76e
								
							
						
					
					
						commit
						b49b10141e
					
				
							
								
								
									
										2
									
								
								cli/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								cli/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							@ -771,7 +771,7 @@ export interface AssetResponseDto {
 | 
				
			|||||||
     * @type {number}
 | 
					     * @type {number}
 | 
				
			||||||
     * @memberof AssetResponseDto
 | 
					     * @memberof AssetResponseDto
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    'stackCount': number;
 | 
					    'stackCount': number | null;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 
 | 
					     * 
 | 
				
			||||||
     * @type {string}
 | 
					     * @type {string}
 | 
				
			||||||
 | 
				
			|||||||
@ -83,7 +83,7 @@ class GalleryViewerPage extends HookConsumerWidget {
 | 
				
			|||||||
        navStack.length > 2 &&
 | 
					        navStack.length > 2 &&
 | 
				
			||||||
        navStack.elementAt(navStack.length - 2).name == TrashRoute.name;
 | 
					        navStack.elementAt(navStack.length - 2).name == TrashRoute.name;
 | 
				
			||||||
    final stackIndex = useState(-1);
 | 
					    final stackIndex = useState(-1);
 | 
				
			||||||
    final stack = showStack && currentAsset.stackCount > 0
 | 
					    final stack = showStack && currentAsset.stackChildrenCount > 0
 | 
				
			||||||
        ? ref.watch(assetStackStateProvider(currentAsset))
 | 
					        ? ref.watch(assetStackStateProvider(currentAsset))
 | 
				
			||||||
        : <Asset>[];
 | 
					        : <Asset>[];
 | 
				
			||||||
    final stackElements = showStack ? [currentAsset, ...stack] : <Asset>[];
 | 
					    final stackElements = showStack ? [currentAsset, ...stack] : <Asset>[];
 | 
				
			||||||
 | 
				
			|||||||
@ -104,16 +104,16 @@ class ThumbnailImage extends StatelessWidget {
 | 
				
			|||||||
        right: 5,
 | 
					        right: 5,
 | 
				
			||||||
        child: Row(
 | 
					        child: Row(
 | 
				
			||||||
          children: [
 | 
					          children: [
 | 
				
			||||||
            if (asset.stackCount > 1)
 | 
					            if (asset.stackChildrenCount > 1)
 | 
				
			||||||
              Text(
 | 
					              Text(
 | 
				
			||||||
                "${asset.stackCount}",
 | 
					                "${asset.stackChildrenCount}",
 | 
				
			||||||
                style: const TextStyle(
 | 
					                style: const TextStyle(
 | 
				
			||||||
                  color: Colors.white,
 | 
					                  color: Colors.white,
 | 
				
			||||||
                  fontSize: 10,
 | 
					                  fontSize: 10,
 | 
				
			||||||
                  fontWeight: FontWeight.bold,
 | 
					                  fontWeight: FontWeight.bold,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
            if (asset.stackCount > 1)
 | 
					            if (asset.stackChildrenCount > 1)
 | 
				
			||||||
              const SizedBox(
 | 
					              const SizedBox(
 | 
				
			||||||
                width: 3,
 | 
					                width: 3,
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
@ -233,7 +233,7 @@ class ThumbnailImage extends StatelessWidget {
 | 
				
			|||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          if (!asset.isImage) buildVideoIcon(),
 | 
					          if (!asset.isImage) buildVideoIcon(),
 | 
				
			||||||
          if (asset.isImage && asset.stackCount > 0) buildStackIcon(),
 | 
					          if (asset.isImage && asset.stackChildrenCount > 0) buildStackIcon(),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
@ -153,7 +153,10 @@ class Asset {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  String? stackParentId;
 | 
					  String? stackParentId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int stackCount;
 | 
					  @ignore
 | 
				
			||||||
 | 
					  int get stackChildrenCount => stackCount ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int? stackCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// `true` if this [Asset] is present on the device
 | 
					  /// `true` if this [Asset] is present on the device
 | 
				
			||||||
  @ignore
 | 
					  @ignore
 | 
				
			||||||
@ -253,7 +256,11 @@ class Asset {
 | 
				
			|||||||
        isFavorite != a.isFavorite ||
 | 
					        isFavorite != a.isFavorite ||
 | 
				
			||||||
        isArchived != a.isArchived ||
 | 
					        isArchived != a.isArchived ||
 | 
				
			||||||
        isTrashed != a.isTrashed ||
 | 
					        isTrashed != a.isTrashed ||
 | 
				
			||||||
        stackCount != a.stackCount;
 | 
					        // no local stack count or different count from remote
 | 
				
			||||||
 | 
					        ((stackCount == null && a.stackCount != null) ||
 | 
				
			||||||
 | 
					            (stackCount != null &&
 | 
				
			||||||
 | 
					                a.stackCount != null &&
 | 
				
			||||||
 | 
					                stackCount != a.stackCount));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Returns a new [Asset] with values from this and merged & updated with [a]
 | 
					  /// Returns a new [Asset] with values from this and merged & updated with [a]
 | 
				
			||||||
@ -269,6 +276,7 @@ class Asset {
 | 
				
			|||||||
          width: a.width ?? width,
 | 
					          width: a.width ?? width,
 | 
				
			||||||
          height: a.height ?? height,
 | 
					          height: a.height ?? height,
 | 
				
			||||||
          exifInfo: a.exifInfo?.copyWith(id: id) ?? exifInfo,
 | 
					          exifInfo: a.exifInfo?.copyWith(id: id) ?? exifInfo,
 | 
				
			||||||
 | 
					          stackCount: a.stackCount ?? stackCount,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      } else if (isRemote) {
 | 
					      } else if (isRemote) {
 | 
				
			||||||
        return _copyWith(
 | 
					        return _copyWith(
 | 
				
			||||||
@ -299,7 +307,7 @@ class Asset {
 | 
				
			|||||||
          height: a.height,
 | 
					          height: a.height,
 | 
				
			||||||
          livePhotoVideoId: a.livePhotoVideoId,
 | 
					          livePhotoVideoId: a.livePhotoVideoId,
 | 
				
			||||||
          stackParentId: a.stackParentId,
 | 
					          stackParentId: a.stackParentId,
 | 
				
			||||||
          stackCount: a.stackCount,
 | 
					          stackCount: a.stackCount ?? stackCount,
 | 
				
			||||||
          // isFavorite + isArchived are not set by device-only assets
 | 
					          // isFavorite + isArchived are not set by device-only assets
 | 
				
			||||||
          isFavorite: a.isFavorite,
 | 
					          isFavorite: a.isFavorite,
 | 
				
			||||||
          isArchived: a.isArchived,
 | 
					          isArchived: a.isArchived,
 | 
				
			||||||
 | 
				
			|||||||
@ -250,7 +250,7 @@ Asset _assetDeserialize(
 | 
				
			|||||||
    localId: reader.readStringOrNull(offsets[10]),
 | 
					    localId: reader.readStringOrNull(offsets[10]),
 | 
				
			||||||
    ownerId: reader.readLong(offsets[11]),
 | 
					    ownerId: reader.readLong(offsets[11]),
 | 
				
			||||||
    remoteId: reader.readStringOrNull(offsets[12]),
 | 
					    remoteId: reader.readStringOrNull(offsets[12]),
 | 
				
			||||||
    stackCount: reader.readLong(offsets[13]),
 | 
					    stackCount: reader.readLongOrNull(offsets[13]),
 | 
				
			||||||
    stackParentId: reader.readStringOrNull(offsets[14]),
 | 
					    stackParentId: reader.readStringOrNull(offsets[14]),
 | 
				
			||||||
    type: _AssettypeValueEnumMap[reader.readByteOrNull(offsets[15])] ??
 | 
					    type: _AssettypeValueEnumMap[reader.readByteOrNull(offsets[15])] ??
 | 
				
			||||||
        AssetType.other,
 | 
					        AssetType.other,
 | 
				
			||||||
@ -294,7 +294,7 @@ P _assetDeserializeProp<P>(
 | 
				
			|||||||
    case 12:
 | 
					    case 12:
 | 
				
			||||||
      return (reader.readStringOrNull(offset)) as P;
 | 
					      return (reader.readStringOrNull(offset)) as P;
 | 
				
			||||||
    case 13:
 | 
					    case 13:
 | 
				
			||||||
      return (reader.readLong(offset)) as P;
 | 
					      return (reader.readLongOrNull(offset)) as P;
 | 
				
			||||||
    case 14:
 | 
					    case 14:
 | 
				
			||||||
      return (reader.readStringOrNull(offset)) as P;
 | 
					      return (reader.readStringOrNull(offset)) as P;
 | 
				
			||||||
    case 15:
 | 
					    case 15:
 | 
				
			||||||
@ -1825,8 +1825,24 @@ extension AssetQueryFilter on QueryBuilder<Asset, Asset, QFilterCondition> {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountIsNull() {
 | 
				
			||||||
 | 
					    return QueryBuilder.apply(this, (query) {
 | 
				
			||||||
 | 
					      return query.addFilterCondition(const FilterCondition.isNull(
 | 
				
			||||||
 | 
					        property: r'stackCount',
 | 
				
			||||||
 | 
					      ));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountIsNotNull() {
 | 
				
			||||||
 | 
					    return QueryBuilder.apply(this, (query) {
 | 
				
			||||||
 | 
					      return query.addFilterCondition(const FilterCondition.isNotNull(
 | 
				
			||||||
 | 
					        property: r'stackCount',
 | 
				
			||||||
 | 
					      ));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountEqualTo(
 | 
					  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountEqualTo(
 | 
				
			||||||
      int value) {
 | 
					      int? value) {
 | 
				
			||||||
    return QueryBuilder.apply(this, (query) {
 | 
					    return QueryBuilder.apply(this, (query) {
 | 
				
			||||||
      return query.addFilterCondition(FilterCondition.equalTo(
 | 
					      return query.addFilterCondition(FilterCondition.equalTo(
 | 
				
			||||||
        property: r'stackCount',
 | 
					        property: r'stackCount',
 | 
				
			||||||
@ -1836,7 +1852,7 @@ extension AssetQueryFilter on QueryBuilder<Asset, Asset, QFilterCondition> {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountGreaterThan(
 | 
					  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountGreaterThan(
 | 
				
			||||||
    int value, {
 | 
					    int? value, {
 | 
				
			||||||
    bool include = false,
 | 
					    bool include = false,
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
    return QueryBuilder.apply(this, (query) {
 | 
					    return QueryBuilder.apply(this, (query) {
 | 
				
			||||||
@ -1849,7 +1865,7 @@ extension AssetQueryFilter on QueryBuilder<Asset, Asset, QFilterCondition> {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountLessThan(
 | 
					  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountLessThan(
 | 
				
			||||||
    int value, {
 | 
					    int? value, {
 | 
				
			||||||
    bool include = false,
 | 
					    bool include = false,
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
    return QueryBuilder.apply(this, (query) {
 | 
					    return QueryBuilder.apply(this, (query) {
 | 
				
			||||||
@ -1862,8 +1878,8 @@ extension AssetQueryFilter on QueryBuilder<Asset, Asset, QFilterCondition> {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountBetween(
 | 
					  QueryBuilder<Asset, Asset, QAfterFilterCondition> stackCountBetween(
 | 
				
			||||||
    int lower,
 | 
					    int? lower,
 | 
				
			||||||
    int upper, {
 | 
					    int? upper, {
 | 
				
			||||||
    bool includeLower = true,
 | 
					    bool includeLower = true,
 | 
				
			||||||
    bool includeUpper = true,
 | 
					    bool includeUpper = true,
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
@ -2854,7 +2870,7 @@ extension AssetQueryProperty on QueryBuilder<Asset, Asset, QQueryProperty> {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QueryBuilder<Asset, int, QQueryOperations> stackCountProperty() {
 | 
					  QueryBuilder<Asset, int?, QQueryOperations> stackCountProperty() {
 | 
				
			||||||
    return QueryBuilder.apply(this, (query) {
 | 
					    return QueryBuilder.apply(this, (query) {
 | 
				
			||||||
      return query.addPropertyName(r'stackCount');
 | 
					      return query.addPropertyName(r'stackCount');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								mobile/openapi/lib/model/asset_response_dto.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								mobile/openapi/lib/model/asset_response_dto.dart
									
									
									
										generated
									
									
									
								
							@ -118,7 +118,7 @@ class AssetResponseDto {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  List<AssetResponseDto> stack;
 | 
					  List<AssetResponseDto> stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int stackCount;
 | 
					  int? stackCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  String? stackParentId;
 | 
					  String? stackParentId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -194,7 +194,7 @@ class AssetResponseDto {
 | 
				
			|||||||
    (resized.hashCode) +
 | 
					    (resized.hashCode) +
 | 
				
			||||||
    (smartInfo == null ? 0 : smartInfo!.hashCode) +
 | 
					    (smartInfo == null ? 0 : smartInfo!.hashCode) +
 | 
				
			||||||
    (stack.hashCode) +
 | 
					    (stack.hashCode) +
 | 
				
			||||||
    (stackCount.hashCode) +
 | 
					    (stackCount == null ? 0 : stackCount!.hashCode) +
 | 
				
			||||||
    (stackParentId == null ? 0 : stackParentId!.hashCode) +
 | 
					    (stackParentId == null ? 0 : stackParentId!.hashCode) +
 | 
				
			||||||
    (tags.hashCode) +
 | 
					    (tags.hashCode) +
 | 
				
			||||||
    (thumbhash == null ? 0 : thumbhash!.hashCode) +
 | 
					    (thumbhash == null ? 0 : thumbhash!.hashCode) +
 | 
				
			||||||
@ -248,7 +248,11 @@ class AssetResponseDto {
 | 
				
			|||||||
    //  json[r'smartInfo'] = null;
 | 
					    //  json[r'smartInfo'] = null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
      json[r'stack'] = this.stack;
 | 
					      json[r'stack'] = this.stack;
 | 
				
			||||||
 | 
					    if (this.stackCount != null) {
 | 
				
			||||||
      json[r'stackCount'] = this.stackCount;
 | 
					      json[r'stackCount'] = this.stackCount;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					    //  json[r'stackCount'] = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (this.stackParentId != null) {
 | 
					    if (this.stackParentId != null) {
 | 
				
			||||||
      json[r'stackParentId'] = this.stackParentId;
 | 
					      json[r'stackParentId'] = this.stackParentId;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -299,7 +303,7 @@ class AssetResponseDto {
 | 
				
			|||||||
        resized: mapValueOfType<bool>(json, r'resized')!,
 | 
					        resized: mapValueOfType<bool>(json, r'resized')!,
 | 
				
			||||||
        smartInfo: SmartInfoResponseDto.fromJson(json[r'smartInfo']),
 | 
					        smartInfo: SmartInfoResponseDto.fromJson(json[r'smartInfo']),
 | 
				
			||||||
        stack: AssetResponseDto.listFromJson(json[r'stack']),
 | 
					        stack: AssetResponseDto.listFromJson(json[r'stack']),
 | 
				
			||||||
        stackCount: mapValueOfType<int>(json, r'stackCount')!,
 | 
					        stackCount: mapValueOfType<int>(json, r'stackCount'),
 | 
				
			||||||
        stackParentId: mapValueOfType<String>(json, r'stackParentId'),
 | 
					        stackParentId: mapValueOfType<String>(json, r'stackParentId'),
 | 
				
			||||||
        tags: TagResponseDto.listFromJson(json[r'tags']),
 | 
					        tags: TagResponseDto.listFromJson(json[r'tags']),
 | 
				
			||||||
        thumbhash: mapValueOfType<String>(json, r'thumbhash'),
 | 
					        thumbhash: mapValueOfType<String>(json, r'thumbhash'),
 | 
				
			||||||
 | 
				
			|||||||
@ -6009,6 +6009,7 @@
 | 
				
			|||||||
            "type": "array"
 | 
					            "type": "array"
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          "stackCount": {
 | 
					          "stackCount": {
 | 
				
			||||||
 | 
					            "nullable": true,
 | 
				
			||||||
            "type": "integer"
 | 
					            "type": "integer"
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          "stackParentId": {
 | 
					          "stackParentId": {
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,7 @@ export class AssetResponseDto extends SanitizedAssetResponseDto {
 | 
				
			|||||||
  stackParentId?: string | null;
 | 
					  stackParentId?: string | null;
 | 
				
			||||||
  stack?: AssetResponseDto[];
 | 
					  stack?: AssetResponseDto[];
 | 
				
			||||||
  @ApiProperty({ type: 'integer' })
 | 
					  @ApiProperty({ type: 'integer' })
 | 
				
			||||||
  stackCount!: number;
 | 
					  stackCount!: number | null;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type AssetMapOptions = {
 | 
					export type AssetMapOptions = {
 | 
				
			||||||
@ -102,7 +102,7 @@ export function mapAsset(entity: AssetEntity, options: AssetMapOptions = {}): As
 | 
				
			|||||||
    checksum: entity.checksum.toString('base64'),
 | 
					    checksum: entity.checksum.toString('base64'),
 | 
				
			||||||
    stackParentId: entity.stackParentId,
 | 
					    stackParentId: entity.stackParentId,
 | 
				
			||||||
    stack: withStack ? entity.stack?.map((a) => mapAsset(a, { stripMetadata })) ?? undefined : undefined,
 | 
					    stack: withStack ? entity.stack?.map((a) => mapAsset(a, { stripMetadata })) ?? undefined : undefined,
 | 
				
			||||||
    stackCount: entity.stack?.length ?? 0,
 | 
					    stackCount: entity.stack?.length ?? null,
 | 
				
			||||||
    isExternal: entity.isExternal,
 | 
					    isExternal: entity.isExternal,
 | 
				
			||||||
    isOffline: entity.isOffline,
 | 
					    isOffline: entity.isOffline,
 | 
				
			||||||
    isReadOnly: entity.isReadOnly,
 | 
					    isReadOnly: entity.isReadOnly,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								web/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								web/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							@ -771,7 +771,7 @@ export interface AssetResponseDto {
 | 
				
			|||||||
     * @type {number}
 | 
					     * @type {number}
 | 
				
			||||||
     * @memberof AssetResponseDto
 | 
					     * @memberof AssetResponseDto
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    'stackCount': number;
 | 
					    'stackCount': number | null;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 
 | 
					     * 
 | 
				
			||||||
     * @type {string}
 | 
					     * @type {string}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user