mirror of
https://github.com/immich-app/immich.git
synced 2026-06-27 08:54:33 -07:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b6c63df1c9 | |||
| 6e1143e799 |
@@ -180,7 +180,11 @@ class _PeopleCollectionCard extends ConsumerWidget {
|
||||
mainAxisSpacing: 8,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: people.take(4).map((person) {
|
||||
return CircleAvatar(backgroundImage: RemoteImageProvider(url: getFaceThumbnailUrl(person.id)));
|
||||
return CircleAvatar(
|
||||
backgroundImage: RemoteImageProvider(
|
||||
url: getFaceThumbnailUrl(person.id, updatedAt: person.updatedAt),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -94,7 +94,9 @@ class _DriftPeopleCollectionPageState extends ConsumerState<DriftPeopleCollectio
|
||||
child: CircleAvatar(
|
||||
key: ValueKey(person.id),
|
||||
maxRadius: isTablet ? 100 / 2 : 96 / 2,
|
||||
backgroundImage: RemoteImageProvider(url: getFaceThumbnailUrl(person.id)),
|
||||
backgroundImage: RemoteImageProvider(
|
||||
url: getFaceThumbnailUrl(person.id, updatedAt: person.updatedAt),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
+3
-1
@@ -121,7 +121,9 @@ class _Avatar extends StatelessWidget {
|
||||
elevation: 3,
|
||||
child: CircleAvatar(
|
||||
maxRadius: imageSize / 2,
|
||||
backgroundImage: RemoteImageProvider(url: getFaceThumbnailUrl(person.id)),
|
||||
backgroundImage: RemoteImageProvider(
|
||||
url: getFaceThumbnailUrl(person.id, updatedAt: person.updatedAt),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -260,7 +260,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
||||
return IgnorePointer(
|
||||
child: Stack(
|
||||
children: [
|
||||
Center(child: widget.image),
|
||||
if (!_isVideoReady || widget.asset.isMotionPhoto || isCasting) Center(child: widget.image),
|
||||
if (!isCasting) ...[
|
||||
Visibility.maintain(
|
||||
visible: _isVideoReady,
|
||||
|
||||
@@ -32,5 +32,6 @@ class PersonApiRepository extends ApiRepository {
|
||||
isHidden: dto.isHidden,
|
||||
name: dto.name,
|
||||
thumbnailPath: dto.thumbnailPath,
|
||||
updatedAt: dto.updatedAt.orElse(null),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ String getPlaybackUrlForRemoteId(final String id) {
|
||||
return '${Store.get(StoreKey.serverEndpoint)}/assets/$id/video/playback?';
|
||||
}
|
||||
|
||||
String getFaceThumbnailUrl(final String personId) {
|
||||
return '${Store.get(StoreKey.serverEndpoint)}/people/$personId/thumbnail';
|
||||
String getFaceThumbnailUrl(final String personId, {DateTime? updatedAt}) {
|
||||
final url = '${Store.get(StoreKey.serverEndpoint)}/people/$personId/thumbnail';
|
||||
return updatedAt != null ? '$url?c=${updatedAt.millisecondsSinceEpoch}' : url;
|
||||
}
|
||||
|
||||
@@ -230,7 +230,9 @@ class _ExpandedBackgroundState extends ConsumerState<_ExpandedBackground> with S
|
||||
elevation: 3,
|
||||
child: CircleAvatar(
|
||||
maxRadius: 84 / 2,
|
||||
backgroundImage: RemoteImageProvider(url: getFaceThumbnailUrl(widget.person.id)),
|
||||
backgroundImage: RemoteImageProvider(
|
||||
url: getFaceThumbnailUrl(widget.person.id, updatedAt: widget.person.updatedAt),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -80,7 +80,9 @@ class PeoplePicker extends HookConsumerWidget {
|
||||
child: CircleAvatar(
|
||||
key: ValueKey(person.id),
|
||||
maxRadius: imageSize / 2,
|
||||
backgroundImage: RemoteImageProvider(url: getFaceThumbnailUrl(person.id)),
|
||||
backgroundImage: RemoteImageProvider(
|
||||
url: getFaceThumbnailUrl(person.id, updatedAt: person.updatedAt),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||
import 'package:immich_mobile/domain/services/store.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||
|
||||
void main() {
|
||||
const endpoint = 'http://localhost:3000';
|
||||
|
||||
setUpAll(() async {
|
||||
final db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(db), listenUpdates: false);
|
||||
await StoreService.I.put(StoreKey.serverEndpoint, endpoint);
|
||||
});
|
||||
|
||||
group('getFaceThumbnailUrl', () {
|
||||
test('omits the cache buster when updatedAt is null', () {
|
||||
expect(getFaceThumbnailUrl('person-1'), '$endpoint/people/person-1/thumbnail');
|
||||
});
|
||||
|
||||
test('appends the updatedAt cache buster so a changed featured photo busts the cache (#27434)', () {
|
||||
final url = getFaceThumbnailUrl('person-1', updatedAt: DateTime.fromMillisecondsSinceEpoch(1717000000000));
|
||||
expect(url, '$endpoint/people/person-1/thumbnail?c=1717000000000');
|
||||
});
|
||||
|
||||
test('a newer updatedAt yields a different url so the image cache key changes', () {
|
||||
final before = getFaceThumbnailUrl('person-1', updatedAt: DateTime.fromMillisecondsSinceEpoch(1));
|
||||
final after = getFaceThumbnailUrl('person-1', updatedAt: DateTime.fromMillisecondsSinceEpoch(2));
|
||||
expect(before, isNot(after));
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user