Compare commits

..

7 Commits

Author SHA1 Message Date
Alex The Bot
7c34d0595e Version v1.95.1 2024-02-21 04:02:43 +00:00
Mert
eb73f6605b fix(server): don't return archived assets by default (#7278)
* don't show archived results by default

* fix e2e

* generate sql

* set default in dto

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-02-21 03:59:26 +00:00
Alex
bb5236ae65 fix(server): not in album filter with context search (#7275) 2024-02-20 20:44:34 -06:00
Mert
e33fd40b4c fix(server): quote database name in migration (#7277)
quote database name
2024-02-21 02:13:43 +00:00
Alex
73825918c0 fix(web): presenting modal removes the browser's scroll ability (#7257)
* fix(web): presenting modal removes the browser's scroll ability

* removed unsued code

* eslint
2024-02-20 14:02:01 -06:00
martyfuhry
a22bf99206 fix(mobile): Uses immich thumbnail for background of memory picture (#7254)
unused imports
2024-02-20 13:58:41 -06:00
Alex
578b71b961 chore: post release tasks 2024-02-20 11:05:24 -06:00
35 changed files with 149 additions and 103 deletions

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "machine-learning"
version = "1.95.0"
version = "1.95.1"
description = ""
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
readme = "README.md"

View File

@@ -35,8 +35,8 @@ platform :android do
task: 'bundle',
build_type: 'Release',
properties: {
"android.injected.version.code" => 122,
"android.injected.version.name" => "1.95.0",
"android.injected.version.code" => 123,
"android.injected.version.name" => "1.95.1",
}
)
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')

View File

@@ -5,17 +5,17 @@
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000276">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000232">
</testcase>
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="22.651725">
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="78.881681">
</testcase>
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="31.263395">
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="32.080999">
</testcase>

View File

@@ -379,7 +379,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 137;
CURRENT_PROJECT_VERSION = 139;
DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -515,7 +515,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 137;
CURRENT_PROJECT_VERSION = 139;
DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -543,7 +543,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 137;
CURRENT_PROJECT_VERSION = 139;
DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;

View File

@@ -55,11 +55,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.94.1</string>
<string>1.95.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>137</string>
<string>139</string>
<key>FLTEnableImpeller</key>
<true />
<key>ITSAppUsesNonExemptEncryption</key>

View File

@@ -19,7 +19,7 @@ platform :ios do
desc "iOS Beta"
lane :beta do
increment_version_number(
version_number: "1.95.0"
version_number: "1.95.1"
)
increment_build_number(
build_number: latest_testflight_build_number + 1,

View File

@@ -5,32 +5,32 @@
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000247">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000255">
</testcase>
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="0.238661">
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="0.157832">
</testcase>
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="2.965603">
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="4.825919">
</testcase>
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="0.228067">
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="0.18815">
</testcase>
<testcase classname="fastlane.lanes" name="4: build_app" time="108.628243">
<testcase classname="fastlane.lanes" name="4: build_app" time="110.912709">
</testcase>
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="71.752027">
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="78.396901">
</testcase>

View File

@@ -1,13 +1,11 @@
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart';
import 'package:immich_mobile/utils/image_url_builder.dart';
class MemoryCard extends StatelessWidget {
final Asset asset;
@@ -44,14 +42,9 @@ class MemoryCard extends StatelessWidget {
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(
getThumbnailUrl(
asset,
),
cacheKey: getThumbnailCacheKey(
asset,
),
headers: {"x-immich-user-token": accessToken},
image: ImmichImage.imageProvider(
asset: asset,
isThumbnail: true,
),
fit: BoxFit.cover,
),

View File

@@ -3,7 +3,7 @@ Immich API
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
- API version: 1.95.0
- API version: 1.95.1
- Build package: org.openapitools.codegen.languages.DartClientCodegen
## Requirements

View File

@@ -1153,7 +1153,7 @@ Name | Type | Description | Notes
**updatedAfter** | **DateTime**| | [optional]
**updatedBefore** | **DateTime**| | [optional]
**webpPath** | **String**| | [optional]
**withArchived** | **bool**| | [optional]
**withArchived** | **bool**| | [optional] [default to false]
**withDeleted** | **bool**| | [optional]
**withExif** | **bool**| | [optional]
**withPeople** | **bool**| | [optional]

View File

@@ -46,7 +46,7 @@ Name | Type | Description | Notes
**updatedAfter** | [**DateTime**](DateTime.md) | | [optional]
**updatedBefore** | [**DateTime**](DateTime.md) | | [optional]
**webpPath** | **String** | | [optional]
**withArchived** | **bool** | | [optional]
**withArchived** | **bool** | | [optional] [default to false]
**withDeleted** | **bool** | | [optional]
**withExif** | **bool** | | [optional]
**withPeople** | **bool** | | [optional]

View File

@@ -18,6 +18,7 @@ Name | Type | Description | Notes
**isExternal** | **bool** | | [optional]
**isFavorite** | **bool** | | [optional]
**isMotion** | **bool** | | [optional]
**isNotInAlbum** | **bool** | | [optional]
**isOffline** | **bool** | | [optional]
**isReadOnly** | **bool** | | [optional]
**isVisible** | **bool** | | [optional]
@@ -36,7 +37,7 @@ Name | Type | Description | Notes
**type** | [**AssetTypeEnum**](AssetTypeEnum.md) | | [optional]
**updatedAfter** | [**DateTime**](DateTime.md) | | [optional]
**updatedBefore** | [**DateTime**](DateTime.md) | | [optional]
**withArchived** | **bool** | | [optional]
**withArchived** | **bool** | | [optional] [default to false]
**withDeleted** | **bool** | | [optional]
**withExif** | **bool** | | [optional]

View File

@@ -51,7 +51,7 @@ class MetadataSearchDto {
this.updatedAfter,
this.updatedBefore,
this.webpPath,
this.withArchived,
this.withArchived = false,
this.withDeleted,
this.withExif,
this.withPeople,
@@ -356,13 +356,7 @@ class MetadataSearchDto {
///
String? webpPath;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
bool? withArchived;
bool withArchived;
///
/// Please note: This property should have been non-nullable! Since the specification file
@@ -483,7 +477,7 @@ class MetadataSearchDto {
(updatedAfter == null ? 0 : updatedAfter!.hashCode) +
(updatedBefore == null ? 0 : updatedBefore!.hashCode) +
(webpPath == null ? 0 : webpPath!.hashCode) +
(withArchived == null ? 0 : withArchived!.hashCode) +
(withArchived.hashCode) +
(withDeleted == null ? 0 : withDeleted!.hashCode) +
(withExif == null ? 0 : withExif!.hashCode) +
(withPeople == null ? 0 : withPeople!.hashCode) +
@@ -680,11 +674,7 @@ class MetadataSearchDto {
} else {
// json[r'webpPath'] = null;
}
if (this.withArchived != null) {
json[r'withArchived'] = this.withArchived;
} else {
// json[r'withArchived'] = null;
}
if (this.withDeleted != null) {
json[r'withDeleted'] = this.withDeleted;
} else {
@@ -756,7 +746,7 @@ class MetadataSearchDto {
updatedAfter: mapDateTime(json, r'updatedAfter', r''),
updatedBefore: mapDateTime(json, r'updatedBefore', r''),
webpPath: mapValueOfType<String>(json, r'webpPath'),
withArchived: mapValueOfType<bool>(json, r'withArchived'),
withArchived: mapValueOfType<bool>(json, r'withArchived') ?? false,
withDeleted: mapValueOfType<bool>(json, r'withDeleted'),
withExif: mapValueOfType<bool>(json, r'withExif'),
withPeople: mapValueOfType<bool>(json, r'withPeople'),

View File

@@ -23,6 +23,7 @@ class SmartSearchDto {
this.isExternal,
this.isFavorite,
this.isMotion,
this.isNotInAlbum,
this.isOffline,
this.isReadOnly,
this.isVisible,
@@ -41,7 +42,7 @@ class SmartSearchDto {
this.type,
this.updatedAfter,
this.updatedBefore,
this.withArchived,
this.withArchived = false,
this.withDeleted,
this.withExif,
});
@@ -126,6 +127,14 @@ class SmartSearchDto {
///
bool? isMotion;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
bool? isNotInAlbum;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
@@ -264,13 +273,7 @@ class SmartSearchDto {
///
DateTime? updatedBefore;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
bool? withArchived;
bool withArchived;
///
/// Please note: This property should have been non-nullable! Since the specification file
@@ -300,6 +303,7 @@ class SmartSearchDto {
other.isExternal == isExternal &&
other.isFavorite == isFavorite &&
other.isMotion == isMotion &&
other.isNotInAlbum == isNotInAlbum &&
other.isOffline == isOffline &&
other.isReadOnly == isReadOnly &&
other.isVisible == isVisible &&
@@ -335,6 +339,7 @@ class SmartSearchDto {
(isExternal == null ? 0 : isExternal!.hashCode) +
(isFavorite == null ? 0 : isFavorite!.hashCode) +
(isMotion == null ? 0 : isMotion!.hashCode) +
(isNotInAlbum == null ? 0 : isNotInAlbum!.hashCode) +
(isOffline == null ? 0 : isOffline!.hashCode) +
(isReadOnly == null ? 0 : isReadOnly!.hashCode) +
(isVisible == null ? 0 : isVisible!.hashCode) +
@@ -353,12 +358,12 @@ class SmartSearchDto {
(type == null ? 0 : type!.hashCode) +
(updatedAfter == null ? 0 : updatedAfter!.hashCode) +
(updatedBefore == null ? 0 : updatedBefore!.hashCode) +
(withArchived == null ? 0 : withArchived!.hashCode) +
(withArchived.hashCode) +
(withDeleted == null ? 0 : withDeleted!.hashCode) +
(withExif == null ? 0 : withExif!.hashCode);
@override
String toString() => 'SmartSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isArchived=$isArchived, isEncoded=$isEncoded, isExternal=$isExternal, isFavorite=$isFavorite, isMotion=$isMotion, isOffline=$isOffline, isReadOnly=$isReadOnly, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, page=$page, query=$query, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif]';
String toString() => 'SmartSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isArchived=$isArchived, isEncoded=$isEncoded, isExternal=$isExternal, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isReadOnly=$isReadOnly, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, page=$page, query=$query, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
@@ -412,6 +417,11 @@ class SmartSearchDto {
} else {
// json[r'isMotion'] = null;
}
if (this.isNotInAlbum != null) {
json[r'isNotInAlbum'] = this.isNotInAlbum;
} else {
// json[r'isNotInAlbum'] = null;
}
if (this.isOffline != null) {
json[r'isOffline'] = this.isOffline;
} else {
@@ -498,11 +508,7 @@ class SmartSearchDto {
} else {
// json[r'updatedBefore'] = null;
}
if (this.withArchived != null) {
json[r'withArchived'] = this.withArchived;
} else {
// json[r'withArchived'] = null;
}
if (this.withDeleted != null) {
json[r'withDeleted'] = this.withDeleted;
} else {
@@ -534,6 +540,7 @@ class SmartSearchDto {
isExternal: mapValueOfType<bool>(json, r'isExternal'),
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
isMotion: mapValueOfType<bool>(json, r'isMotion'),
isNotInAlbum: mapValueOfType<bool>(json, r'isNotInAlbum'),
isOffline: mapValueOfType<bool>(json, r'isOffline'),
isReadOnly: mapValueOfType<bool>(json, r'isReadOnly'),
isVisible: mapValueOfType<bool>(json, r'isVisible'),
@@ -552,7 +559,7 @@ class SmartSearchDto {
type: AssetTypeEnum.fromJson(json[r'type']),
updatedAfter: mapDateTime(json, r'updatedAfter', r''),
updatedBefore: mapDateTime(json, r'updatedBefore', r''),
withArchived: mapValueOfType<bool>(json, r'withArchived'),
withArchived: mapValueOfType<bool>(json, r'withArchived') ?? false,
withDeleted: mapValueOfType<bool>(json, r'withDeleted'),
withExif: mapValueOfType<bool>(json, r'withExif'),
);

View File

@@ -206,7 +206,7 @@ void main() {
// TODO
});
// bool withArchived
// bool withArchived (default value: false)
test('to test the property `withArchived`', () async {
// TODO
});

View File

@@ -66,6 +66,11 @@ void main() {
// TODO
});
// bool isNotInAlbum
test('to test the property `isNotInAlbum`', () async {
// TODO
});
// bool isOffline
test('to test the property `isOffline`', () async {
// TODO
@@ -156,7 +161,7 @@ void main() {
// TODO
});
// bool withArchived
// bool withArchived (default value: false)
test('to test the property `withArchived`', () async {
// TODO
});

View File

@@ -2,7 +2,7 @@ name: immich_mobile
description: Immich - selfhosted backup media file on mobile phone
publish_to: "none"
version: 1.95.0+122
version: 1.95.1+123
isar_version: &isar_version 3.1.0+1
environment:

View File

@@ -2463,6 +2463,7 @@
"required": false,
"in": "query",
"schema": {
"default": false,
"type": "boolean"
}
},
@@ -6413,7 +6414,7 @@
"info": {
"title": "Immich",
"description": "Immich API",
"version": "1.95.0",
"version": "1.95.1",
"contact": {}
},
"tags": [],
@@ -8429,6 +8430,7 @@
"type": "string"
},
"withArchived": {
"default": false,
"type": "boolean"
},
"withDeleted": {
@@ -9435,6 +9437,9 @@
"isMotion": {
"type": "boolean"
},
"isNotInAlbum": {
"type": "boolean"
},
"isOffline": {
"type": "boolean"
},
@@ -9497,6 +9502,7 @@
"type": "string"
},
"withArchived": {
"default": false,
"type": "boolean"
},
"withDeleted": {

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.95.0
* The version of the OpenAPI document: 1.95.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -3880,6 +3880,12 @@ export interface SmartSearchDto {
* @memberof SmartSearchDto
*/
'isMotion'?: boolean;
/**
*
* @type {boolean}
* @memberof SmartSearchDto
*/
'isNotInAlbum'?: boolean;
/**
*
* @type {boolean}

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.95.0
* The version of the OpenAPI document: 1.95.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.95.0
* The version of the OpenAPI document: 1.95.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.95.0
* The version of the OpenAPI document: 1.95.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -4,7 +4,7 @@
* Immich
* Immich API
*
* The version of the OpenAPI document: 1.95.0
* The version of the OpenAPI document: 1.95.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -1,6 +1,6 @@
/**
* Immich
* 1.95.0
* 1.95.1
* DO NOT MODIFY - This file has been generated using oazapfts.
* See https://www.npmjs.com/package/oazapfts
*/
@@ -656,6 +656,7 @@ export type SmartSearchDto = {
isExternal?: boolean;
isFavorite?: boolean;
isMotion?: boolean;
isNotInAlbum?: boolean;
isOffline?: boolean;
isReadOnly?: boolean;
isVisible?: boolean;

View File

@@ -50,6 +50,7 @@ describe(`${AssetController.name} (e2e)`, () => {
let asset3: AssetResponseDto;
let asset4: AssetResponseDto;
let asset5: AssetResponseDto;
let asset6: AssetResponseDto;
const createAsset = async (
loginResponse: LoginResponseDto,
@@ -96,12 +97,11 @@ describe(`${AssetController.name} (e2e)`, () => {
beforeEach(async () => {
await testApp.reset({ entities: [AssetEntity, AssetStackEntity] });
[asset1, asset2, asset3, asset4, asset5] = await Promise.all([
[asset1, asset2, asset3, asset4, asset5, asset6] = await Promise.all([
createAsset(user1, new Date('1970-01-01')),
createAsset(user1, new Date('1970-02-10')),
createAsset(user1, new Date('1970-02-11'), {
isFavorite: true,
isArchived: true,
isExternal: true,
isReadOnly: true,
type: AssetType.VIDEO,
@@ -118,6 +118,9 @@ describe(`${AssetController.name} (e2e)`, () => {
createAsset(user1, new Date('1970-01-01'), {
deletedAt: yesterday.toJSDate(),
}),
createAsset(user1, new Date('1970-02-11'), {
isArchived: true,
}),
]);
await assetRepository.upsertExif({
@@ -275,14 +278,14 @@ describe(`${AssetController.name} (e2e)`, () => {
should: 'should search by isArchived (true)',
deferred: () => ({
query: { isArchived: true },
assets: [asset3],
assets: [asset6],
}),
},
{
should: 'should search by isArchived (false)',
deferred: () => ({
query: { isArchived: false },
assets: [asset2, asset1],
assets: [asset3, asset2, asset1],
}),
},
{
@@ -313,6 +316,20 @@ describe(`${AssetController.name} (e2e)`, () => {
assets: [asset3],
}),
},
{
should: 'should search by withArchived (true)',
deferred: () => ({
query: { withArchived: true },
assets: [asset3, asset6, asset2, asset1],
}),
},
{
should: 'should search by withArchived (false)',
deferred: () => ({
query: { withArchived: false },
assets: [asset3, asset2, asset1],
}),
},
{
should: 'should search by createdBefore',
deferred: () => ({
@@ -902,7 +919,7 @@ describe(`${AssetController.name} (e2e)`, () => {
.get('/asset/statistics')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(body).toEqual({ images: 5, videos: 1, total: 6 });
expect(body).toEqual({ images: 6, videos: 1, total: 7 });
expect(status).toBe(200);
});
@@ -923,7 +940,7 @@ describe(`${AssetController.name} (e2e)`, () => {
.query({ isArchived: true });
expect(status).toBe(200);
expect(body).toEqual({ images: 2, videos: 1, total: 3 });
expect(body).toEqual({ images: 3, videos: 0, total: 3 });
});
it('should return stats of all favored and archived assets', async () => {
@@ -933,7 +950,7 @@ describe(`${AssetController.name} (e2e)`, () => {
.query({ isFavorite: true, isArchived: true });
expect(status).toBe(200);
expect(body).toEqual({ images: 1, videos: 1, total: 2 });
expect(body).toEqual({ images: 1, videos: 0, total: 1 });
});
it('should return stats of all assets neither favored nor archived', async () => {
@@ -1041,7 +1058,7 @@ describe(`${AssetController.name} (e2e)`, () => {
expect.arrayContaining([
{ count: 1, timeBucket: '2023-11-01T00:00:00.000Z' },
{ count: 1, timeBucket: '1970-01-01T00:00:00.000Z' },
{ count: 1, timeBucket: '1970-02-01T00:00:00.000Z' },
{ count: 2, timeBucket: '1970-02-01T00:00:00.000Z' },
]),
);
});
@@ -1198,8 +1215,13 @@ describe(`${AssetController.name} (e2e)`, () => {
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(1);
expect(body).toEqual(expect.arrayContaining([expect.objectContaining({ id: asset2.id })]));
expect(body).toHaveLength(2);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: asset2.id }),
expect.objectContaining({ id: asset3.id }),
]),
);
});
it('should get all map markers', async () => {
@@ -1209,8 +1231,13 @@ describe(`${AssetController.name} (e2e)`, () => {
.query({ isArchived: false });
expect(status).toBe(200);
expect(body).toHaveLength(1);
expect(body).toEqual([expect.objectContaining({ id: asset2.id })]);
expect(body).toHaveLength(2);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: asset2.id }),
expect.objectContaining({ id: asset3.id }),
]),
);
});
});

View File

@@ -1,12 +1,12 @@
{
"name": "immich",
"version": "1.95.0",
"version": "1.95.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "immich",
"version": "1.95.0",
"version": "1.95.1",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@babel/runtime": "^7.22.11",

View File

@@ -1,6 +1,6 @@
{
"name": "immich",
"version": "1.95.0",
"version": "1.95.1",
"description": "",
"author": "",
"private": true,

View File

@@ -23,6 +23,7 @@ class BaseSearchDto {
isArchived?: boolean;
@QueryBoolean({ optional: true })
@ApiProperty({ default: false })
withArchived?: boolean;
@QueryBoolean({ optional: true })
@@ -118,6 +119,9 @@ class BaseSearchDto {
@Type(() => Number)
@Optional()
size?: number;
@QueryBoolean({ optional: true })
isNotInAlbum?: boolean;
}
export class MetadataSearchDto extends BaseSearchDto {
@@ -170,9 +174,6 @@ export class MetadataSearchDto extends BaseSearchDto {
@ApiProperty({ enumName: 'AssetOrder', enum: AssetOrder })
order?: AssetOrder;
@QueryBoolean({ optional: true })
isNotInAlbum?: boolean;
@Optional()
personIds?: string[];
}

View File

@@ -183,7 +183,7 @@ export function searchAssetBuilder(
_.omitBy(
{
...status,
isArchived: isArchived ?? withArchived,
isArchived: isArchived ?? (withArchived ? undefined : false),
encodedVideoPath: isEncoded ? Not(IsNull()) : undefined,
livePhotoVideoId: isMotion ? Not(IsNull()) : undefined,
},

View File

@@ -4,11 +4,11 @@ export class AddVectorsToSearchPath1707000751533 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
const res = await queryRunner.query(`SELECT current_database() as db`);
const databaseName = res[0]['db'];
await queryRunner.query(`ALTER DATABASE ${databaseName} SET search_path TO "$user", public, vectors`);
await queryRunner.query(`ALTER DATABASE "${databaseName}" SET search_path TO "$user", public, vectors`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const databaseName = await queryRunner.query(`SELECT current_database()`);
await queryRunner.query(`ALTER DATABASE ${databaseName} SET search_path TO "$user", public`);
await queryRunner.query(`ALTER DATABASE "${databaseName}" SET search_path TO "$user", public`);
}
}

View File

@@ -434,7 +434,7 @@ WHERE
AND 1 = 1
AND "asset"."ownerId" IN ($2)
AND 1 = 1
AND 1 = 1
AND "asset"."isArchived" = $3
)
AND ("asset"."deletedAt" IS NULL)
ORDER BY

View File

@@ -79,7 +79,10 @@ FROM
AND "exifInfo"."lensModel" = $2
AND 1 = 1
AND 1 = 1
AND "asset"."isFavorite" = $3
AND (
"asset"."isFavorite" = $3
AND "asset"."isArchived" = $4
)
AND (
"stack"."primaryAssetId" = "asset"."id"
OR "asset"."stackId" IS NULL
@@ -177,16 +180,19 @@ WHERE
AND "exifInfo"."lensModel" = $2
AND 1 = 1
AND 1 = 1
AND "asset"."isFavorite" = $3
AND (
"asset"."isFavorite" = $3
AND "asset"."isArchived" = $4
)
AND (
"stack"."primaryAssetId" = "asset"."id"
OR "asset"."stackId" IS NULL
)
AND "asset"."ownerId" IN ($4)
AND "asset"."ownerId" IN ($5)
)
AND ("asset"."deletedAt" IS NULL)
ORDER BY
"search"."embedding" <= > $5 ASC
"search"."embedding" <= > $6 ASC
LIMIT
101
COMMIT

4
web/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "immich-web",
"version": "1.1.0",
"version": "1.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "immich-web",
"version": "1.1.0",
"version": "1.1.1",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@immich/sdk": "file:../open-api/typescript-sdk",

View File

@@ -1,6 +1,6 @@
{
"name": "immich-web",
"version": "1.1.0",
"version": "1.1.1",
"license": "GNU Affero General Public License version 3",
"scripts": {
"dev": "vite dev --host 0.0.0.0 --port 3000",

View File

@@ -18,15 +18,18 @@
if (browser) {
const scrollTop = document.documentElement.scrollTop;
const scrollLeft = document.documentElement.scrollLeft;
window.addEventListener('scroll', function () {
/* eslint-disable unicorn/prefer-add-event-listener */
window.onscroll = function () {
window.scrollTo(scrollLeft, scrollTop);
});
};
}
});
onDestroy(() => {
if (browser) {
window.addEventListener('scroll', () => {});
/* eslint-disable unicorn/prefer-add-event-listener */
window.onscroll = null;
}
});
</script>