Skip to content

Commit 7134f93

Browse files
authored
Add ablum feature to web (immich-app#352)
* Added album page * Refactor sidebar * Added album assets count info * Added album viewer page * Refactor album sorting * Fixed incorrectly showing selected asset in album selection * Improve fetching speed with prefetch * Refactor to use ImmichThubmnail component for all * Update to the latest version of Svelte * Implement fixed app bar in album viewer * Added shared user avatar * Correctly get all owned albums, including shared
1 parent 1887b5a commit 7134f93

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2574
-993
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@ prod:
1717
docker-compose -f ./docker/docker-compose.yml up --build -V --remove-orphans
1818

1919
prod-scale:
20-
docker-compose -f ./docker/docker-compose.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans
20+
docker-compose -f ./docker/docker-compose.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans
21+
22+
api:
23+
cd ./server && npm run api:generate

mobile/lib/modules/sharing/ui/month_group_title.dart

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,16 @@ class MonthGroupTitle extends HookConsumerWidget {
9696
color: Colors.grey,
9797
),
9898
),
99-
Padding(
100-
padding: const EdgeInsets.only(left: 8.0),
101-
child: Text(
102-
_getSimplifiedMonth(),
103-
style: TextStyle(
104-
fontSize: 24,
105-
color: Theme.of(context).primaryColor,
99+
GestureDetector(
100+
onTap: _handleTitleIconClick,
101+
child: Padding(
102+
padding: const EdgeInsets.only(left: 8.0),
103+
child: Text(
104+
_getSimplifiedMonth(),
105+
style: TextStyle(
106+
fontSize: 24,
107+
color: Theme.of(context).primaryColor,
108+
),
106109
),
107110
),
108111
),

mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,21 @@ class SelectionThumbnailImage extends HookConsumerWidget {
2626
var isAlbumExist = ref.watch(assetSelectionProvider).isAlbumExist;
2727

2828
Widget _buildSelectionIcon(AssetResponseDto asset) {
29-
if (selectedAsset.contains(asset) && !isAlbumExist) {
29+
var isSelected = selectedAsset.map((item) => item.id).contains(asset.id);
30+
var isNewlySelected =
31+
newAssetsForAlbum.map((item) => item.id).contains(asset.id);
32+
33+
if (isSelected && !isAlbumExist) {
3034
return Icon(
3135
Icons.check_circle,
3236
color: Theme.of(context).primaryColor,
3337
);
34-
} else if (selectedAsset.contains(asset) && isAlbumExist) {
38+
} else if (isSelected && isAlbumExist) {
3539
return const Icon(
3640
Icons.check_circle,
3741
color: Color.fromARGB(255, 233, 233, 233),
3842
);
39-
} else if (newAssetsForAlbum.contains(asset) && isAlbumExist) {
43+
} else if (isNewlySelected && isAlbumExist) {
4044
return Icon(
4145
Icons.check_circle,
4246
color: Theme.of(context).primaryColor,
@@ -50,17 +54,21 @@ class SelectionThumbnailImage extends HookConsumerWidget {
5054
}
5155

5256
BoxBorder drawBorderColor() {
53-
if (selectedAsset.contains(asset) && !isAlbumExist) {
57+
var isSelected = selectedAsset.map((item) => item.id).contains(asset.id);
58+
var isNewlySelected =
59+
newAssetsForAlbum.map((item) => item.id).contains(asset.id);
60+
61+
if (isSelected && !isAlbumExist) {
5462
return Border.all(
5563
color: Theme.of(context).primaryColorLight,
5664
width: 10,
5765
);
58-
} else if (selectedAsset.contains(asset) && isAlbumExist) {
66+
} else if (isSelected && isAlbumExist) {
5967
return Border.all(
6068
color: const Color.fromARGB(255, 190, 190, 190),
6169
width: 10,
6270
);
63-
} else if (newAssetsForAlbum.contains(asset) && isAlbumExist) {
71+
} else if (isNewlySelected && isAlbumExist) {
6472
return Border.all(
6573
color: Theme.of(context).primaryColorLight,
6674
width: 10,
@@ -71,10 +79,15 @@ class SelectionThumbnailImage extends HookConsumerWidget {
7179

7280
return GestureDetector(
7381
onTap: () {
82+
var isSelected =
83+
selectedAsset.map((item) => item.id).contains(asset.id);
84+
var isNewlySelected =
85+
newAssetsForAlbum.map((item) => item.id).contains(asset.id);
86+
7487
if (isAlbumExist) {
7588
// Operation for existing album
76-
if (!selectedAsset.contains(asset)) {
77-
if (newAssetsForAlbum.contains(asset)) {
89+
if (!isSelected) {
90+
if (isNewlySelected) {
7891
ref
7992
.watch(assetSelectionProvider.notifier)
8093
.removeSelectedAdditionalAssets([asset]);
@@ -86,7 +99,7 @@ class SelectionThumbnailImage extends HookConsumerWidget {
8699
}
87100
} else {
88101
// Operation for new album
89-
if (selectedAsset.contains(asset)) {
102+
if (isSelected) {
90103
ref
91104
.watch(assetSelectionProvider.notifier)
92105
.removeSelectedNewAssets([asset]);

mobile/openapi/.openapi-generator/FILES

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ doc/ServerPingResponse.md
3737
doc/ServerVersionReponseDto.md
3838
doc/SignUpDto.md
3939
doc/SmartInfoResponseDto.md
40+
doc/ThumbnailFormat.md
4041
doc/UpdateAlbumDto.md
4142
doc/UpdateDeviceInfoDto.md
4243
doc/UpdateUserDto.md
@@ -90,11 +91,12 @@ lib/model/server_ping_response.dart
9091
lib/model/server_version_reponse_dto.dart
9192
lib/model/sign_up_dto.dart
9293
lib/model/smart_info_response_dto.dart
94+
lib/model/thumbnail_format.dart
9395
lib/model/update_album_dto.dart
9496
lib/model/update_device_info_dto.dart
9597
lib/model/update_user_dto.dart
9698
lib/model/user_count_response_dto.dart
9799
lib/model/user_response_dto.dart
98100
lib/model/validate_access_token_response_dto.dart
99101
pubspec.yaml
100-
test/validate_access_token_response_dto_test.dart
102+
test/thumbnail_format_test.dart

mobile/openapi/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ Class | Method | HTTP request | Description
136136
- [ServerVersionReponseDto](doc//ServerVersionReponseDto.md)
137137
- [SignUpDto](doc//SignUpDto.md)
138138
- [SmartInfoResponseDto](doc//SmartInfoResponseDto.md)
139+
- [ThumbnailFormat](doc//ThumbnailFormat.md)
139140
- [UpdateAlbumDto](doc//UpdateAlbumDto.md)
140141
- [UpdateDeviceInfoDto](doc//UpdateDeviceInfoDto.md)
141142
- [UpdateUserDto](doc//UpdateUserDto.md)

mobile/openapi/doc/AssetApi.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ This endpoint does not need any parameter.
311311
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
312312

313313
# **getAssetThumbnail**
314-
> Object getAssetThumbnail(assetId)
314+
> Object getAssetThumbnail(assetId, format)
315315
316316

317317

@@ -327,9 +327,10 @@ import 'package:openapi/api.dart';
327327
328328
final api_instance = AssetApi();
329329
final assetId = assetId_example; // String |
330+
final format = ; // ThumbnailFormat |
330331
331332
try {
332-
final result = api_instance.getAssetThumbnail(assetId);
333+
final result = api_instance.getAssetThumbnail(assetId, format);
333334
print(result);
334335
} catch (e) {
335336
print('Exception when calling AssetApi->getAssetThumbnail: $e\n');
@@ -341,6 +342,7 @@ try {
341342
Name | Type | Description | Notes
342343
------------- | ------------- | ------------- | -------------
343344
**assetId** | **String**| |
345+
**format** | [**ThumbnailFormat**](.md)| | [optional]
344346

345347
### Return type
346348

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# openapi.model.ThumbnailFormat
2+
3+
## Load the model package
4+
```dart
5+
import 'package:openapi/api.dart';
6+
```
7+
8+
## Properties
9+
Name | Type | Description | Notes
10+
------------ | ------------- | ------------- | -------------
11+
12+
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
13+
14+

mobile/openapi/lib/api.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ part 'model/server_ping_response.dart';
6464
part 'model/server_version_reponse_dto.dart';
6565
part 'model/sign_up_dto.dart';
6666
part 'model/smart_info_response_dto.dart';
67+
part 'model/thumbnail_format.dart';
6768
part 'model/update_album_dto.dart';
6869
part 'model/update_device_info_dto.dart';
6970
part 'model/update_user_dto.dart';

mobile/openapi/lib/api/asset_api.dart

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,9 @@ class AssetApi {
346346
/// Parameters:
347347
///
348348
/// * [String] assetId (required):
349-
Future<Response> getAssetThumbnailWithHttpInfo(String assetId,) async {
349+
///
350+
/// * [ThumbnailFormat] format:
351+
Future<Response> getAssetThumbnailWithHttpInfo(String assetId, { ThumbnailFormat? format, }) async {
350352
// ignore: prefer_const_declarations
351353
final path = r'/asset/thumbnail/{assetId}'
352354
.replaceAll('{assetId}', assetId);
@@ -358,6 +360,10 @@ class AssetApi {
358360
final headerParams = <String, String>{};
359361
final formParams = <String, String>{};
360362

363+
if (format != null) {
364+
queryParams.addAll(_queryParams('', 'format', format));
365+
}
366+
361367
const contentTypes = <String>[];
362368

363369

@@ -375,8 +381,10 @@ class AssetApi {
375381
/// Parameters:
376382
///
377383
/// * [String] assetId (required):
378-
Future<Object?> getAssetThumbnail(String assetId,) async {
379-
final response = await getAssetThumbnailWithHttpInfo(assetId,);
384+
///
385+
/// * [ThumbnailFormat] format:
386+
Future<Object?> getAssetThumbnail(String assetId, { ThumbnailFormat? format, }) async {
387+
final response = await getAssetThumbnailWithHttpInfo(assetId, format: format, );
380388
if (response.statusCode >= HttpStatus.badRequest) {
381389
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
382390
}

mobile/openapi/lib/api_client.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ class ApiClient {
252252
return SignUpDto.fromJson(value);
253253
case 'SmartInfoResponseDto':
254254
return SmartInfoResponseDto.fromJson(value);
255+
case 'ThumbnailFormat':
256+
return ThumbnailFormatTypeTransformer().decode(value);
255257
case 'UpdateAlbumDto':
256258
return UpdateAlbumDto.fromJson(value);
257259
case 'UpdateDeviceInfoDto':

0 commit comments

Comments
 (0)