Compare commits

..

1 Commits

Author SHA1 Message Date
Alex Tran
34aa6c1329 Revert "feat(web): make asset grid row height responsive (#16970)"
This reverts commit 7075c5b393.
2025-03-26 09:08:23 -05:00
22 changed files with 34 additions and 181 deletions

6
cli/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@immich/cli",
"version": "2.2.56",
"version": "2.2.55",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@immich/cli",
"version": "2.2.56",
"version": "2.2.55",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"chokidar": "^4.0.3",
@@ -55,7 +55,7 @@
},
"../open-api/typescript-sdk": {
"name": "@immich/sdk",
"version": "1.130.2",
"version": "1.130.1",
"dev": true,
"license": "GNU Affero General Public License version 3",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@immich/cli",
"version": "2.2.56",
"version": "2.2.55",
"description": "Command Line Interface (CLI) for Immich",
"type": "module",
"exports": "./dist/index.js",

View File

@@ -1,8 +1,4 @@
[
{
"label": "v1.130.2",
"url": "https://v1.130.2.archive.immich.app"
},
{
"label": "v1.130.1",
"url": "https://v1.130.1.archive.immich.app"

8
e2e/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "immich-e2e",
"version": "1.130.2",
"version": "1.130.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "immich-e2e",
"version": "1.130.2",
"version": "1.130.1",
"license": "GNU Affero General Public License version 3",
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
@@ -45,7 +45,7 @@
},
"../cli": {
"name": "@immich/cli",
"version": "2.2.56",
"version": "2.2.55",
"dev": true,
"license": "GNU Affero General Public License version 3",
"dependencies": {
@@ -95,7 +95,7 @@
},
"../open-api/typescript-sdk": {
"name": "@immich/sdk",
"version": "1.130.2",
"version": "1.130.1",
"dev": true,
"license": "GNU Affero General Public License version 3",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "immich-e2e",
"version": "1.130.2",
"version": "1.130.1",
"description": "",
"main": "index.js",
"type": "module",

View File

@@ -454,133 +454,6 @@ describe('/libraries', () => {
utils.removeImageFile(`${testAssetDir}/temp/folder${char}2/asset2.png`);
});
it('should respect exclusion patterns when using multiple import paths', async () => {
// https://github.com/immich-app/immich/issues/17121
const library = await utils.createLibrary(admin.accessToken, {
ownerId: admin.userId,
importPaths: [`${testAssetDirInternal}/temp/exclusion/`, `${testAssetDirInternal}/temp/exclusion2/`],
});
const excludedFolder = `Raw`;
utils.createImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
utils.createImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual(
expect.arrayContaining([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
]),
);
}
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual(
expect.arrayContaining([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
]),
);
}
await utils.updateLibrary(admin.accessToken, library.id, { exclusionPatterns: [`**/${excludedFolder}/**`] });
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
]);
}
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
]);
}
utils.removeImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
utils.removeImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
});
const annoyingExclusionPatterns = ['@', '#', '$', '%', '^', '&', '='];
it.each(annoyingExclusionPatterns)('should support exclusion patterns with %s', async (char) => {
const library = await utils.createLibrary(admin.accessToken, {
ownerId: admin.userId,
importPaths: [`${testAssetDirInternal}/temp/exclusion/`],
});
const excludedFolder = `${char}folder`;
utils.createImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
utils.createImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual(
expect.arrayContaining([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
]),
);
}
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual(
expect.arrayContaining([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
]),
);
}
await utils.updateLibrary(admin.accessToken, library.id, { exclusionPatterns: [`**/${excludedFolder}/**`] });
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
]);
}
await utils.scan(admin.accessToken, library.id);
{
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
expect(assets.items).toEqual([
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
]);
}
utils.removeImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
utils.removeImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
});
it('should reimport a modified file', async () => {
const library = await utils.createLibrary(admin.accessToken, {
ownerId: admin.userId,

View File

@@ -35,8 +35,8 @@ platform :android do
task: 'bundle',
build_type: 'Release',
properties: {
"android.injected.version.code" => 190,
"android.injected.version.name" => "1.130.2",
"android.injected.version.code" => 189,
"android.injected.version.name" => "1.130.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

@@ -19,7 +19,7 @@ platform :ios do
desc "iOS Release"
lane :release do
increment_version_number(
version_number: "1.130.2"
version_number: "1.130.1"
)
increment_build_number(
build_number: latest_testflight_build_number + 1,

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.130.2
- API version: 1.130.1
- Generator version: 7.8.0
- Build package: org.openapitools.codegen.languages.DartClientCodegen

View File

@@ -2,7 +2,7 @@ name: immich_mobile
description: Immich - selfhosted backup media file on mobile phone
publish_to: 'none'
version: 1.130.2+190
version: 1.130.1+189
environment:
sdk: '>=3.3.0 <4.0.0'

View File

@@ -7656,7 +7656,7 @@
"info": {
"title": "Immich",
"description": "Immich API",
"version": "1.130.2",
"version": "1.130.1",
"contact": {}
},
"tags": [],

View File

@@ -1,12 +1,12 @@
{
"name": "@immich/sdk",
"version": "1.130.2",
"version": "1.130.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@immich/sdk",
"version": "1.130.2",
"version": "1.130.1",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@oazapfts/runtime": "^1.0.2"

View File

@@ -1,6 +1,6 @@
{
"name": "@immich/sdk",
"version": "1.130.2",
"version": "1.130.1",
"description": "Auto-generated TypeScript SDK for the Immich API",
"type": "module",
"main": "./build/index.js",

View File

@@ -1,6 +1,6 @@
/**
* Immich
* 1.130.2
* 1.130.1
* DO NOT MODIFY - This file has been generated using oazapfts.
* See https://www.npmjs.com/package/oazapfts
*/

View File

@@ -1,12 +1,12 @@
{
"name": "immich",
"version": "1.130.2",
"version": "1.130.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "immich",
"version": "1.130.2",
"version": "1.130.1",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@nestjs/bullmq": "^11.0.1",

View File

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

View File

@@ -1062,10 +1062,7 @@ export class AssetRepository {
.where('isExternal', '=', true)
.where('libraryId', '=', asUuid(libraryId))
.where((eb) =>
eb.or([
eb.not(eb.or(paths.map((path) => eb('originalPath', 'like', path)))),
eb('originalPath', 'like', exclusions.join('|')),
]),
eb.or([eb('originalPath', 'not like', paths.join('|')), eb('originalPath', 'like', exclusions.join('|'))]),
)
.executeTakeFirstOrThrow();
}

6
web/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "immich-web",
"version": "1.130.2",
"version": "1.130.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "immich-web",
"version": "1.130.2",
"version": "1.130.1",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@formatjs/icu-messageformat-parser": "^2.9.8",
@@ -81,7 +81,7 @@
},
"../open-api/typescript-sdk": {
"name": "@immich/sdk",
"version": "1.130.2",
"version": "1.130.1",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@oazapfts/runtime": "^1.0.2"

View File

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

View File

@@ -1,6 +1,4 @@
<script lang="ts" module>
import { get } from 'svelte/store';
export type ComboBoxOption = {
id?: string;
label: string;
@@ -30,6 +28,7 @@
import { generateId } from '$lib/utils/generate-id';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import { t } from 'svelte-i18n';
import { get } from 'svelte/store';
interface Props {
label: string;
@@ -283,6 +282,7 @@
class:cursor-pointer={!isActive}
class="immich-form-input text-sm text-left w-full !pr-12 transition-all"
id={inputId}
onclick={activate}
onfocus={activate}
oninput={onInput}
role="combobox"
@@ -366,7 +366,7 @@
aria-disabled={true}
class="text-left w-full px-4 py-2 hover:bg-gray-200 dark:hover:bg-gray-700 cursor-default aria-selected:bg-gray-200 aria-selected:dark:bg-gray-700"
id={`${listboxId}-${0}`}
onclick={closeDropdown}
onclick={() => closeDropdown()}
>
{allowCreate ? searchQuery : $t('no_results')}
</li>

View File

@@ -63,14 +63,11 @@
const _assets = assets;
updateSlidingWindow();
const rowWidth = Math.floor(viewport.width);
const rowHeight = rowWidth < 850 ? 100 : 235;
geometry = getJustifiedLayoutFromAssets(_assets, {
spacing: 2,
heightTolerance: 0.15,
rowHeight,
rowWidth,
rowHeight: 235,
rowWidth: Math.floor(viewport.width),
});
});

View File

@@ -39,9 +39,7 @@ export type AssetStoreOptions = Omit<AssetApiGetTimeBucketsRequest, 'size'> & {
timelineAlbumId?: string;
deferInit?: boolean;
};
export type AssetStoreLayoutOptions = {
rowHeight: number;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function updateObject(target: any, source: any): boolean {
if (!target) {
@@ -578,7 +576,6 @@ export class AssetStore {
// --- private
static #INIT_OPTIONS = {};
#rowHeight = 235;
#viewportHeight = $state(0);
#viewportWidth = $state(0);
#scrollTop = $state(0);
@@ -621,7 +618,6 @@ export class AssetStore {
const changed = value !== this.#viewportWidth;
this.#viewportWidth = value;
this.suspendTransitions = true;
this.#rowHeight = value < 850 ? 100 : 235;
// side-effect - its ok!
void this.#updateViewportGeometry(changed);
}
@@ -797,11 +793,6 @@ export class AssetStore {
this.#updateViewportGeometry(false);
}
updateLayoutOptions(options: AssetStoreLayoutOptions) {
this.#rowHeight = options.rowHeight;
this.refreshLayout();
}
async #init(options: AssetStoreOptions) {
// doing the following outside of the task reduces flickr
this.isInitialized = false;
@@ -871,11 +862,10 @@ export class AssetStore {
createLayoutOptions() {
const viewportWidth = this.viewportWidth;
return {
spacing: 2,
heightTolerance: 0.15,
rowHeight: this.#rowHeight,
rowHeight: 235,
rowWidth: Math.floor(viewportWidth),
};
}