mirror of
https://github.com/immich-app/immich.git
synced 2026-02-06 18:00:43 +03:00
Compare commits
4 Commits
renovate/t
...
release/ne
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9067c6205 | ||
|
|
a356497d96 | ||
|
|
16fe828913 | ||
|
|
211dc3c056 |
27
CHANGELOG.md
Normal file
27
CHANGELOG.md
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
# v2.5.6
|
||||
|
||||
## Highlights
|
||||
|
||||
{{RELEASE HIGHLIGHTS}}
|
||||
|
||||
As always, please consider supporting the project.
|
||||
|
||||
🎉 Cheers! 🎉
|
||||
|
||||
|
||||
----
|
||||
|
||||
And as always, bugs are fixed, and many other improvements also come with this release.
|
||||
|
||||
<!-- Release notes generated using configuration in .github/release.yml at main -->
|
||||
|
||||
## What's Changed
|
||||
### 🐛 Bug fixes
|
||||
* fix: add missing translations for image editor by @michelheusschen in https://github.com/immich-app/immich/pull/25957
|
||||
|
||||
|
||||
**Full Changelog**: https://github.com/immich-app/immich/compare/v2.5.5...v2.5.6
|
||||
|
||||
---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/cli",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"description": "Command Line Interface (CLI) for Immich",
|
||||
"type": "module",
|
||||
"exports": "./dist/index.js",
|
||||
|
||||
4
docs/static/archived-versions.json
vendored
4
docs/static/archived-versions.json
vendored
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"label": "v2.5.5",
|
||||
"url": "https://docs.v2.5.5.archive.immich.app"
|
||||
"label": "v2.5.6",
|
||||
"url": "https://docs.v2.5.6.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v2.4.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-e2e",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
|
||||
@@ -997,6 +997,11 @@
|
||||
"editor_close_without_save_prompt": "The changes will not be saved",
|
||||
"editor_close_without_save_title": "Close editor?",
|
||||
"editor_confirm_reset_all_changes": "Are you sure you want to reset all changes?",
|
||||
"editor_discard_edits_confirm": "Discard edits",
|
||||
"editor_discard_edits_prompt": "You have unsaved edits. Are you sure you want to discard them?",
|
||||
"editor_discard_edits_title": "Discard edits?",
|
||||
"editor_edits_applied_error": "Failed to apply edits",
|
||||
"editor_edits_applied_success": "Edits applied successfully",
|
||||
"editor_flip_horizontal": "Flip horizontal",
|
||||
"editor_flip_vertical": "Flip vertical",
|
||||
"editor_orientation": "Orientation",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-i18n",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"format": "prettier --check .",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "immich-ml"
|
||||
version = "2.5.5"
|
||||
version = "2.5.6"
|
||||
description = ""
|
||||
authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }]
|
||||
requires-python = ">=3.11,<4.0"
|
||||
|
||||
2
machine-learning/uv.lock
generated
2
machine-learning/uv.lock
generated
@@ -882,7 +882,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "immich-ml"
|
||||
version = "2.5.5"
|
||||
version = "2.5.6"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "aiocache" },
|
||||
|
||||
@@ -35,8 +35,8 @@ platform :android do
|
||||
task: 'bundle',
|
||||
build_type: 'Release',
|
||||
properties: {
|
||||
"android.injected.version.code" => 3036,
|
||||
"android.injected.version.name" => "2.5.5",
|
||||
"android.injected.version.code" => 3037,
|
||||
"android.injected.version.name" => "2.5.6",
|
||||
}
|
||||
)
|
||||
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')
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.5.5</string>
|
||||
<string>2.5.6</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
2
mobile/openapi/README.md
generated
2
mobile/openapi/README.md
generated
@@ -3,7 +3,7 @@ Immich API
|
||||
|
||||
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||
|
||||
- API version: 2.5.5
|
||||
- API version: 2.5.6
|
||||
- Generator version: 7.8.0
|
||||
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ name: immich_mobile
|
||||
description: Immich - selfhosted backup media file on mobile phone
|
||||
|
||||
publish_to: 'none'
|
||||
version: 2.5.5+3036
|
||||
version: 2.5.6+3037
|
||||
|
||||
environment:
|
||||
sdk: '>=3.8.0 <4.0.0'
|
||||
|
||||
@@ -15072,7 +15072,7 @@
|
||||
"info": {
|
||||
"title": "Immich",
|
||||
"description": "Immich API",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"contact": {}
|
||||
},
|
||||
"tags": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/sdk",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"description": "Auto-generated TypeScript SDK for the Immich API",
|
||||
"type": "module",
|
||||
"main": "./build/index.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Immich
|
||||
* 2.5.5
|
||||
* 2.5.6
|
||||
* DO NOT MODIFY - This file has been generated using oazapfts.
|
||||
* See https://www.npmjs.com/package/oazapfts
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-monorepo",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"description": "Monorepo for Immich",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -17,8 +17,6 @@ set
|
||||
where
|
||||
"userId" = $2
|
||||
and "albumId" = $3
|
||||
returning
|
||||
*
|
||||
|
||||
-- AlbumUserRepository.delete
|
||||
delete from "album_user"
|
||||
|
||||
@@ -25,14 +25,13 @@ export class AlbumUserRepository {
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [{ userId: DummyValue.UUID, albumId: DummyValue.UUID }, { role: AlbumUserRole.Viewer }] })
|
||||
update({ userId, albumId }: AlbumPermissionId, dto: Updateable<AlbumUserTable>) {
|
||||
return this.db
|
||||
async update({ userId, albumId }: AlbumPermissionId, dto: Updateable<AlbumUserTable>) {
|
||||
await this.db
|
||||
.updateTable('album_user')
|
||||
.set(dto)
|
||||
.where('userId', '=', userId)
|
||||
.where('albumId', '=', albumId)
|
||||
.returningAll()
|
||||
.executeTakeFirstOrThrow();
|
||||
.execute();
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [{ userId: DummyValue.UUID, albumId: DummyValue.UUID }] })
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
Activity,
|
||||
Album,
|
||||
ApiKey,
|
||||
AssetFace,
|
||||
AssetFile,
|
||||
@@ -23,6 +24,7 @@ import { AssetEditAction, AssetEditActionItem, MirrorAxis } from 'src/dtos/editi
|
||||
import { QueueStatisticsDto } from 'src/dtos/queue.dto';
|
||||
import {
|
||||
AssetFileType,
|
||||
AssetOrder,
|
||||
AssetStatus,
|
||||
AssetType,
|
||||
AssetVisibility,
|
||||
@@ -506,6 +508,24 @@ const personFactory = (person?: Partial<Person>): Person => ({
|
||||
...person,
|
||||
});
|
||||
|
||||
const albumFactory = (album?: Partial<Omit<Album, 'assets'>>) => ({
|
||||
albumName: 'My Album',
|
||||
albumThumbnailAssetId: null,
|
||||
albumUsers: [],
|
||||
assets: [],
|
||||
createdAt: newDate(),
|
||||
deletedAt: null,
|
||||
description: 'Album description',
|
||||
id: newUuid(),
|
||||
isActivityEnabled: false,
|
||||
order: AssetOrder.Desc,
|
||||
ownerId: newUuid(),
|
||||
sharedLinks: [],
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
...album,
|
||||
});
|
||||
|
||||
export const factory = {
|
||||
activity: activityFactory,
|
||||
apiKey: apiKeyFactory,
|
||||
@@ -532,6 +552,7 @@ export const factory = {
|
||||
person: personFactory,
|
||||
assetEdit: assetEditFactory,
|
||||
tag: tagFactory,
|
||||
album: albumFactory,
|
||||
uuid: newUuid,
|
||||
buffer: () => Buffer.from('this is a fake buffer'),
|
||||
date: newDate,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-web",
|
||||
"version": "2.5.5",
|
||||
"version": "2.5.6",
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -2,6 +2,7 @@ import TransformTool from '$lib/components/asset-viewer/editor/transform-tool/tr
|
||||
import { transformManager } from '$lib/managers/edit/transform-manager.svelte';
|
||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||
import { waitForWebsocketEvent } from '$lib/stores/websocket';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
import { editAsset, removeAssetEdits, type AssetEditsDto, type AssetResponseDto } from '@immich/sdk';
|
||||
import { ConfirmModal, modalManager, toastManager } from '@immich/ui';
|
||||
import { mdiCropRotate } from '@mdi/js';
|
||||
@@ -63,10 +64,12 @@ export class EditManager {
|
||||
|
||||
this.isShowingConfirmDialog = true;
|
||||
|
||||
const t = await getFormatter();
|
||||
|
||||
const confirmed = await modalManager.show(ConfirmModal, {
|
||||
title: 'Discard Edits?',
|
||||
prompt: 'You have unsaved edits. Are you sure you want to discard them?',
|
||||
confirmText: 'Discard Edits',
|
||||
title: t('editor_discard_edits_title'),
|
||||
prompt: t('editor_discard_edits_prompt'),
|
||||
confirmText: t('editor_discard_edits_confirm'),
|
||||
});
|
||||
|
||||
this.isShowingConfirmDialog = false;
|
||||
@@ -120,6 +123,7 @@ export class EditManager {
|
||||
}
|
||||
|
||||
const assetId = this.currentAsset.id;
|
||||
const t = await getFormatter();
|
||||
|
||||
try {
|
||||
// Setup the websocket listener before sending the edit request
|
||||
@@ -138,12 +142,12 @@ export class EditManager {
|
||||
|
||||
eventManager.emit('AssetEditsApplied', assetId);
|
||||
|
||||
toastManager.success('Edits applied successfully');
|
||||
toastManager.success(t('editor_edits_applied_success'));
|
||||
this.hasAppliedEdits = true;
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
toastManager.danger('Failed to apply edits');
|
||||
toastManager.danger(t('editor_edits_applied_error'));
|
||||
return false;
|
||||
} finally {
|
||||
this.isApplyingEdits = false;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
let { asset, onClose }: Props = $props();
|
||||
|
||||
let imgElement: HTMLDivElement | undefined = $state();
|
||||
let cropContainer: HTMLDivElement | undefined = $state();
|
||||
|
||||
onMount(() => {
|
||||
if (!imgElement) {
|
||||
@@ -52,23 +51,16 @@
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
if (!cropContainer) {
|
||||
if (!imgElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Get the container dimensions (which is always square due to aspect-square class)
|
||||
const containerSize = cropContainer.offsetWidth;
|
||||
|
||||
// Capture the crop container which maintains 1:1 aspect ratio
|
||||
// Override border-radius and border to avoid transparent corners from rounded-full
|
||||
const blob = await domtoimage.toBlob(cropContainer, {
|
||||
width: containerSize,
|
||||
height: containerSize,
|
||||
style: {
|
||||
borderRadius: '0',
|
||||
border: 'none',
|
||||
},
|
||||
const imgElementHeight = imgElement.offsetHeight;
|
||||
const imgElementWidth = imgElement.offsetWidth;
|
||||
const blob = await domtoimage.toBlob(imgElement, {
|
||||
width: imgElementWidth,
|
||||
height: imgElementHeight,
|
||||
});
|
||||
|
||||
if (await hasTransparentPixels(blob)) {
|
||||
@@ -91,7 +83,6 @@
|
||||
<FormModal size="small" title={$t('set_profile_picture')} {onClose} {onSubmit}>
|
||||
<div class="flex place-items-center items-center justify-center">
|
||||
<div
|
||||
bind:this={cropContainer}
|
||||
class="relative flex aspect-square w-62.5 overflow-hidden rounded-full border-4 border-immich-primary bg-immich-dark-primary dark:border-immich-dark-primary dark:bg-immich-primary"
|
||||
>
|
||||
<PhotoViewer bind:element={imgElement} cursor={{ current: asset }} />
|
||||
|
||||
Reference in New Issue
Block a user