mirror of
https://github.com/immich-app/immich.git
synced 2025-12-06 04:41:40 -08:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fd8c1b3c1 | ||
|
|
f3ba994186 | ||
|
|
b4a4abbf51 | ||
|
|
a0aea021a1 | ||
|
|
9033a99587 | ||
|
|
cc0cbd705e | ||
|
|
da580d4685 | ||
|
|
cb6d94c7a7 | ||
|
|
060300de8a | ||
|
|
c2ba1cc202 | ||
|
|
08db77db23 | ||
|
|
92dff839d0 | ||
|
|
fe1e09e51f | ||
|
|
f44669447f | ||
|
|
92412ca2f7 | ||
|
|
64d926581f | ||
|
|
c139e05170 | ||
|
|
0fe62298e1 | ||
|
|
e5794e6cfc | ||
|
|
f6cbc9db06 | ||
|
|
8dab5d3798 | ||
|
|
e864811a85 | ||
|
|
72a55c13b6 | ||
|
|
206412267a | ||
|
|
f780a56e24 | ||
|
|
7bbffccf76 | ||
|
|
05a446c259 | ||
|
|
4f725b95e1 | ||
|
|
64b92cb24c | ||
|
|
19f2f888ee | ||
|
|
d12b1c907d | ||
|
|
947c053c15 | ||
|
|
79592701dd | ||
|
|
39697cd973 | ||
|
|
10e518db42 | ||
|
|
72fa31f9e9 | ||
|
|
9871a04d54 | ||
|
|
ba01b40e7c | ||
|
|
f5a3d7ba23 | ||
|
|
d4a9eed4a1 | ||
|
|
9d8072b994 | ||
|
|
3c1fa22109 | ||
|
|
c0210bd6c0 | ||
|
|
a6ace5151c | ||
|
|
ede9c99adb | ||
|
|
ec7ab209f3 | ||
|
|
61bc24d7ea | ||
|
|
6c95eb22b7 | ||
|
|
aaea5cf1ad | ||
|
|
96d2e9b4c5 | ||
|
|
19740a3560 | ||
|
|
8a481e2ea1 | ||
|
|
ba105d9f19 | ||
|
|
065d885ca0 | ||
|
|
a07ae9b5b2 | ||
|
|
1869b1b41a | ||
|
|
995314446b | ||
|
|
a1691ddc0f | ||
|
|
071b271484 |
6
cli/package-lock.json
generated
6
cli/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@immich/cli",
|
||||
"version": "2.2.42",
|
||||
"version": "2.2.48",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@immich/cli",
|
||||
"version": "2.2.42",
|
||||
"version": "2.2.48",
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
"fast-glob": "^3.3.2",
|
||||
@@ -52,7 +52,7 @@
|
||||
},
|
||||
"../open-api/typescript-sdk": {
|
||||
"name": "@immich/sdk",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"dev": true,
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/cli",
|
||||
"version": "2.2.42",
|
||||
"version": "2.2.48",
|
||||
"description": "Command Line Interface (CLI) for Immich",
|
||||
"type": "module",
|
||||
"exports": "./dist/index.js",
|
||||
|
||||
@@ -48,6 +48,7 @@ services:
|
||||
vaapi-wsl: # use this for VAAPI if you're running Immich in WSL2
|
||||
devices:
|
||||
- /dev/dri:/dev/dri
|
||||
- /dev/dxg:/dev/dxg
|
||||
volumes:
|
||||
- /usr/lib/wsl:/usr/lib/wsl
|
||||
environment:
|
||||
|
||||
@@ -62,6 +62,10 @@ Instead of these experimental features, we recommend using the URL switching fea
|
||||
We are not actively developing these features and will not be able to provide support, but welcome contributions to improve them.
|
||||
Please discuss any large PRs with our dev team to ensure your time is not wasted.
|
||||
|
||||
### Why isn't the mobile app updated yet?
|
||||
|
||||
The app stores can take a few days to approve new builds of the app. If you're impatient, android APKs can be downloaded from the GitHub releases.
|
||||
|
||||
---
|
||||
|
||||
## Assets
|
||||
|
||||
@@ -8,22 +8,23 @@ For the full list, refer to the [Immich source code](https://github.com/immich-a
|
||||
|
||||
## Image formats
|
||||
|
||||
| Format | Extension(s) | Supported? | Notes |
|
||||
| :-------- | :---------------------------- | :----------------: | :-------------- |
|
||||
| `AVIF` | `.avif` | :white_check_mark: | |
|
||||
| `BMP` | `.bmp` | :white_check_mark: | |
|
||||
| `GIF` | `.gif` | :white_check_mark: | |
|
||||
| `HEIC` | `.heic` | :white_check_mark: | |
|
||||
| `HEIF` | `.heif` | :white_check_mark: | |
|
||||
| `JPEG` | `.webp` `.jpg` `.jpe` `.insp` | :white_check_mark: | |
|
||||
| `JPEG XL` | `.jxl` | :white_check_mark: | |
|
||||
| `PNG` | `.webp` | :white_check_mark: | |
|
||||
| `PSD` | `.psd` | :white_check_mark: | Adobe Photoshop |
|
||||
| `RAW` | `.raw` | :white_check_mark: | |
|
||||
| `RW2` | `.rw2` | :white_check_mark: | |
|
||||
| `SVG` | `.svg` | :white_check_mark: | |
|
||||
| `TIFF` | `.tif` `.tiff` | :white_check_mark: | |
|
||||
| `WEBP` | `.webp` | :white_check_mark: | |
|
||||
| Format | Extension(s) | Supported? | Notes |
|
||||
| :---------- | :---------------------------- | :----------------: | :-------------- |
|
||||
| `AVIF` | `.avif` | :white_check_mark: | |
|
||||
| `BMP` | `.bmp` | :white_check_mark: | |
|
||||
| `GIF` | `.gif` | :white_check_mark: | |
|
||||
| `HEIC` | `.heic` | :white_check_mark: | |
|
||||
| `HEIF` | `.heif` | :white_check_mark: | |
|
||||
| `JPEG 2000` | `.jp2` | :white_check_mark: | |
|
||||
| `JPEG` | `.webp` `.jpg` `.jpe` `.insp` | :white_check_mark: | |
|
||||
| `JPEG XL` | `.jxl` | :white_check_mark: | |
|
||||
| `PNG` | `.webp` | :white_check_mark: | |
|
||||
| `PSD` | `.psd` | :white_check_mark: | Adobe Photoshop |
|
||||
| `RAW` | `.raw` | :white_check_mark: | |
|
||||
| `RW2` | `.rw2` | :white_check_mark: | |
|
||||
| `SVG` | `.svg` | :white_check_mark: | |
|
||||
| `TIFF` | `.tif` `.tiff` | :white_check_mark: | |
|
||||
| `WEBP` | `.webp` | :white_check_mark: | |
|
||||
|
||||
## Video formats
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ The script will perform the following actions:
|
||||
1. Download [docker-compose.yml](https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml), and the [.env](https://github.com/immich-app/immich/releases/latest/download/example.env) file from the main branch of the [repository](https://github.com/immich-app/immich).
|
||||
2. Start the containers.
|
||||
|
||||
The web application will be available at `http://<machine-ip-address>:2283`, and the server URL for the mobile app will be `http://<machine-ip-address>:2283/api`
|
||||
The web application and mobile app will be available at `http://<machine-ip-address>:2283`
|
||||
|
||||
The directory which is used to store the library files is `./immich-app` relative to the current directory.
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
Login to the mobile app with the server endpoint URL at `http://<machine-ip-address>:2283/api`
|
||||
Login to the mobile app with the server endpoint URL at `http://<machine-ip-address>:2283`
|
||||
|
||||
<img src={require('./img/sign-in-phone.webp').default} width='50%' title='Mobile App Sign In' />
|
||||
|
||||
@@ -99,6 +99,11 @@ const projects: CommunityProjectProps[] = [
|
||||
description: 'Downloads a configurable number of random photos based on people or album ID.',
|
||||
url: 'https://github.com/jon6fingrs/immich-dl',
|
||||
},
|
||||
{
|
||||
title: 'Immich Upload Optimizer',
|
||||
description: 'Automatically optimize files uploaded to Immich in order to save storage space',
|
||||
url: 'https://github.com/miguelangel-nubla/immich-upload-optimizer',
|
||||
},
|
||||
];
|
||||
|
||||
function CommunityProject({ title, description, url }: CommunityProjectProps): JSX.Element {
|
||||
|
||||
24
docs/static/archived-versions.json
vendored
24
docs/static/archived-versions.json
vendored
@@ -1,4 +1,28 @@
|
||||
[
|
||||
{
|
||||
"label": "v1.125.7",
|
||||
"url": "https://v1.125.7.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.6",
|
||||
"url": "https://v1.125.6.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.5",
|
||||
"url": "https://v1.125.5.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.4",
|
||||
"url": "https://v1.125.4.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.3",
|
||||
"url": "https://v1.125.3.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.2",
|
||||
"url": "https://v1.125.2.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.1",
|
||||
"url": "https://v1.125.1.archive.immich.app"
|
||||
|
||||
8
e2e/package-lock.json
generated
8
e2e/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "immich-e2e",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "immich-e2e",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"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.42",
|
||||
"version": "2.2.48",
|
||||
"dev": true,
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
@@ -92,7 +92,7 @@
|
||||
},
|
||||
"../open-api/typescript-sdk": {
|
||||
"name": "@immich/sdk",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"dev": true,
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-e2e",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
|
||||
@@ -22,79 +22,92 @@ const user1NotShared = 'user1NotShared';
|
||||
const user2SharedUser = 'user2SharedUser';
|
||||
const user2SharedLink = 'user2SharedLink';
|
||||
const user2NotShared = 'user2NotShared';
|
||||
const user4DeletedAsset = 'user4DeletedAsset';
|
||||
const user4Empty = 'user4Empty';
|
||||
|
||||
describe('/albums', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let user1: LoginResponseDto;
|
||||
let user1Asset1: AssetMediaResponseDto;
|
||||
let user1Asset2: AssetMediaResponseDto;
|
||||
let user4Asset1: AssetMediaResponseDto;
|
||||
let user1Albums: AlbumResponseDto[];
|
||||
let user2: LoginResponseDto;
|
||||
let user2Albums: AlbumResponseDto[];
|
||||
let deletedAssetAlbum: AlbumResponseDto;
|
||||
let user3: LoginResponseDto; // deleted
|
||||
let user4: LoginResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
|
||||
admin = await utils.adminSetup();
|
||||
|
||||
[user1, user2, user3] = await Promise.all([
|
||||
[user1, user2, user3, user4] = await Promise.all([
|
||||
utils.userSetup(admin.accessToken, createUserDto.user1),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user2),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user3),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user4),
|
||||
]);
|
||||
|
||||
[user1Asset1, user1Asset2] = await Promise.all([
|
||||
[user1Asset1, user1Asset2, user4Asset1] = await Promise.all([
|
||||
utils.createAsset(user1.accessToken, { isFavorite: true }),
|
||||
utils.createAsset(user1.accessToken),
|
||||
utils.createAsset(user1.accessToken),
|
||||
]);
|
||||
|
||||
user1Albums = await Promise.all([
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1SharedEditorUser,
|
||||
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Editor }],
|
||||
assetIds: [user1Asset1.id],
|
||||
}),
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1SharedLink,
|
||||
assetIds: [user1Asset1.id],
|
||||
}),
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1NotShared,
|
||||
assetIds: [user1Asset1.id, user1Asset2.id],
|
||||
}),
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1SharedViewerUser,
|
||||
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Viewer }],
|
||||
assetIds: [user1Asset1.id],
|
||||
[user1Albums, user2Albums, deletedAssetAlbum] = await Promise.all([
|
||||
Promise.all([
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1SharedEditorUser,
|
||||
albumUsers: [
|
||||
{ userId: admin.userId, role: AlbumUserRole.Editor },
|
||||
{ userId: user2.userId, role: AlbumUserRole.Editor },
|
||||
],
|
||||
assetIds: [user1Asset1.id],
|
||||
}),
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1SharedLink,
|
||||
assetIds: [user1Asset1.id],
|
||||
}),
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1NotShared,
|
||||
assetIds: [user1Asset1.id, user1Asset2.id],
|
||||
}),
|
||||
utils.createAlbum(user1.accessToken, {
|
||||
albumName: user1SharedViewerUser,
|
||||
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Viewer }],
|
||||
assetIds: [user1Asset1.id],
|
||||
}),
|
||||
]),
|
||||
Promise.all([
|
||||
utils.createAlbum(user2.accessToken, {
|
||||
albumName: user2SharedUser,
|
||||
albumUsers: [
|
||||
{ userId: user1.userId, role: AlbumUserRole.Editor },
|
||||
{ userId: user3.userId, role: AlbumUserRole.Editor },
|
||||
],
|
||||
}),
|
||||
utils.createAlbum(user2.accessToken, { albumName: user2SharedLink }),
|
||||
utils.createAlbum(user2.accessToken, { albumName: user2NotShared }),
|
||||
]),
|
||||
utils.createAlbum(user4.accessToken, { albumName: user4DeletedAsset }),
|
||||
utils.createAlbum(user4.accessToken, { albumName: user4Empty }),
|
||||
utils.createAlbum(user3.accessToken, {
|
||||
albumName: 'Deleted',
|
||||
albumUsers: [{ userId: user1.userId, role: AlbumUserRole.Editor }],
|
||||
}),
|
||||
]);
|
||||
|
||||
user2Albums = await Promise.all([
|
||||
utils.createAlbum(user2.accessToken, {
|
||||
albumName: user2SharedUser,
|
||||
albumUsers: [
|
||||
{ userId: user1.userId, role: AlbumUserRole.Editor },
|
||||
{ userId: user3.userId, role: AlbumUserRole.Editor },
|
||||
],
|
||||
}),
|
||||
utils.createAlbum(user2.accessToken, { albumName: user2SharedLink }),
|
||||
utils.createAlbum(user2.accessToken, { albumName: user2NotShared }),
|
||||
]);
|
||||
|
||||
await utils.createAlbum(user3.accessToken, {
|
||||
albumName: 'Deleted',
|
||||
albumUsers: [{ userId: user1.userId, role: AlbumUserRole.Editor }],
|
||||
});
|
||||
|
||||
await addAssetsToAlbum(
|
||||
{ id: user2Albums[0].id, bulkIdsDto: { ids: [user1Asset1.id, user1Asset2.id] } },
|
||||
{ headers: asBearerAuth(user1.accessToken) },
|
||||
);
|
||||
|
||||
user2Albums[0] = await getAlbumInfo({ id: user2Albums[0].id }, { headers: asBearerAuth(user2.accessToken) });
|
||||
|
||||
await Promise.all([
|
||||
addAssetsToAlbum(
|
||||
{ id: user2Albums[0].id, bulkIdsDto: { ids: [user1Asset1.id, user1Asset2.id] } },
|
||||
{ headers: asBearerAuth(user1.accessToken) },
|
||||
),
|
||||
addAssetsToAlbum(
|
||||
{ id: deletedAssetAlbum.id, bulkIdsDto: { ids: [user4Asset1.id] } },
|
||||
{ headers: asBearerAuth(user4.accessToken) },
|
||||
),
|
||||
// add shared link to user1SharedLink album
|
||||
utils.createSharedLink(user1.accessToken, {
|
||||
type: SharedLinkType.Album,
|
||||
@@ -107,7 +120,11 @@ describe('/albums', () => {
|
||||
}),
|
||||
]);
|
||||
|
||||
await deleteUserAdmin({ id: user3.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
[user2Albums[0]] = await Promise.all([
|
||||
getAlbumInfo({ id: user2Albums[0].id }, { headers: asBearerAuth(user2.accessToken) }),
|
||||
deleteUserAdmin({ id: user3.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) }),
|
||||
utils.deleteAssets(user1.accessToken, [user4Asset1.id]),
|
||||
]);
|
||||
});
|
||||
|
||||
describe('GET /albums', () => {
|
||||
@@ -284,6 +301,25 @@ describe('/albums', () => {
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(5);
|
||||
});
|
||||
|
||||
it('should return empty albums and albums where all assets are deleted', async () => {
|
||||
const { status, body } = await request(app).get('/albums').set('Authorization', `Bearer ${user4.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
ownerId: user4.userId,
|
||||
albumName: user4DeletedAsset,
|
||||
shared: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
ownerId: user4.userId,
|
||||
albumName: user4Empty,
|
||||
shared: false,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /albums/:id', () => {
|
||||
@@ -362,6 +398,26 @@ describe('/albums', () => {
|
||||
shared: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not count trashed assets', async () => {
|
||||
await utils.deleteAssets(user1.accessToken, [user1Asset2.id]);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get(`/albums/${user2Albums[0].id}?withoutAssets=true`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
...user2Albums[0],
|
||||
assets: [],
|
||||
assetCount: 1,
|
||||
lastModifiedAssetTimestamp: expect.any(String),
|
||||
endDate: expect.any(String),
|
||||
startDate: expect.any(String),
|
||||
albumUsers: expect.any(Array),
|
||||
shared: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /albums/statistics', () => {
|
||||
|
||||
@@ -3,11 +3,11 @@ import {
|
||||
AssetMediaStatus,
|
||||
AssetResponseDto,
|
||||
AssetTypeEnum,
|
||||
LoginResponseDto,
|
||||
SharedLinkType,
|
||||
getAssetInfo,
|
||||
getConfig,
|
||||
getMyUser,
|
||||
LoginResponseDto,
|
||||
SharedLinkType,
|
||||
updateConfig,
|
||||
} from '@immich/sdk';
|
||||
import { exiftool } from 'exiftool-vendored';
|
||||
@@ -19,7 +19,7 @@ import { Socket } from 'socket.io-client';
|
||||
import { createUserDto, uuidDto } from 'src/fixtures';
|
||||
import { makeRandomImage } from 'src/generators';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, asBearerAuth, tempDir, testAssetDir, utils } from 'src/utils';
|
||||
import { app, asBearerAuth, tempDir, TEN_TIMES, testAssetDir, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
@@ -41,8 +41,6 @@ const makeUploadDto = (options?: { omit: string }): Record<string, any> => {
|
||||
return dto;
|
||||
};
|
||||
|
||||
const TEN_TIMES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
const locationAssetFilepath = `${testAssetDir}/metadata/gps-position/thompson-springs.jpg`;
|
||||
const ratingAssetFilepath = `${testAssetDir}/metadata/rating/mongolels.jpg`;
|
||||
const facesAssetFilepath = `${testAssetDir}/metadata/faces/portrait.jpg`;
|
||||
@@ -703,6 +701,20 @@ describe('/asset', () => {
|
||||
expect(status).toEqual(200);
|
||||
});
|
||||
|
||||
it('should set the negative rating', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/assets/${user1Assets[0].id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ rating: -1 });
|
||||
expect(body).toMatchObject({
|
||||
id: user1Assets[0].id,
|
||||
exifInfo: expect.objectContaining({
|
||||
rating: -1,
|
||||
}),
|
||||
});
|
||||
expect(status).toEqual(200);
|
||||
});
|
||||
|
||||
it('should reject invalid rating', async () => {
|
||||
for (const test of [{ rating: 7 }, { rating: 3.5 }, { rating: null }]) {
|
||||
const { status, body } = await request(app)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { AssetMediaResponseDto, LoginResponseDto, deleteAssets, updateAsset } from '@immich/sdk';
|
||||
import { AssetMediaResponseDto, AssetResponseDto, deleteAssets, LoginResponseDto, updateAsset } from '@immich/sdk';
|
||||
import { DateTime } from 'luxon';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, asBearerAuth, testAssetDir, utils } from 'src/utils';
|
||||
import { app, asBearerAuth, TEN_TIMES, testAssetDir, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
const today = DateTime.now();
|
||||
@@ -462,6 +462,55 @@ describe('/search', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /search/random', () => {
|
||||
beforeAll(async () => {
|
||||
await Promise.all([
|
||||
utils.createAsset(admin.accessToken),
|
||||
utils.createAsset(admin.accessToken),
|
||||
utils.createAsset(admin.accessToken),
|
||||
utils.createAsset(admin.accessToken),
|
||||
utils.createAsset(admin.accessToken),
|
||||
utils.createAsset(admin.accessToken),
|
||||
]);
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, 'thumbnailGeneration');
|
||||
});
|
||||
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post('/search/random').send({ size: 1 });
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it.each(TEN_TIMES)('should return 1 random assets', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/search/random')
|
||||
.send({ size: 1 })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
const assets: AssetResponseDto[] = body;
|
||||
expect(assets.length).toBe(1);
|
||||
expect(assets[0].ownerId).toBe(admin.userId);
|
||||
});
|
||||
|
||||
it.each(TEN_TIMES)('should return 2 random assets', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/search/random')
|
||||
.send({ size: 2 })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
const assets: AssetResponseDto[] = body;
|
||||
expect(assets.length).toBe(2);
|
||||
expect(assets[0].ownerId).toBe(admin.userId);
|
||||
expect(assets[1].ownerId).toBe(admin.userId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /search/explore', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/search/explore');
|
||||
|
||||
@@ -356,5 +356,24 @@ describe('/admin/users', () => {
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should restore a user', async () => {
|
||||
const user = await utils.userSetup(admin.accessToken, createUserDto.create('restore'));
|
||||
|
||||
await deleteUserAdmin({ id: user.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.post(`/admin/users/${user.userId}/restore`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: user.userId,
|
||||
email: user.userEmail,
|
||||
status: 'active',
|
||||
deletedAt: null,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -76,6 +76,7 @@ export const immichCli = (args: string[]) =>
|
||||
export const immichAdmin = (args: string[]) =>
|
||||
executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', `immich-admin ${args.join(' ')}`]);
|
||||
export const specialCharStrings = ["'", '"', ',', '{', '}', '*'];
|
||||
export const TEN_TIMES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
const executeCommand = (command: string, args: string[]) => {
|
||||
let _resolve: (value: CommandResponse) => void;
|
||||
|
||||
@@ -53,7 +53,7 @@ show_friendly_message() {
|
||||
ip_address=$(hostname -I | awk '{print $1}')
|
||||
cat <<EOF
|
||||
Successfully deployed Immich!
|
||||
You can access the website at http://$ip_address:2283 and the server URL for the mobile app is http://$ip_address:2283/api
|
||||
You can access the website or the mobile app at http://$ip_address:2283
|
||||
---------------------------------------------------
|
||||
If you want to configure custom information of the server, including the database, Redis information, or the backup (or upload) location, etc.
|
||||
|
||||
|
||||
@@ -97,8 +97,8 @@ download:
|
||||
- file: mobile/assets/i18n/id-ID.json
|
||||
locale_code: id-ID
|
||||
- file: mobile/assets/i18n/gl.json
|
||||
locale_code: gl-ES
|
||||
locale_code: gl
|
||||
- file: mobile/assets/i18n/ga.json
|
||||
locale_code: ga-IE
|
||||
locale_code: ga
|
||||
- file: mobile/assets/i18n/tr-TR.json
|
||||
locale_code: tr-TR
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "machine-learning"
|
||||
version = "1.125.1"
|
||||
version = "1.125.7"
|
||||
description = ""
|
||||
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -35,8 +35,8 @@ platform :android do
|
||||
task: 'bundle',
|
||||
build_type: 'Release',
|
||||
properties: {
|
||||
"android.injected.version.code" => 177,
|
||||
"android.injected.version.name" => "1.125.1",
|
||||
"android.injected.version.code" => 182,
|
||||
"android.injected.version.name" => "1.125.7",
|
||||
}
|
||||
)
|
||||
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')
|
||||
|
||||
@@ -336,9 +336,9 @@
|
||||
"login_form_back_button_text": "الرجوع للخلف",
|
||||
"login_form_button_text": "تسجيل الدخول",
|
||||
"login_form_email_hint": "yoursemail@email.com",
|
||||
"login_form_endpoint_hint": "http: // your-server-ip: port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "url نقطة نهاية الخادم",
|
||||
"login_form_err_http": "يرجى تحديد http: // أو https: //",
|
||||
"login_form_err_http": "يرجى تحديد http:// أو https://",
|
||||
"login_form_err_invalid_email": "بريد إلكتروني خاطئ",
|
||||
"login_form_err_invalid_url": "URL غير صالح",
|
||||
"login_form_err_leading_whitespace": "قيادة المساحة البيضاء",
|
||||
@@ -670,4 +670,4 @@
|
||||
"viewer_unstack": "فك الكومه",
|
||||
"wifi_name": "WiFi Name",
|
||||
"your_wifi_name": "Your WiFi name"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Entra",
|
||||
"login_form_email_hint": "elteu@correu.cat",
|
||||
"login_form_endpoint_hint": "http://ip-del-servidor:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-del-servidor:port",
|
||||
"login_form_endpoint_url": "URL del servidor",
|
||||
"login_form_err_http": "Especifica http:// o https://",
|
||||
"login_form_err_invalid_email": "Adreça de correu electrònic no vàlida",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Zpět",
|
||||
"login_form_button_text": "Přihlásit se",
|
||||
"login_form_email_hint": "tvůje-mail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-tvého-serveru:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-tvého-serveru:port",
|
||||
"login_form_endpoint_url": "URL adresa serveru",
|
||||
"login_form_err_http": "Prosím, uveďte http:// nebo https://",
|
||||
"login_form_err_invalid_email": "Neplatný e-mail",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Tilbage",
|
||||
"login_form_button_text": "Log ind",
|
||||
"login_form_email_hint": "din-e-mail@e-mail.com",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Angiv venligst http:// eller https://",
|
||||
"login_form_err_invalid_email": "Ugyldig e-mail",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Zurück",
|
||||
"login_form_button_text": "Anmelden",
|
||||
"login_form_email_hint": "deine@email.de",
|
||||
"login_form_endpoint_hint": "http://deine-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://deine-server-ip:port",
|
||||
"login_form_endpoint_url": "Server-URL",
|
||||
"login_form_err_http": "Bitte gebe http:// oder https:// an",
|
||||
"login_form_err_invalid_email": "Ungültige E-Mail",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Πίσω",
|
||||
"login_form_button_text": "Σύνδεση",
|
||||
"login_form_email_hint": "to-email-sou@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-tou-server-sou:porta/api",
|
||||
"login_form_endpoint_hint": "http://ip-tou-server-sou:porta",
|
||||
"login_form_endpoint_url": "URL τελικού σημείου διακομιστή",
|
||||
"login_form_err_http": "Προσδιορίστε http:// ή https://",
|
||||
"login_form_err_invalid_email": "Μη έγκυρο email",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"advanced_settings_proxy_headers_subtitle": "Define proxy headers Immich should send with each network request",
|
||||
"advanced_settings_proxy_headers_title": "Proxy Headers",
|
||||
"advanced_settings_self_signed_ssl_subtitle": "Skips SSL certificate verification for the server endpoint. Required for self-signed certificates.",
|
||||
"advanced_settings_self_signed_ssl_title": "Allow self-signed SSL certificates",
|
||||
"advanced_settings_self_signed_ssl_title": "Allow self-signed SSL certificates (EXPERIMENTAL)",
|
||||
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||
"advanced_settings_tile_title": "Advanced",
|
||||
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||
@@ -175,7 +175,7 @@
|
||||
"client_cert_remove": "Remove",
|
||||
"client_cert_remove_msg": "Client certificate is removed",
|
||||
"client_cert_subtitle": "Supports PKCS12 (.p12, .pfx) format only. Certificate Import/Remove is available only before login",
|
||||
"client_cert_title": "SSL Client Certificate",
|
||||
"client_cert_title": "SSL Client Certificate (EXPERIMENTAL)",
|
||||
"common_add_to_album": "Add to album",
|
||||
"common_change_password": "Change Password",
|
||||
"common_create_new_album": "Create new album",
|
||||
@@ -248,6 +248,7 @@
|
||||
"download_waiting_to_retry": "Waiting to retry",
|
||||
"edit_date_time_dialog_date_time": "Date and Time",
|
||||
"edit_date_time_dialog_timezone": "Timezone",
|
||||
"edit_date_time_dialog_search_timezone": "Search timezone...",
|
||||
"edit_image_title": "Edit",
|
||||
"edit_location_dialog_title": "Location",
|
||||
"end_date": "End date",
|
||||
@@ -281,7 +282,7 @@
|
||||
"header_settings_field_validator_msg": "Value cannot be empty",
|
||||
"header_settings_header_name_input": "Header name",
|
||||
"header_settings_header_value_input": "Header value",
|
||||
"header_settings_page_title": "Proxy Headers",
|
||||
"header_settings_page_title": "Proxy Headers (EXPERIMENTAL)",
|
||||
"headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request",
|
||||
"headers_settings_tile_title": "Custom proxy headers",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
@@ -336,7 +337,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
@@ -670,4 +671,4 @@
|
||||
"viewer_unstack": "Un-Stack",
|
||||
"wifi_name": "WiFi Name",
|
||||
"your_wifi_name": "Your WiFi name"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Atrás",
|
||||
"login_form_button_text": "Iniciar Sesión",
|
||||
"login_form_email_hint": "tucorreo@correo.com",
|
||||
"login_form_endpoint_hint": "http://tu-ip-de-servidor:puerto/api",
|
||||
"login_form_endpoint_hint": "http://tu-ip-de-servidor:puerto",
|
||||
"login_form_endpoint_url": "URL del servidor",
|
||||
"login_form_err_http": "Por favor, especifique http:// o https://",
|
||||
"login_form_err_invalid_email": "Correo electrónico no válido",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Iniciar sesión",
|
||||
"login_form_email_hint": "tucorreo@correo.com",
|
||||
"login_form_endpoint_hint": "http://la-ip-de-tu-servidor:puerto/api",
|
||||
"login_form_endpoint_hint": "http://la-ip-de-tu-servidor:puerto",
|
||||
"login_form_endpoint_url": "URL del servidor",
|
||||
"login_form_err_http": "Por favor, especifique http:// o https://",
|
||||
"login_form_err_invalid_email": "Correo electrónico inválido",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Iniciar sesión",
|
||||
"login_form_email_hint": "tucorreo@correo.com",
|
||||
"login_form_endpoint_hint": "http://la-ip-de-tu-servidor:puerto/api",
|
||||
"login_form_endpoint_hint": "http://la-ip-de-tu-servidor:puerto",
|
||||
"login_form_endpoint_url": "URL del servidor",
|
||||
"login_form_err_http": "Por favor, especifique http:// o https://",
|
||||
"login_form_err_invalid_email": "Correo electrónico inválido",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Iniciar sesión",
|
||||
"login_form_email_hint": "tucorreo@correo.com",
|
||||
"login_form_endpoint_hint": "http://ip-de-tu-servidor:puerto/api",
|
||||
"login_form_endpoint_hint": "http://ip-de-tu-servidor:puerto",
|
||||
"login_form_endpoint_url": "URL del servidor",
|
||||
"login_form_err_http": "Por favor, especifique http:// o https://",
|
||||
"login_form_err_invalid_email": "Correo electrónico inválido",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Takaisin",
|
||||
"login_form_button_text": "Kirjaudu",
|
||||
"login_form_email_hint": "sahkopostisi@esimerkki.fi",
|
||||
"login_form_endpoint_hint": "http://palvelimesi-osoite:portti/api",
|
||||
"login_form_endpoint_hint": "http://palvelimesi-osoite:portti",
|
||||
"login_form_endpoint_url": "Palvelimen URL",
|
||||
"login_form_err_http": "Lisää http:// tai https://",
|
||||
"login_form_err_invalid_email": "Virheellinen sähköpostiosoite",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Connexion",
|
||||
"login_form_email_hint": "votrecourriel@email.com",
|
||||
"login_form_endpoint_hint": "http://adresse-ip-serveur:port/api",
|
||||
"login_form_endpoint_hint": "http://adresse-ip-serveur:port",
|
||||
"login_form_endpoint_url": "URL du point d'accès au serveur",
|
||||
"login_form_err_http": "Veuillez préciser http:// ou https://",
|
||||
"login_form_err_invalid_email": "Courriel invalide",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Retour",
|
||||
"login_form_button_text": "Connexion",
|
||||
"login_form_email_hint": "votreemail@email.com",
|
||||
"login_form_endpoint_hint": "http://adresse-ip-serveur:port/api",
|
||||
"login_form_endpoint_hint": "http://adresse-ip-serveur:port",
|
||||
"login_form_endpoint_url": "URL du point d'accès au serveur",
|
||||
"login_form_err_http": "Veuillez préciser http:// ou https://",
|
||||
"login_form_err_invalid_email": "E-mail invalide",
|
||||
|
||||
673
mobile/assets/i18n/ga.json
Normal file
673
mobile/assets/i18n/ga.json
Normal file
@@ -0,0 +1,673 @@
|
||||
{
|
||||
"action_common_back": "Back",
|
||||
"action_common_cancel": "Cancel",
|
||||
"action_common_clear": "Clear",
|
||||
"action_common_confirm": "Confirm",
|
||||
"action_common_save": "Save",
|
||||
"action_common_select": "Select",
|
||||
"action_common_update": "Update",
|
||||
"add_a_name": "Add a name",
|
||||
"add_endpoint": "Add endpoint",
|
||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
||||
"advanced_settings_log_level_title": "Log level: {}",
|
||||
"advanced_settings_prefer_remote_subtitle": "Some devices are painfully slow to load thumbnails from assets on the device. Activate this setting to load remote images instead.",
|
||||
"advanced_settings_prefer_remote_title": "Prefer remote images",
|
||||
"advanced_settings_proxy_headers_subtitle": "Define proxy headers Immich should send with each network request",
|
||||
"advanced_settings_proxy_headers_title": "Proxy Headers",
|
||||
"advanced_settings_self_signed_ssl_subtitle": "Skips SSL certificate verification for the server endpoint. Required for self-signed certificates.",
|
||||
"advanced_settings_self_signed_ssl_title": "Allow self-signed SSL certificates (EXPERIMENTAL)",
|
||||
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||
"advanced_settings_tile_title": "Advanced",
|
||||
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||
"album_info_card_backup_album_excluded": "EXCLUDED",
|
||||
"album_info_card_backup_album_included": "INCLUDED",
|
||||
"albums": "Albums",
|
||||
"album_thumbnail_card_item": "1 item",
|
||||
"album_thumbnail_card_items": "{} items",
|
||||
"album_thumbnail_card_shared": " · Shared",
|
||||
"album_thumbnail_owned": "Owned",
|
||||
"album_thumbnail_shared_by": "Shared by {}",
|
||||
"album_viewer_appbar_delete_confirm": "Are you sure you want to delete this album from your account?",
|
||||
"album_viewer_appbar_share_delete": "Delete album",
|
||||
"album_viewer_appbar_share_err_delete": "Failed to delete album",
|
||||
"album_viewer_appbar_share_err_leave": "Failed to leave album",
|
||||
"album_viewer_appbar_share_err_remove": "There are problems in removing assets from album",
|
||||
"album_viewer_appbar_share_err_title": "Failed to change album title",
|
||||
"album_viewer_appbar_share_leave": "Leave album",
|
||||
"album_viewer_appbar_share_remove": "Remove from album",
|
||||
"album_viewer_appbar_share_to": "Share To",
|
||||
"album_viewer_page_share_add_users": "Add users",
|
||||
"all": "All",
|
||||
"all_people_page_title": "People",
|
||||
"all_videos_page_title": "Videos",
|
||||
"app_bar_signout_dialog_content": "Are you sure you want to sign out?",
|
||||
"app_bar_signout_dialog_ok": "Yes",
|
||||
"app_bar_signout_dialog_title": "Sign out",
|
||||
"archived": "Archived",
|
||||
"archive_page_no_archived_assets": "No archived assets found",
|
||||
"archive_page_title": "Archive ({})",
|
||||
"asset_action_delete_err_read_only": "Cannot delete read only asset(s), skipping",
|
||||
"asset_action_share_err_offline": "Cannot fetch offline asset(s), skipping",
|
||||
"asset_list_group_by_sub_title": "Group by",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||
"asset_list_layout_settings_group_by": "Group assets by",
|
||||
"asset_list_layout_settings_group_by_month": "Month",
|
||||
"asset_list_layout_settings_group_by_month_day": "Month + day",
|
||||
"asset_list_layout_sub_title": "Layout",
|
||||
"asset_list_settings_subtitle": "Photo grid layout settings",
|
||||
"asset_list_settings_title": "Photo Grid",
|
||||
"asset_restored_successfully": "Asset restored successfully",
|
||||
"assets_deleted_permanently": "{} asset(s) deleted permanently",
|
||||
"assets_deleted_permanently_from_server": "{} asset(s) deleted permanently from the Immich server",
|
||||
"assets_removed_permanently_from_device": "{} asset(s) removed permanently from your device",
|
||||
"assets_restored_successfully": "{} asset(s) restored successfully",
|
||||
"assets_trashed": "{} asset(s) trashed",
|
||||
"assets_trashed_from_server": "{} asset(s) trashed from the Immich server",
|
||||
"asset_viewer_settings_subtitle": "Manage your gallery viewer settings",
|
||||
"asset_viewer_settings_title": "Asset Viewer",
|
||||
"automatic_endpoint_switching_subtitle": "Connect locally over designated Wi-Fi when available and use alternative connections elsewhere",
|
||||
"automatic_endpoint_switching_title": "Automatic URL switching",
|
||||
"background_location_permission": "Background location permission",
|
||||
"background_location_permission_content": "In order to switch networks when running in the background, Immich must *always* have precise location access so the app can read the Wi-Fi network's name",
|
||||
"backup_album_selection_page_albums_device": "Albums on device ({})",
|
||||
"backup_album_selection_page_albums_tap": "Tap to include, double tap to exclude",
|
||||
"backup_album_selection_page_assets_scatter": "Assets can scatter across multiple albums. Thus, albums can be included or excluded during the backup process.",
|
||||
"backup_album_selection_page_select_albums": "Select albums",
|
||||
"backup_album_selection_page_selection_info": "Selection Info",
|
||||
"backup_album_selection_page_total_assets": "Total unique assets",
|
||||
"backup_all": "All",
|
||||
"backup_background_service_backup_failed_message": "Failed to backup assets. Retrying…",
|
||||
"backup_background_service_connection_failed_message": "Failed to connect to the server. Retrying…",
|
||||
"backup_background_service_current_upload_notification": "Uploading {}",
|
||||
"backup_background_service_default_notification": "Checking for new assets…",
|
||||
"backup_background_service_error_title": "Backup error",
|
||||
"backup_background_service_in_progress_notification": "Backing up your assets…",
|
||||
"backup_background_service_upload_failure_notification": "Failed to upload {}",
|
||||
"backup_controller_page_albums": "Backup Albums",
|
||||
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
|
||||
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
|
||||
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
|
||||
"backup_controller_page_background_battery_info_link": "Show me how",
|
||||
"backup_controller_page_background_battery_info_message": "For the best background backup experience, please disable any battery optimizations restricting background activity for Immich.\n\nSince this is device-specific, please lookup the required information for your device manufacturer.",
|
||||
"backup_controller_page_background_battery_info_ok": "OK",
|
||||
"backup_controller_page_background_battery_info_title": "Battery optimizations",
|
||||
"backup_controller_page_background_charging": "Only while charging",
|
||||
"backup_controller_page_background_configure_error": "Failed to configure the background service",
|
||||
"backup_controller_page_background_delay": "Delay new assets backup: {}",
|
||||
"backup_controller_page_background_description": "Turn on the background service to automatically backup any new assets without needing to open the app",
|
||||
"backup_controller_page_background_is_off": "Automatic background backup is off",
|
||||
"backup_controller_page_background_is_on": "Automatic background backup is on",
|
||||
"backup_controller_page_background_turn_off": "Turn off background service",
|
||||
"backup_controller_page_background_turn_on": "Turn on background service",
|
||||
"backup_controller_page_background_wifi": "Only on WiFi",
|
||||
"backup_controller_page_backup": "Backup",
|
||||
"backup_controller_page_backup_selected": "Selected: ",
|
||||
"backup_controller_page_backup_sub": "Backed up photos and videos",
|
||||
"backup_controller_page_cancel": "Cancel",
|
||||
"backup_controller_page_created": "Created on: {}",
|
||||
"backup_controller_page_desc_backup": "Turn on foreground backup to automatically upload new assets to the server when opening the app.",
|
||||
"backup_controller_page_excluded": "Excluded: ",
|
||||
"backup_controller_page_failed": "Failed ({})",
|
||||
"backup_controller_page_filename": "File name: {} [{}]",
|
||||
"backup_controller_page_id": "ID: {}",
|
||||
"backup_controller_page_info": "Backup Information",
|
||||
"backup_controller_page_none_selected": "None selected",
|
||||
"backup_controller_page_remainder": "Remainder",
|
||||
"backup_controller_page_remainder_sub": "Remaining photos and videos to back up from selection",
|
||||
"backup_controller_page_select": "Select",
|
||||
"backup_controller_page_server_storage": "Server Storage",
|
||||
"backup_controller_page_start_backup": "Start Backup",
|
||||
"backup_controller_page_status_off": "Automatic foreground backup is off",
|
||||
"backup_controller_page_status_on": "Automatic foreground backup is on",
|
||||
"backup_controller_page_storage_format": "{} of {} used",
|
||||
"backup_controller_page_to_backup": "Albums to be backed up",
|
||||
"backup_controller_page_total": "Total",
|
||||
"backup_controller_page_total_sub": "All unique photos and videos from selected albums",
|
||||
"backup_controller_page_turn_off": "Turn off foreground backup",
|
||||
"backup_controller_page_turn_on": "Turn on foreground backup",
|
||||
"backup_controller_page_uploading_file_info": "Uploading file info",
|
||||
"backup_err_only_album": "Cannot remove the only album",
|
||||
"backup_info_card_assets": "assets",
|
||||
"backup_manual_cancelled": "Cancelled",
|
||||
"backup_manual_failed": "Failed",
|
||||
"backup_manual_in_progress": "Upload already in progress. Try after sometime",
|
||||
"backup_manual_success": "Success",
|
||||
"backup_manual_title": "Upload status",
|
||||
"backup_options_page_title": "Backup options",
|
||||
"backup_setting_subtitle": "Manage background and foreground upload settings",
|
||||
"cache_settings_album_thumbnails": "Library page thumbnails ({} assets)",
|
||||
"cache_settings_clear_cache_button": "Clear cache",
|
||||
"cache_settings_clear_cache_button_title": "Clears the app's cache. This will significantly impact the app's performance until the cache has rebuilt.",
|
||||
"cache_settings_duplicated_assets_clear_button": "CLEAR",
|
||||
"cache_settings_duplicated_assets_subtitle": "Photos and videos that are black listed by the app",
|
||||
"cache_settings_duplicated_assets_title": "Duplicated Assets ({})",
|
||||
"cache_settings_image_cache_size": "Image cache size ({} assets)",
|
||||
"cache_settings_statistics_album": "Library thumbnails",
|
||||
"cache_settings_statistics_assets": "{} assets ({})",
|
||||
"cache_settings_statistics_full": "Full images",
|
||||
"cache_settings_statistics_shared": "Shared album thumbnails",
|
||||
"cache_settings_statistics_thumbnail": "Thumbnails",
|
||||
"cache_settings_statistics_title": "Cache usage",
|
||||
"cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application",
|
||||
"cache_settings_thumbnail_size": "Thumbnail cache size ({} assets)",
|
||||
"cache_settings_tile_subtitle": "Control the local storage behaviour",
|
||||
"cache_settings_tile_title": "Local Storage",
|
||||
"cache_settings_title": "Caching Settings",
|
||||
"cancel": "Cancel",
|
||||
"canceled": "Canceled",
|
||||
"change_display_order": "Change display order",
|
||||
"change_password_form_confirm_password": "Confirm Password",
|
||||
"change_password_form_description": "Hi {name},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
|
||||
"change_password_form_new_password": "New Password",
|
||||
"change_password_form_password_mismatch": "Passwords do not match",
|
||||
"change_password_form_reenter_new_password": "Re-enter New Password",
|
||||
"check_corrupt_asset_backup": "Check for corrupt asset backups",
|
||||
"check_corrupt_asset_backup_button": "Perform check",
|
||||
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
|
||||
"client_cert_dialog_msg_confirm": "OK",
|
||||
"client_cert_enter_password": "Enter Password",
|
||||
"client_cert_import": "Import",
|
||||
"client_cert_import_success_msg": "Client certificate is imported",
|
||||
"client_cert_invalid_msg": "Invalid certificate file or wrong password",
|
||||
"client_cert_remove": "Remove",
|
||||
"client_cert_remove_msg": "Client certificate is removed",
|
||||
"client_cert_subtitle": "Supports PKCS12 (.p12, .pfx) format only. Certificate Import/Remove is available only before login",
|
||||
"client_cert_title": "SSL Client Certificate (EXPERIMENTAL)",
|
||||
"common_add_to_album": "Add to album",
|
||||
"common_change_password": "Change Password",
|
||||
"common_create_new_album": "Create new album",
|
||||
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
|
||||
"common_shared": "Shared",
|
||||
"completed": "Completed",
|
||||
"contextual_search": "Sunrise on the beach",
|
||||
"control_bottom_app_bar_add_to_album": "Add to album",
|
||||
"control_bottom_app_bar_album_info": "{} items",
|
||||
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
||||
"control_bottom_app_bar_archive": "Archive",
|
||||
"control_bottom_app_bar_create_new_album": "Create new album",
|
||||
"control_bottom_app_bar_delete": "Delete",
|
||||
"control_bottom_app_bar_delete_from_immich": "Delete from Immich",
|
||||
"control_bottom_app_bar_delete_from_local": "Delete from device",
|
||||
"control_bottom_app_bar_download": "Download",
|
||||
"control_bottom_app_bar_edit": "Edit",
|
||||
"control_bottom_app_bar_edit_location": "Edit Location",
|
||||
"control_bottom_app_bar_edit_time": "Edit Date & Time",
|
||||
"control_bottom_app_bar_favorite": "Favorite",
|
||||
"control_bottom_app_bar_share": "Share",
|
||||
"control_bottom_app_bar_share_to": "Share To",
|
||||
"control_bottom_app_bar_stack": "Stack",
|
||||
"control_bottom_app_bar_trash_from_immich": "Move to Trash",
|
||||
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||
"control_bottom_app_bar_unfavorite": "Unfavorite",
|
||||
"control_bottom_app_bar_upload": "Upload",
|
||||
"create_album": "Create album",
|
||||
"create_album_page_untitled": "Untitled",
|
||||
"create_new": "CREATE NEW",
|
||||
"create_shared_album_page_create": "Create",
|
||||
"create_shared_album_page_share": "Share",
|
||||
"create_shared_album_page_share_add_assets": "ADD ASSETS",
|
||||
"create_shared_album_page_share_select_photos": "Select Photos",
|
||||
"crop": "Crop",
|
||||
"curated_location_page_title": "Places",
|
||||
"curated_object_page_title": "Things",
|
||||
"current_server_address": "Current server address",
|
||||
"daily_title_text_date": "E, MMM dd",
|
||||
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
||||
"date_format": "E, LLL d, y • h:mm a",
|
||||
"delete_dialog_alert": "These items will be permanently deleted from Immich and from your device",
|
||||
"delete_dialog_alert_local": "These items will be permanently removed from your device but still be available on the Immich server",
|
||||
"delete_dialog_alert_local_non_backed_up": "Some of the items aren't backed up to Immich and will be permanently removed from your device",
|
||||
"delete_dialog_alert_remote": "These items will be permanently deleted from the Immich server",
|
||||
"delete_dialog_cancel": "Cancel",
|
||||
"delete_dialog_ok": "Delete",
|
||||
"delete_dialog_ok_force": "Delete Anyway",
|
||||
"delete_dialog_title": "Delete Permanently",
|
||||
"delete_local_dialog_ok_backed_up_only": "Delete Backed Up Only",
|
||||
"delete_local_dialog_ok_force": "Delete Anyway",
|
||||
"delete_shared_link_dialog_content": "Are you sure you want to delete this shared link?",
|
||||
"delete_shared_link_dialog_title": "Delete Shared Link",
|
||||
"description_input_hint_text": "Add description...",
|
||||
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||
"download_canceled": "Download canceled",
|
||||
"download_complete": "Download complete",
|
||||
"download_enqueue": "Download enqueued",
|
||||
"download_error": "Download Error",
|
||||
"download_failed": "Download failed",
|
||||
"download_filename": "file: {}",
|
||||
"download_finished": "Download finished",
|
||||
"downloading": "Downloading...",
|
||||
"downloading_media": "Downloading media",
|
||||
"download_notfound": "Download not found",
|
||||
"download_paused": "Download paused",
|
||||
"download_started": "Download started",
|
||||
"download_sucess": "Download success",
|
||||
"download_sucess_android": "The media has been downloaded to DCIM/Immich",
|
||||
"download_waiting_to_retry": "Waiting to retry",
|
||||
"edit_date_time_dialog_date_time": "Date and Time",
|
||||
"edit_date_time_dialog_timezone": "Timezone",
|
||||
"edit_image_title": "Edit",
|
||||
"edit_location_dialog_title": "Location",
|
||||
"end_date": "End date",
|
||||
"enqueued": "Enqueued",
|
||||
"enter_wifi_name": "Enter WiFi name",
|
||||
"error_change_sort_album": "Failed to change album sort order",
|
||||
"error_saving_image": "Error: {}",
|
||||
"exif_bottom_sheet_description": "Add Description...",
|
||||
"exif_bottom_sheet_details": "DETAILS",
|
||||
"exif_bottom_sheet_location": "LOCATION",
|
||||
"exif_bottom_sheet_location_add": "Add a location",
|
||||
"exif_bottom_sheet_people": "PEOPLE",
|
||||
"exif_bottom_sheet_person_add_person": "Add name",
|
||||
"experimental_settings_new_asset_list_subtitle": "Work in progress",
|
||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"experimental_settings_subtitle": "Use at your own risk!",
|
||||
"experimental_settings_title": "Experimental",
|
||||
"external_network": "External network",
|
||||
"external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
|
||||
"failed": "Failed",
|
||||
"favorites": "Favorites",
|
||||
"favorites_page_no_favorites": "No favorite assets found",
|
||||
"favorites_page_title": "Favorites",
|
||||
"filename_search": "File name or extension",
|
||||
"filter": "Filter",
|
||||
"get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network",
|
||||
"grant_permission": "Grant permission",
|
||||
"haptic_feedback_switch": "Enable haptic feedback",
|
||||
"haptic_feedback_title": "Haptic Feedback",
|
||||
"header_settings_add_header_tip": "Add Header",
|
||||
"header_settings_field_validator_msg": "Value cannot be empty",
|
||||
"header_settings_header_name_input": "Header name",
|
||||
"header_settings_header_value_input": "Header value",
|
||||
"header_settings_page_title": "Proxy Headers (EXPERIMENTAL)",
|
||||
"headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request",
|
||||
"headers_settings_tile_title": "Custom proxy headers",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"home_page_album_err_partner": "Can not add partner assets to an album yet, skipping",
|
||||
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||
"home_page_archive_err_partner": "Can not archive partner assets, skipping",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"home_page_delete_err_partner": "Can not delete partner assets, skipping",
|
||||
"home_page_delete_remote_err_local": "Local assets in delete remote selection, skipping",
|
||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
||||
"home_page_favorite_err_partner": "Can not favorite partner assets yet, skipping",
|
||||
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
|
||||
"home_page_share_err_local": "Can not share local assets via link, skipping",
|
||||
"home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping",
|
||||
"ignore_icloud_photos": "Ignore iCloud photos",
|
||||
"ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server",
|
||||
"image_saved_successfully": "Image saved",
|
||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
||||
"image_viewer_page_state_provider_download_started": "Download Started",
|
||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
||||
"image_viewer_page_state_provider_share_error": "Share Error",
|
||||
"invalid_date": "Invalid date",
|
||||
"invalid_date_format": "Invalid date format",
|
||||
"library": "Library",
|
||||
"library_page_albums": "Albums",
|
||||
"library_page_archive": "Archive",
|
||||
"library_page_device_albums": "Albums on Device",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "New album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_asset_count": "Number of assets",
|
||||
"library_page_sort_created": "Created date",
|
||||
"library_page_sort_last_modified": "Last modified",
|
||||
"library_page_sort_most_oldest_photo": "Oldest photo",
|
||||
"library_page_sort_most_recent_photo": "Most recent photo",
|
||||
"library_page_sort_title": "Album title",
|
||||
"local_network": "Local network",
|
||||
"local_network_sheet_info": "The app will connect to the server through this URL when using the specified Wi-Fi network",
|
||||
"location_permission": "Location permission",
|
||||
"location_permission_content": "In order to use the auto-switching feature, Immich needs precise location permission so it can read the current WiFi network's name",
|
||||
"location_picker_choose_on_map": "Choose on map",
|
||||
"location_picker_latitude": "Latitude",
|
||||
"location_picker_latitude_error": "Enter a valid latitude",
|
||||
"location_picker_latitude_hint": "Enter your latitude here",
|
||||
"location_picker_longitude": "Longitude",
|
||||
"location_picker_longitude_error": "Enter a valid longitude",
|
||||
"location_picker_longitude_hint": "Enter your longitude here",
|
||||
"login_disabled": "Login has been disabled",
|
||||
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
"login_form_err_invalid_url": "Invalid URL",
|
||||
"login_form_err_leading_whitespace": "Leading whitespace",
|
||||
"login_form_err_trailing_whitespace": "Trailing whitespace",
|
||||
"login_form_failed_get_oauth_server_config": "Error logging using OAuth, check server URL",
|
||||
"login_form_failed_get_oauth_server_disable": "OAuth feature is not available on this server",
|
||||
"login_form_failed_login": "Error logging you in, check server URL, email and password",
|
||||
"login_form_handshake_exception": "There was an Handshake Exception with the server. Enable self-signed certificate support in the settings if you are using a self-signed certificate.",
|
||||
"login_form_label_email": "Email",
|
||||
"login_form_label_password": "Password",
|
||||
"login_form_next_button": "Next",
|
||||
"login_form_password_hint": "password",
|
||||
"login_form_save_login": "Stay logged in",
|
||||
"login_form_server_empty": "Enter a server URL.",
|
||||
"login_form_server_error": "Could not connect to server.",
|
||||
"login_password_changed_error": "There was an error updating your password",
|
||||
"login_password_changed_success": "Password updated successfully",
|
||||
"map_assets_in_bound": "{} photo",
|
||||
"map_assets_in_bounds": "{} photos",
|
||||
"map_cannot_get_user_location": "Cannot get user's location",
|
||||
"map_location_dialog_cancel": "Cancel",
|
||||
"map_location_dialog_yes": "Yes",
|
||||
"map_location_picker_page_use_location": "Use this location",
|
||||
"map_location_service_disabled_content": "Location service needs to be enabled to display assets from your current location. Do you want to enable it now?",
|
||||
"map_location_service_disabled_title": "Location Service disabled",
|
||||
"map_no_assets_in_bounds": "No photos in this area",
|
||||
"map_no_location_permission_content": "Location permission is needed to display assets from your current location. Do you want to allow it now?",
|
||||
"map_no_location_permission_title": "Location Permission denied",
|
||||
"map_settings_dark_mode": "Dark mode",
|
||||
"map_settings_date_range_option_all": "All",
|
||||
"map_settings_date_range_option_day": "Past 24 hours",
|
||||
"map_settings_date_range_option_days": "Past {} days",
|
||||
"map_settings_date_range_option_year": "Past year",
|
||||
"map_settings_date_range_option_years": "Past {} years",
|
||||
"map_settings_dialog_cancel": "Cancel",
|
||||
"map_settings_dialog_save": "Save",
|
||||
"map_settings_dialog_title": "Map Settings",
|
||||
"map_settings_include_show_archived": "Include Archived",
|
||||
"map_settings_include_show_partners": "Include Partners",
|
||||
"map_settings_only_relative_range": "Date range",
|
||||
"map_settings_only_show_favorites": "Show Favorite Only",
|
||||
"map_settings_theme_settings": "Map Theme",
|
||||
"map_zoom_to_see_photos": "Zoom out to see photos",
|
||||
"memories_all_caught_up": "All caught up",
|
||||
"memories_check_back_tomorrow": "Check back tomorrow for more memories",
|
||||
"memories_start_over": "Start Over",
|
||||
"memories_swipe_to_close": "Swipe up to close",
|
||||
"memories_year_ago": "A year ago",
|
||||
"memories_years_ago": "{} years ago",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"motion_photos_page_title": "Motion Photos",
|
||||
"multiselect_grid_edit_date_time_err_read_only": "Cannot edit date of read only asset(s), skipping",
|
||||
"multiselect_grid_edit_gps_err_read_only": "Cannot edit location of read only asset(s), skipping",
|
||||
"my_albums": "My albums",
|
||||
"networking_settings": "Networking",
|
||||
"networking_subtitle": "Manage the server endpoint settings",
|
||||
"no_assets_to_show": "No assets to show",
|
||||
"no_name": "No name",
|
||||
"notification_permission_dialog_cancel": "Cancel",
|
||||
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
|
||||
"notification_permission_dialog_settings": "Settings",
|
||||
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
|
||||
"notification_permission_list_tile_enable_button": "Enable Notifications",
|
||||
"notification_permission_list_tile_title": "Notification Permission",
|
||||
"not_selected": "Not selected",
|
||||
"on_this_device": "On this device",
|
||||
"partner_list_user_photos": "{user}'s photos",
|
||||
"partner_list_view_all": "View all",
|
||||
"partner_page_add_partner": "Add partner",
|
||||
"partner_page_empty_message": "Your photos are not yet shared with any partner.",
|
||||
"partner_page_no_more_users": "No more users to add",
|
||||
"partner_page_partner_add_failed": "Failed to add partner",
|
||||
"partner_page_select_partner": "Select partner",
|
||||
"partner_page_shared_to_title": "Shared to",
|
||||
"partner_page_stop_sharing_content": "{} will no longer be able to access your photos.",
|
||||
"partner_page_stop_sharing_title": "Stop sharing your photos?",
|
||||
"partner_page_title": "Partner",
|
||||
"partners": "Partners",
|
||||
"paused": "Paused",
|
||||
"people": "People",
|
||||
"permission_onboarding_back": "Back",
|
||||
"permission_onboarding_continue_anyway": "Continue anyway",
|
||||
"permission_onboarding_get_started": "Get started",
|
||||
"permission_onboarding_go_to_settings": "Go to settings",
|
||||
"permission_onboarding_grant_permission": "Grant permission",
|
||||
"permission_onboarding_log_out": "Log out",
|
||||
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
|
||||
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
|
||||
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
|
||||
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
|
||||
"places": "Places",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
"preferences_settings_title": "Preferences",
|
||||
"profile_drawer_app_logs": "Logs",
|
||||
"profile_drawer_client_out_of_date_major": "Mobile App is out of date. Please update to the latest major version.",
|
||||
"profile_drawer_client_out_of_date_minor": "Mobile App is out of date. Please update to the latest minor version.",
|
||||
"profile_drawer_client_server_up_to_date": "Client and Server are up-to-date",
|
||||
"profile_drawer_documentation": "Documentation",
|
||||
"profile_drawer_github": "GitHub",
|
||||
"profile_drawer_server_out_of_date_major": "Server is out of date. Please update to the latest major version.",
|
||||
"profile_drawer_server_out_of_date_minor": "Server is out of date. Please update to the latest minor version.",
|
||||
"profile_drawer_settings": "Settings",
|
||||
"profile_drawer_sign_out": "Sign Out",
|
||||
"profile_drawer_trash": "Trash",
|
||||
"recently_added": "Recently added",
|
||||
"recently_added_page_title": "Recently Added",
|
||||
"save": "Save",
|
||||
"save_to_gallery": "Save to gallery",
|
||||
"scaffold_body_error_occurred": "Error occurred",
|
||||
"search_albums": "Search albums",
|
||||
"search_bar_hint": "Search your photos",
|
||||
"search_filter_apply": "Apply filter",
|
||||
"search_filter_camera": "Camera",
|
||||
"search_filter_camera_make": "Make",
|
||||
"search_filter_camera_model": "Model",
|
||||
"search_filter_camera_title": "Select camera type",
|
||||
"search_filter_date": "Date",
|
||||
"search_filter_date_interval": "{start} to {end}",
|
||||
"search_filter_date_title": "Select a date range",
|
||||
"search_filter_display_option_archive": "Archive",
|
||||
"search_filter_display_option_favorite": "Favorite",
|
||||
"search_filter_display_option_not_in_album": "Not in album",
|
||||
"search_filter_display_options": "Display Options",
|
||||
"search_filter_display_options_title": "Display options",
|
||||
"search_filter_location": "Location",
|
||||
"search_filter_location_city": "City",
|
||||
"search_filter_location_country": "Country",
|
||||
"search_filter_location_state": "State",
|
||||
"search_filter_location_title": "Select location",
|
||||
"search_filter_media_type": "Media Type",
|
||||
"search_filter_media_type_all": "All",
|
||||
"search_filter_media_type_image": "Image",
|
||||
"search_filter_media_type_title": "Select media type",
|
||||
"search_filter_media_type_video": "Video",
|
||||
"search_filter_people": "People",
|
||||
"search_filter_people_title": "Select people",
|
||||
"search_page_categories": "Categories",
|
||||
"search_page_favorites": "Favorites",
|
||||
"search_page_motion_photos": "Motion Photos",
|
||||
"search_page_no_objects": "No Objects Info Available",
|
||||
"search_page_no_places": "No Places Info Available",
|
||||
"search_page_people": "People",
|
||||
"search_page_person_add_name_dialog_cancel": "Cancel",
|
||||
"search_page_person_add_name_dialog_hint": "Name",
|
||||
"search_page_person_add_name_dialog_save": "Save",
|
||||
"search_page_person_add_name_dialog_title": "Add a name",
|
||||
"search_page_person_add_name_subtitle": "Find them fast by name with search",
|
||||
"search_page_person_add_name_title": "Add a name",
|
||||
"search_page_person_edit_name": "Edit name",
|
||||
"search_page_places": "Places",
|
||||
"search_page_recently_added": "Recently added",
|
||||
"search_page_screenshots": "Screenshots",
|
||||
"search_page_search_photos_videos": "Search for your photos and videos",
|
||||
"search_page_selfies": "Selfies",
|
||||
"search_page_things": "Things",
|
||||
"search_page_videos": "Videos",
|
||||
"search_page_view_all_button": "View all",
|
||||
"search_page_your_activity": "Your activity",
|
||||
"search_page_your_map": "Your Map",
|
||||
"search_result_page_new_search_hint": "New Search",
|
||||
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
|
||||
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
|
||||
"select_additional_user_for_sharing_page_suggestions": "Suggestions",
|
||||
"select_user_for_sharing_page_err_album": "Failed to create album",
|
||||
"select_user_for_sharing_page_share_suggestions": "Suggestions",
|
||||
"server_endpoint": "Server Endpoint",
|
||||
"server_info_box_app_version": "App Version",
|
||||
"server_info_box_latest_release": "Latest Version",
|
||||
"server_info_box_server_url": "Server URL",
|
||||
"server_info_box_server_version": "Server Version",
|
||||
"setting_image_viewer_help": "The detail viewer loads the small thumbnail first, then loads the medium-size preview (if enabled), finally loads the original (if enabled).",
|
||||
"setting_image_viewer_original_subtitle": "Enable to load the original full-resolution image (large!). Disable to reduce data usage (both network and on device cache).",
|
||||
"setting_image_viewer_original_title": "Load original image",
|
||||
"setting_image_viewer_preview_subtitle": "Enable to load a medium-resolution image. Disable to either directly load the original or only use the thumbnail.",
|
||||
"setting_image_viewer_preview_title": "Load preview image",
|
||||
"setting_image_viewer_title": "Images",
|
||||
"setting_languages_apply": "Apply",
|
||||
"setting_languages_subtitle": "Change the app's language",
|
||||
"setting_languages_title": "Languages",
|
||||
"setting_notifications_notify_failures_grace_period": "Notify background backup failures: {}",
|
||||
"setting_notifications_notify_hours": "{} hours",
|
||||
"setting_notifications_notify_immediately": "immediately",
|
||||
"setting_notifications_notify_minutes": "{} minutes",
|
||||
"setting_notifications_notify_never": "never",
|
||||
"setting_notifications_notify_seconds": "{} seconds",
|
||||
"setting_notifications_single_progress_subtitle": "Detailed upload progress information per asset",
|
||||
"setting_notifications_single_progress_title": "Show background backup detail progress",
|
||||
"setting_notifications_subtitle": "Adjust your notification preferences",
|
||||
"setting_notifications_title": "Notifications",
|
||||
"setting_notifications_total_progress_subtitle": "Overall upload progress (done/total assets)",
|
||||
"setting_notifications_total_progress_title": "Show background backup total progress",
|
||||
"setting_pages_app_bar_settings": "Settings",
|
||||
"settings_require_restart": "Please restart Immich to apply this setting",
|
||||
"setting_video_viewer_looping_subtitle": "Enable to automatically loop a video in the detail viewer.",
|
||||
"setting_video_viewer_looping_title": "Looping",
|
||||
"setting_video_viewer_original_video_subtitle": "When streaming a video from the server, play the original even when a transcode is available. May lead to buffering. Videos available locally are played in original quality regardless of this setting.",
|
||||
"setting_video_viewer_original_video_title": "Force original video",
|
||||
"setting_video_viewer_title": "Videos",
|
||||
"share_add": "Add",
|
||||
"share_add_photos": "Add photos",
|
||||
"share_add_title": "Add a title",
|
||||
"share_assets_selected": "{} selected",
|
||||
"share_create_album": "Create album",
|
||||
"shared_album_activities_input_disable": "Comment is disabled",
|
||||
"shared_album_activities_input_hint": "Say something",
|
||||
"shared_album_activity_remove_content": "Do you want to delete this activity?",
|
||||
"shared_album_activity_remove_title": "Delete Activity",
|
||||
"shared_album_activity_setting_subtitle": "Let others respond",
|
||||
"shared_album_activity_setting_title": "Comments & likes",
|
||||
"shared_album_section_people_action_error": "Error leaving/removing from album",
|
||||
"shared_album_section_people_action_leave": "Remove user from album",
|
||||
"shared_album_section_people_action_remove_user": "Remove user from album",
|
||||
"shared_album_section_people_owner_label": "Owner",
|
||||
"shared_album_section_people_title": "PEOPLE",
|
||||
"share_dialog_preparing": "Preparing...",
|
||||
"shared_intent_upload_button_progress_text": "{} / {} Uploaded",
|
||||
"shared_link_app_bar_title": "Shared Links",
|
||||
"shared_link_clipboard_copied_massage": "Copied to clipboard",
|
||||
"shared_link_clipboard_text": "Link: {}\nPassword: {}",
|
||||
"shared_link_create_app_bar_title": "Create link to share",
|
||||
"shared_link_create_error": "Error while creating shared link",
|
||||
"shared_link_create_info": "Let anyone with the link see the selected photo(s)",
|
||||
"shared_link_create_submit_button": "Create link",
|
||||
"shared_link_edit_allow_download": "Allow public user to download",
|
||||
"shared_link_edit_allow_upload": "Allow public user to upload",
|
||||
"shared_link_edit_app_bar_title": "Edit link",
|
||||
"shared_link_edit_change_expiry": "Change expiration time",
|
||||
"shared_link_edit_description": "Description",
|
||||
"shared_link_edit_description_hint": "Enter the share description",
|
||||
"shared_link_edit_expire_after": "Expire after",
|
||||
"shared_link_edit_expire_after_option_day": "1 day",
|
||||
"shared_link_edit_expire_after_option_days": "{} days",
|
||||
"shared_link_edit_expire_after_option_hour": "1 hour",
|
||||
"shared_link_edit_expire_after_option_hours": "{} hours",
|
||||
"shared_link_edit_expire_after_option_minute": "1 minute",
|
||||
"shared_link_edit_expire_after_option_minutes": "{} minutes",
|
||||
"shared_link_edit_expire_after_option_months": "{} months",
|
||||
"shared_link_edit_expire_after_option_never": "Never",
|
||||
"shared_link_edit_expire_after_option_year": "{} year",
|
||||
"shared_link_edit_password": "Password",
|
||||
"shared_link_edit_password_hint": "Enter the share password",
|
||||
"shared_link_edit_show_meta": "Show metadata",
|
||||
"shared_link_edit_submit_button": "Update link",
|
||||
"shared_link_empty": "You don't have any shared links",
|
||||
"shared_link_error_server_url_fetch": "Cannot fetch the server url",
|
||||
"shared_link_expired": "Expired",
|
||||
"shared_link_expires_day": "Expires in {} day",
|
||||
"shared_link_expires_days": "Expires in {} days",
|
||||
"shared_link_expires_hour": "Expires in {} hour",
|
||||
"shared_link_expires_hours": "Expires in {} hours",
|
||||
"shared_link_expires_minute": "Expires in {} minute",
|
||||
"shared_link_expires_minutes": "Expires in {} minutes",
|
||||
"shared_link_expires_never": "Expires ∞",
|
||||
"shared_link_expires_second": "Expires in {} second",
|
||||
"shared_link_expires_seconds": "Expires in {} seconds",
|
||||
"shared_link_individual_shared": "Individual shared",
|
||||
"shared_link_info_chip_download": "Download",
|
||||
"shared_link_info_chip_metadata": "EXIF",
|
||||
"shared_link_info_chip_upload": "Upload",
|
||||
"shared_link_manage_links": "Manage Shared links",
|
||||
"shared_link_public_album": "Public album",
|
||||
"shared_links": "Shared links",
|
||||
"share_done": "Done",
|
||||
"shared_with_me": "Shared with me",
|
||||
"share_invite": "Invite to album",
|
||||
"sharing_page_album": "Shared albums",
|
||||
"sharing_page_description": "Create shared albums to share photos and videos with people in your network.",
|
||||
"sharing_page_empty_list": "EMPTY LIST",
|
||||
"sharing_silver_appbar_create_shared_album": "New shared album",
|
||||
"sharing_silver_appbar_shared_links": "Shared links",
|
||||
"sharing_silver_appbar_share_partner": "Share with partner",
|
||||
"start_date": "Start date",
|
||||
"sync": "Sync",
|
||||
"sync_albums": "Sync albums",
|
||||
"sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums",
|
||||
"sync_upload_album_setting_subtitle": "Create and upload your photos and videos to the selected albums on Immich",
|
||||
"tab_controller_nav_library": "Library",
|
||||
"tab_controller_nav_photos": "Photos",
|
||||
"tab_controller_nav_search": "Search",
|
||||
"tab_controller_nav_sharing": "Sharing",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({})",
|
||||
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
|
||||
"theme_setting_colorful_interface_title": "Colorful interface",
|
||||
"theme_setting_dark_mode_switch": "Dark mode",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Adjust the quality of the detail image viewer",
|
||||
"theme_setting_image_viewer_quality_title": "Image viewer quality",
|
||||
"theme_setting_primary_color_subtitle": "Pick a color for primary actions and accents.",
|
||||
"theme_setting_primary_color_title": "Primary color",
|
||||
"theme_setting_system_primary_color_title": "Use system color",
|
||||
"theme_setting_system_theme_switch": "Automatic (Follow system setting)",
|
||||
"theme_setting_theme_subtitle": "Choose the app's theme setting",
|
||||
"theme_setting_theme_title": "Theme",
|
||||
"theme_setting_three_stage_loading_subtitle": "Three-stage loading might increase the loading performance but causes significantly higher network load",
|
||||
"theme_setting_three_stage_loading_title": "Enable three-stage loading",
|
||||
"translated_text_options": "Options",
|
||||
"trash": "Trash",
|
||||
"trash_emptied": "Emptied trash",
|
||||
"trash_page_delete": "Delete",
|
||||
"trash_page_delete_all": "Delete All",
|
||||
"trash_page_empty_trash_btn": "Empty trash",
|
||||
"trash_page_empty_trash_dialog_content": "Do you want to empty your trashed assets? These items will be permanently removed from Immich",
|
||||
"trash_page_empty_trash_dialog_ok": "Ok",
|
||||
"trash_page_info": "Trashed items will be permanently deleted after {} days",
|
||||
"trash_page_no_assets": "No trashed assets",
|
||||
"trash_page_restore": "Restore",
|
||||
"trash_page_restore_all": "Restore All",
|
||||
"trash_page_select_assets_btn": "Select assets",
|
||||
"trash_page_select_btn": "Select",
|
||||
"trash_page_title": "Trash ({})",
|
||||
"upload": "Upload",
|
||||
"upload_dialog_cancel": "Cancel",
|
||||
"upload_dialog_info": "Do you want to backup the selected Asset(s) to the server?",
|
||||
"upload_dialog_ok": "Upload",
|
||||
"upload_dialog_title": "Upload Asset",
|
||||
"uploading": "Uploading",
|
||||
"upload_to_immich": "Upload to Immich ({})",
|
||||
"use_current_connection": "use current connection",
|
||||
"validate_endpoint_error": "Please enter a valid URL",
|
||||
"version_announcement_overlay_ack": "Acknowledge",
|
||||
"version_announcement_overlay_release_notes": "release notes",
|
||||
"version_announcement_overlay_text_1": "Hi friend, there is a new release of",
|
||||
"version_announcement_overlay_text_2": "please take your time to visit the ",
|
||||
"version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
|
||||
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89",
|
||||
"videos": "Videos",
|
||||
"viewer_remove_from_stack": "Remove from Stack",
|
||||
"viewer_stack_use_as_main_asset": "Use as Main Asset",
|
||||
"viewer_unstack": "Un-Stack",
|
||||
"wifi_name": "WiFi Name",
|
||||
"your_wifi_name": "Your WiFi name"
|
||||
}
|
||||
673
mobile/assets/i18n/gl.json
Normal file
673
mobile/assets/i18n/gl.json
Normal file
@@ -0,0 +1,673 @@
|
||||
{
|
||||
"action_common_back": "Back",
|
||||
"action_common_cancel": "Cancel",
|
||||
"action_common_clear": "Clear",
|
||||
"action_common_confirm": "Confirm",
|
||||
"action_common_save": "Save",
|
||||
"action_common_select": "Select",
|
||||
"action_common_update": "Update",
|
||||
"add_a_name": "Add a name",
|
||||
"add_endpoint": "Add endpoint",
|
||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
||||
"advanced_settings_log_level_title": "Log level: {}",
|
||||
"advanced_settings_prefer_remote_subtitle": "Some devices are painfully slow to load thumbnails from assets on the device. Activate this setting to load remote images instead.",
|
||||
"advanced_settings_prefer_remote_title": "Prefer remote images",
|
||||
"advanced_settings_proxy_headers_subtitle": "Define proxy headers Immich should send with each network request",
|
||||
"advanced_settings_proxy_headers_title": "Proxy Headers",
|
||||
"advanced_settings_self_signed_ssl_subtitle": "Skips SSL certificate verification for the server endpoint. Required for self-signed certificates.",
|
||||
"advanced_settings_self_signed_ssl_title": "Allow self-signed SSL certificates (EXPERIMENTAL)",
|
||||
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||
"advanced_settings_tile_title": "Advanced",
|
||||
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||
"album_info_card_backup_album_excluded": "EXCLUDED",
|
||||
"album_info_card_backup_album_included": "INCLUDED",
|
||||
"albums": "Albums",
|
||||
"album_thumbnail_card_item": "1 item",
|
||||
"album_thumbnail_card_items": "{} items",
|
||||
"album_thumbnail_card_shared": " · Shared",
|
||||
"album_thumbnail_owned": "Owned",
|
||||
"album_thumbnail_shared_by": "Shared by {}",
|
||||
"album_viewer_appbar_delete_confirm": "Are you sure you want to delete this album from your account?",
|
||||
"album_viewer_appbar_share_delete": "Delete album",
|
||||
"album_viewer_appbar_share_err_delete": "Failed to delete album",
|
||||
"album_viewer_appbar_share_err_leave": "Failed to leave album",
|
||||
"album_viewer_appbar_share_err_remove": "There are problems in removing assets from album",
|
||||
"album_viewer_appbar_share_err_title": "Failed to change album title",
|
||||
"album_viewer_appbar_share_leave": "Leave album",
|
||||
"album_viewer_appbar_share_remove": "Remove from album",
|
||||
"album_viewer_appbar_share_to": "Share To",
|
||||
"album_viewer_page_share_add_users": "Add users",
|
||||
"all": "All",
|
||||
"all_people_page_title": "People",
|
||||
"all_videos_page_title": "Videos",
|
||||
"app_bar_signout_dialog_content": "Are you sure you want to sign out?",
|
||||
"app_bar_signout_dialog_ok": "Yes",
|
||||
"app_bar_signout_dialog_title": "Sign out",
|
||||
"archived": "Archived",
|
||||
"archive_page_no_archived_assets": "No archived assets found",
|
||||
"archive_page_title": "Archive ({})",
|
||||
"asset_action_delete_err_read_only": "Cannot delete read only asset(s), skipping",
|
||||
"asset_action_share_err_offline": "Cannot fetch offline asset(s), skipping",
|
||||
"asset_list_group_by_sub_title": "Group by",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||
"asset_list_layout_settings_group_by": "Group assets by",
|
||||
"asset_list_layout_settings_group_by_month": "Month",
|
||||
"asset_list_layout_settings_group_by_month_day": "Month + day",
|
||||
"asset_list_layout_sub_title": "Layout",
|
||||
"asset_list_settings_subtitle": "Photo grid layout settings",
|
||||
"asset_list_settings_title": "Photo Grid",
|
||||
"asset_restored_successfully": "Asset restored successfully",
|
||||
"assets_deleted_permanently": "{} asset(s) deleted permanently",
|
||||
"assets_deleted_permanently_from_server": "{} asset(s) deleted permanently from the Immich server",
|
||||
"assets_removed_permanently_from_device": "{} asset(s) removed permanently from your device",
|
||||
"assets_restored_successfully": "{} asset(s) restored successfully",
|
||||
"assets_trashed": "{} asset(s) trashed",
|
||||
"assets_trashed_from_server": "{} asset(s) trashed from the Immich server",
|
||||
"asset_viewer_settings_subtitle": "Manage your gallery viewer settings",
|
||||
"asset_viewer_settings_title": "Asset Viewer",
|
||||
"automatic_endpoint_switching_subtitle": "Connect locally over designated Wi-Fi when available and use alternative connections elsewhere",
|
||||
"automatic_endpoint_switching_title": "Automatic URL switching",
|
||||
"background_location_permission": "Background location permission",
|
||||
"background_location_permission_content": "In order to switch networks when running in the background, Immich must *always* have precise location access so the app can read the Wi-Fi network's name",
|
||||
"backup_album_selection_page_albums_device": "Albums on device ({})",
|
||||
"backup_album_selection_page_albums_tap": "Tap to include, double tap to exclude",
|
||||
"backup_album_selection_page_assets_scatter": "Assets can scatter across multiple albums. Thus, albums can be included or excluded during the backup process.",
|
||||
"backup_album_selection_page_select_albums": "Select albums",
|
||||
"backup_album_selection_page_selection_info": "Selection Info",
|
||||
"backup_album_selection_page_total_assets": "Total unique assets",
|
||||
"backup_all": "All",
|
||||
"backup_background_service_backup_failed_message": "Failed to backup assets. Retrying…",
|
||||
"backup_background_service_connection_failed_message": "Failed to connect to the server. Retrying…",
|
||||
"backup_background_service_current_upload_notification": "Uploading {}",
|
||||
"backup_background_service_default_notification": "Checking for new assets…",
|
||||
"backup_background_service_error_title": "Backup error",
|
||||
"backup_background_service_in_progress_notification": "Backing up your assets…",
|
||||
"backup_background_service_upload_failure_notification": "Failed to upload {}",
|
||||
"backup_controller_page_albums": "Backup Albums",
|
||||
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
|
||||
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
|
||||
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
|
||||
"backup_controller_page_background_battery_info_link": "Show me how",
|
||||
"backup_controller_page_background_battery_info_message": "For the best background backup experience, please disable any battery optimizations restricting background activity for Immich.\n\nSince this is device-specific, please lookup the required information for your device manufacturer.",
|
||||
"backup_controller_page_background_battery_info_ok": "OK",
|
||||
"backup_controller_page_background_battery_info_title": "Battery optimizations",
|
||||
"backup_controller_page_background_charging": "Only while charging",
|
||||
"backup_controller_page_background_configure_error": "Failed to configure the background service",
|
||||
"backup_controller_page_background_delay": "Delay new assets backup: {}",
|
||||
"backup_controller_page_background_description": "Turn on the background service to automatically backup any new assets without needing to open the app",
|
||||
"backup_controller_page_background_is_off": "Automatic background backup is off",
|
||||
"backup_controller_page_background_is_on": "Automatic background backup is on",
|
||||
"backup_controller_page_background_turn_off": "Turn off background service",
|
||||
"backup_controller_page_background_turn_on": "Turn on background service",
|
||||
"backup_controller_page_background_wifi": "Only on WiFi",
|
||||
"backup_controller_page_backup": "Backup",
|
||||
"backup_controller_page_backup_selected": "Selected: ",
|
||||
"backup_controller_page_backup_sub": "Backed up photos and videos",
|
||||
"backup_controller_page_cancel": "Cancel",
|
||||
"backup_controller_page_created": "Created on: {}",
|
||||
"backup_controller_page_desc_backup": "Turn on foreground backup to automatically upload new assets to the server when opening the app.",
|
||||
"backup_controller_page_excluded": "Excluded: ",
|
||||
"backup_controller_page_failed": "Failed ({})",
|
||||
"backup_controller_page_filename": "File name: {} [{}]",
|
||||
"backup_controller_page_id": "ID: {}",
|
||||
"backup_controller_page_info": "Backup Information",
|
||||
"backup_controller_page_none_selected": "None selected",
|
||||
"backup_controller_page_remainder": "Remainder",
|
||||
"backup_controller_page_remainder_sub": "Remaining photos and videos to back up from selection",
|
||||
"backup_controller_page_select": "Select",
|
||||
"backup_controller_page_server_storage": "Server Storage",
|
||||
"backup_controller_page_start_backup": "Start Backup",
|
||||
"backup_controller_page_status_off": "Automatic foreground backup is off",
|
||||
"backup_controller_page_status_on": "Automatic foreground backup is on",
|
||||
"backup_controller_page_storage_format": "{} of {} used",
|
||||
"backup_controller_page_to_backup": "Albums to be backed up",
|
||||
"backup_controller_page_total": "Total",
|
||||
"backup_controller_page_total_sub": "All unique photos and videos from selected albums",
|
||||
"backup_controller_page_turn_off": "Turn off foreground backup",
|
||||
"backup_controller_page_turn_on": "Turn on foreground backup",
|
||||
"backup_controller_page_uploading_file_info": "Uploading file info",
|
||||
"backup_err_only_album": "Cannot remove the only album",
|
||||
"backup_info_card_assets": "assets",
|
||||
"backup_manual_cancelled": "Cancelled",
|
||||
"backup_manual_failed": "Failed",
|
||||
"backup_manual_in_progress": "Upload already in progress. Try after sometime",
|
||||
"backup_manual_success": "Success",
|
||||
"backup_manual_title": "Upload status",
|
||||
"backup_options_page_title": "Backup options",
|
||||
"backup_setting_subtitle": "Manage background and foreground upload settings",
|
||||
"cache_settings_album_thumbnails": "Library page thumbnails ({} assets)",
|
||||
"cache_settings_clear_cache_button": "Clear cache",
|
||||
"cache_settings_clear_cache_button_title": "Clears the app's cache. This will significantly impact the app's performance until the cache has rebuilt.",
|
||||
"cache_settings_duplicated_assets_clear_button": "CLEAR",
|
||||
"cache_settings_duplicated_assets_subtitle": "Photos and videos that are black listed by the app",
|
||||
"cache_settings_duplicated_assets_title": "Duplicated Assets ({})",
|
||||
"cache_settings_image_cache_size": "Image cache size ({} assets)",
|
||||
"cache_settings_statistics_album": "Library thumbnails",
|
||||
"cache_settings_statistics_assets": "{} assets ({})",
|
||||
"cache_settings_statistics_full": "Full images",
|
||||
"cache_settings_statistics_shared": "Shared album thumbnails",
|
||||
"cache_settings_statistics_thumbnail": "Thumbnails",
|
||||
"cache_settings_statistics_title": "Cache usage",
|
||||
"cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application",
|
||||
"cache_settings_thumbnail_size": "Thumbnail cache size ({} assets)",
|
||||
"cache_settings_tile_subtitle": "Control the local storage behaviour",
|
||||
"cache_settings_tile_title": "Local Storage",
|
||||
"cache_settings_title": "Caching Settings",
|
||||
"cancel": "Cancel",
|
||||
"canceled": "Canceled",
|
||||
"change_display_order": "Change display order",
|
||||
"change_password_form_confirm_password": "Confirm Password",
|
||||
"change_password_form_description": "Hi {name},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
|
||||
"change_password_form_new_password": "New Password",
|
||||
"change_password_form_password_mismatch": "Passwords do not match",
|
||||
"change_password_form_reenter_new_password": "Re-enter New Password",
|
||||
"check_corrupt_asset_backup": "Check for corrupt asset backups",
|
||||
"check_corrupt_asset_backup_button": "Perform check",
|
||||
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
|
||||
"client_cert_dialog_msg_confirm": "OK",
|
||||
"client_cert_enter_password": "Enter Password",
|
||||
"client_cert_import": "Import",
|
||||
"client_cert_import_success_msg": "Client certificate is imported",
|
||||
"client_cert_invalid_msg": "Invalid certificate file or wrong password",
|
||||
"client_cert_remove": "Remove",
|
||||
"client_cert_remove_msg": "Client certificate is removed",
|
||||
"client_cert_subtitle": "Supports PKCS12 (.p12, .pfx) format only. Certificate Import/Remove is available only before login",
|
||||
"client_cert_title": "SSL Client Certificate (EXPERIMENTAL)",
|
||||
"common_add_to_album": "Add to album",
|
||||
"common_change_password": "Change Password",
|
||||
"common_create_new_album": "Create new album",
|
||||
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
|
||||
"common_shared": "Shared",
|
||||
"completed": "Completed",
|
||||
"contextual_search": "Sunrise on the beach",
|
||||
"control_bottom_app_bar_add_to_album": "Add to album",
|
||||
"control_bottom_app_bar_album_info": "{} items",
|
||||
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
||||
"control_bottom_app_bar_archive": "Archive",
|
||||
"control_bottom_app_bar_create_new_album": "Create new album",
|
||||
"control_bottom_app_bar_delete": "Delete",
|
||||
"control_bottom_app_bar_delete_from_immich": "Delete from Immich",
|
||||
"control_bottom_app_bar_delete_from_local": "Delete from device",
|
||||
"control_bottom_app_bar_download": "Download",
|
||||
"control_bottom_app_bar_edit": "Edit",
|
||||
"control_bottom_app_bar_edit_location": "Edit Location",
|
||||
"control_bottom_app_bar_edit_time": "Edit Date & Time",
|
||||
"control_bottom_app_bar_favorite": "Favorite",
|
||||
"control_bottom_app_bar_share": "Share",
|
||||
"control_bottom_app_bar_share_to": "Share To",
|
||||
"control_bottom_app_bar_stack": "Stack",
|
||||
"control_bottom_app_bar_trash_from_immich": "Move to Trash",
|
||||
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||
"control_bottom_app_bar_unfavorite": "Unfavorite",
|
||||
"control_bottom_app_bar_upload": "Upload",
|
||||
"create_album": "Create album",
|
||||
"create_album_page_untitled": "Untitled",
|
||||
"create_new": "CREATE NEW",
|
||||
"create_shared_album_page_create": "Create",
|
||||
"create_shared_album_page_share": "Share",
|
||||
"create_shared_album_page_share_add_assets": "ADD ASSETS",
|
||||
"create_shared_album_page_share_select_photos": "Select Photos",
|
||||
"crop": "Crop",
|
||||
"curated_location_page_title": "Places",
|
||||
"curated_object_page_title": "Things",
|
||||
"current_server_address": "Current server address",
|
||||
"daily_title_text_date": "E, MMM dd",
|
||||
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
||||
"date_format": "E, LLL d, y • h:mm a",
|
||||
"delete_dialog_alert": "These items will be permanently deleted from Immich and from your device",
|
||||
"delete_dialog_alert_local": "These items will be permanently removed from your device but still be available on the Immich server",
|
||||
"delete_dialog_alert_local_non_backed_up": "Some of the items aren't backed up to Immich and will be permanently removed from your device",
|
||||
"delete_dialog_alert_remote": "These items will be permanently deleted from the Immich server",
|
||||
"delete_dialog_cancel": "Cancel",
|
||||
"delete_dialog_ok": "Delete",
|
||||
"delete_dialog_ok_force": "Delete Anyway",
|
||||
"delete_dialog_title": "Delete Permanently",
|
||||
"delete_local_dialog_ok_backed_up_only": "Delete Backed Up Only",
|
||||
"delete_local_dialog_ok_force": "Delete Anyway",
|
||||
"delete_shared_link_dialog_content": "Are you sure you want to delete this shared link?",
|
||||
"delete_shared_link_dialog_title": "Delete Shared Link",
|
||||
"description_input_hint_text": "Add description...",
|
||||
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||
"download_canceled": "Download canceled",
|
||||
"download_complete": "Download complete",
|
||||
"download_enqueue": "Download enqueued",
|
||||
"download_error": "Download Error",
|
||||
"download_failed": "Download failed",
|
||||
"download_filename": "file: {}",
|
||||
"download_finished": "Download finished",
|
||||
"downloading": "Downloading...",
|
||||
"downloading_media": "Downloading media",
|
||||
"download_notfound": "Download not found",
|
||||
"download_paused": "Download paused",
|
||||
"download_started": "Download started",
|
||||
"download_sucess": "Download success",
|
||||
"download_sucess_android": "The media has been downloaded to DCIM/Immich",
|
||||
"download_waiting_to_retry": "Waiting to retry",
|
||||
"edit_date_time_dialog_date_time": "Date and Time",
|
||||
"edit_date_time_dialog_timezone": "Timezone",
|
||||
"edit_image_title": "Edit",
|
||||
"edit_location_dialog_title": "Location",
|
||||
"end_date": "End date",
|
||||
"enqueued": "Enqueued",
|
||||
"enter_wifi_name": "Enter WiFi name",
|
||||
"error_change_sort_album": "Failed to change album sort order",
|
||||
"error_saving_image": "Error: {}",
|
||||
"exif_bottom_sheet_description": "Add Description...",
|
||||
"exif_bottom_sheet_details": "DETAILS",
|
||||
"exif_bottom_sheet_location": "LOCATION",
|
||||
"exif_bottom_sheet_location_add": "Add a location",
|
||||
"exif_bottom_sheet_people": "PEOPLE",
|
||||
"exif_bottom_sheet_person_add_person": "Add name",
|
||||
"experimental_settings_new_asset_list_subtitle": "Work in progress",
|
||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"experimental_settings_subtitle": "Use at your own risk!",
|
||||
"experimental_settings_title": "Experimental",
|
||||
"external_network": "External network",
|
||||
"external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
|
||||
"failed": "Failed",
|
||||
"favorites": "Favorites",
|
||||
"favorites_page_no_favorites": "No favorite assets found",
|
||||
"favorites_page_title": "Favorites",
|
||||
"filename_search": "File name or extension",
|
||||
"filter": "Filter",
|
||||
"get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network",
|
||||
"grant_permission": "Grant permission",
|
||||
"haptic_feedback_switch": "Enable haptic feedback",
|
||||
"haptic_feedback_title": "Haptic Feedback",
|
||||
"header_settings_add_header_tip": "Add Header",
|
||||
"header_settings_field_validator_msg": "Value cannot be empty",
|
||||
"header_settings_header_name_input": "Header name",
|
||||
"header_settings_header_value_input": "Header value",
|
||||
"header_settings_page_title": "Proxy Headers (EXPERIMENTAL)",
|
||||
"headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request",
|
||||
"headers_settings_tile_title": "Custom proxy headers",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"home_page_album_err_partner": "Can not add partner assets to an album yet, skipping",
|
||||
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||
"home_page_archive_err_partner": "Can not archive partner assets, skipping",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"home_page_delete_err_partner": "Can not delete partner assets, skipping",
|
||||
"home_page_delete_remote_err_local": "Local assets in delete remote selection, skipping",
|
||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
||||
"home_page_favorite_err_partner": "Can not favorite partner assets yet, skipping",
|
||||
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
|
||||
"home_page_share_err_local": "Can not share local assets via link, skipping",
|
||||
"home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping",
|
||||
"ignore_icloud_photos": "Ignore iCloud photos",
|
||||
"ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server",
|
||||
"image_saved_successfully": "Image saved",
|
||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
||||
"image_viewer_page_state_provider_download_started": "Download Started",
|
||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
||||
"image_viewer_page_state_provider_share_error": "Share Error",
|
||||
"invalid_date": "Invalid date",
|
||||
"invalid_date_format": "Invalid date format",
|
||||
"library": "Library",
|
||||
"library_page_albums": "Albums",
|
||||
"library_page_archive": "Archive",
|
||||
"library_page_device_albums": "Albums on Device",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "New album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_asset_count": "Number of assets",
|
||||
"library_page_sort_created": "Created date",
|
||||
"library_page_sort_last_modified": "Last modified",
|
||||
"library_page_sort_most_oldest_photo": "Oldest photo",
|
||||
"library_page_sort_most_recent_photo": "Most recent photo",
|
||||
"library_page_sort_title": "Album title",
|
||||
"local_network": "Local network",
|
||||
"local_network_sheet_info": "The app will connect to the server through this URL when using the specified Wi-Fi network",
|
||||
"location_permission": "Location permission",
|
||||
"location_permission_content": "In order to use the auto-switching feature, Immich needs precise location permission so it can read the current WiFi network's name",
|
||||
"location_picker_choose_on_map": "Choose on map",
|
||||
"location_picker_latitude": "Latitude",
|
||||
"location_picker_latitude_error": "Enter a valid latitude",
|
||||
"location_picker_latitude_hint": "Enter your latitude here",
|
||||
"location_picker_longitude": "Longitude",
|
||||
"location_picker_longitude_error": "Enter a valid longitude",
|
||||
"location_picker_longitude_hint": "Enter your longitude here",
|
||||
"login_disabled": "Login has been disabled",
|
||||
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
"login_form_err_invalid_url": "Invalid URL",
|
||||
"login_form_err_leading_whitespace": "Leading whitespace",
|
||||
"login_form_err_trailing_whitespace": "Trailing whitespace",
|
||||
"login_form_failed_get_oauth_server_config": "Error logging using OAuth, check server URL",
|
||||
"login_form_failed_get_oauth_server_disable": "OAuth feature is not available on this server",
|
||||
"login_form_failed_login": "Error logging you in, check server URL, email and password",
|
||||
"login_form_handshake_exception": "There was an Handshake Exception with the server. Enable self-signed certificate support in the settings if you are using a self-signed certificate.",
|
||||
"login_form_label_email": "Email",
|
||||
"login_form_label_password": "Password",
|
||||
"login_form_next_button": "Next",
|
||||
"login_form_password_hint": "password",
|
||||
"login_form_save_login": "Stay logged in",
|
||||
"login_form_server_empty": "Enter a server URL.",
|
||||
"login_form_server_error": "Could not connect to server.",
|
||||
"login_password_changed_error": "There was an error updating your password",
|
||||
"login_password_changed_success": "Password updated successfully",
|
||||
"map_assets_in_bound": "{} photo",
|
||||
"map_assets_in_bounds": "{} photos",
|
||||
"map_cannot_get_user_location": "Cannot get user's location",
|
||||
"map_location_dialog_cancel": "Cancel",
|
||||
"map_location_dialog_yes": "Yes",
|
||||
"map_location_picker_page_use_location": "Use this location",
|
||||
"map_location_service_disabled_content": "Location service needs to be enabled to display assets from your current location. Do you want to enable it now?",
|
||||
"map_location_service_disabled_title": "Location Service disabled",
|
||||
"map_no_assets_in_bounds": "No photos in this area",
|
||||
"map_no_location_permission_content": "Location permission is needed to display assets from your current location. Do you want to allow it now?",
|
||||
"map_no_location_permission_title": "Location Permission denied",
|
||||
"map_settings_dark_mode": "Dark mode",
|
||||
"map_settings_date_range_option_all": "All",
|
||||
"map_settings_date_range_option_day": "Past 24 hours",
|
||||
"map_settings_date_range_option_days": "Past {} days",
|
||||
"map_settings_date_range_option_year": "Past year",
|
||||
"map_settings_date_range_option_years": "Past {} years",
|
||||
"map_settings_dialog_cancel": "Cancel",
|
||||
"map_settings_dialog_save": "Save",
|
||||
"map_settings_dialog_title": "Map Settings",
|
||||
"map_settings_include_show_archived": "Include Archived",
|
||||
"map_settings_include_show_partners": "Include Partners",
|
||||
"map_settings_only_relative_range": "Date range",
|
||||
"map_settings_only_show_favorites": "Show Favorite Only",
|
||||
"map_settings_theme_settings": "Map Theme",
|
||||
"map_zoom_to_see_photos": "Zoom out to see photos",
|
||||
"memories_all_caught_up": "All caught up",
|
||||
"memories_check_back_tomorrow": "Check back tomorrow for more memories",
|
||||
"memories_start_over": "Start Over",
|
||||
"memories_swipe_to_close": "Swipe up to close",
|
||||
"memories_year_ago": "A year ago",
|
||||
"memories_years_ago": "{} years ago",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"motion_photos_page_title": "Motion Photos",
|
||||
"multiselect_grid_edit_date_time_err_read_only": "Cannot edit date of read only asset(s), skipping",
|
||||
"multiselect_grid_edit_gps_err_read_only": "Cannot edit location of read only asset(s), skipping",
|
||||
"my_albums": "My albums",
|
||||
"networking_settings": "Networking",
|
||||
"networking_subtitle": "Manage the server endpoint settings",
|
||||
"no_assets_to_show": "No assets to show",
|
||||
"no_name": "No name",
|
||||
"notification_permission_dialog_cancel": "Cancel",
|
||||
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
|
||||
"notification_permission_dialog_settings": "Settings",
|
||||
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
|
||||
"notification_permission_list_tile_enable_button": "Enable Notifications",
|
||||
"notification_permission_list_tile_title": "Notification Permission",
|
||||
"not_selected": "Not selected",
|
||||
"on_this_device": "On this device",
|
||||
"partner_list_user_photos": "{user}'s photos",
|
||||
"partner_list_view_all": "View all",
|
||||
"partner_page_add_partner": "Add partner",
|
||||
"partner_page_empty_message": "Your photos are not yet shared with any partner.",
|
||||
"partner_page_no_more_users": "No more users to add",
|
||||
"partner_page_partner_add_failed": "Failed to add partner",
|
||||
"partner_page_select_partner": "Select partner",
|
||||
"partner_page_shared_to_title": "Shared to",
|
||||
"partner_page_stop_sharing_content": "{} will no longer be able to access your photos.",
|
||||
"partner_page_stop_sharing_title": "Stop sharing your photos?",
|
||||
"partner_page_title": "Partner",
|
||||
"partners": "Partners",
|
||||
"paused": "Paused",
|
||||
"people": "People",
|
||||
"permission_onboarding_back": "Back",
|
||||
"permission_onboarding_continue_anyway": "Continue anyway",
|
||||
"permission_onboarding_get_started": "Get started",
|
||||
"permission_onboarding_go_to_settings": "Go to settings",
|
||||
"permission_onboarding_grant_permission": "Grant permission",
|
||||
"permission_onboarding_log_out": "Log out",
|
||||
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
|
||||
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
|
||||
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
|
||||
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
|
||||
"places": "Places",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
"preferences_settings_title": "Preferences",
|
||||
"profile_drawer_app_logs": "Logs",
|
||||
"profile_drawer_client_out_of_date_major": "Mobile App is out of date. Please update to the latest major version.",
|
||||
"profile_drawer_client_out_of_date_minor": "Mobile App is out of date. Please update to the latest minor version.",
|
||||
"profile_drawer_client_server_up_to_date": "Client and Server are up-to-date",
|
||||
"profile_drawer_documentation": "Documentation",
|
||||
"profile_drawer_github": "GitHub",
|
||||
"profile_drawer_server_out_of_date_major": "Server is out of date. Please update to the latest major version.",
|
||||
"profile_drawer_server_out_of_date_minor": "Server is out of date. Please update to the latest minor version.",
|
||||
"profile_drawer_settings": "Settings",
|
||||
"profile_drawer_sign_out": "Sign Out",
|
||||
"profile_drawer_trash": "Trash",
|
||||
"recently_added": "Recently added",
|
||||
"recently_added_page_title": "Recently Added",
|
||||
"save": "Save",
|
||||
"save_to_gallery": "Save to gallery",
|
||||
"scaffold_body_error_occurred": "Error occurred",
|
||||
"search_albums": "Search albums",
|
||||
"search_bar_hint": "Search your photos",
|
||||
"search_filter_apply": "Apply filter",
|
||||
"search_filter_camera": "Camera",
|
||||
"search_filter_camera_make": "Make",
|
||||
"search_filter_camera_model": "Model",
|
||||
"search_filter_camera_title": "Select camera type",
|
||||
"search_filter_date": "Date",
|
||||
"search_filter_date_interval": "{start} to {end}",
|
||||
"search_filter_date_title": "Select a date range",
|
||||
"search_filter_display_option_archive": "Archive",
|
||||
"search_filter_display_option_favorite": "Favorite",
|
||||
"search_filter_display_option_not_in_album": "Not in album",
|
||||
"search_filter_display_options": "Display Options",
|
||||
"search_filter_display_options_title": "Display options",
|
||||
"search_filter_location": "Location",
|
||||
"search_filter_location_city": "City",
|
||||
"search_filter_location_country": "Country",
|
||||
"search_filter_location_state": "State",
|
||||
"search_filter_location_title": "Select location",
|
||||
"search_filter_media_type": "Media Type",
|
||||
"search_filter_media_type_all": "All",
|
||||
"search_filter_media_type_image": "Image",
|
||||
"search_filter_media_type_title": "Select media type",
|
||||
"search_filter_media_type_video": "Video",
|
||||
"search_filter_people": "People",
|
||||
"search_filter_people_title": "Select people",
|
||||
"search_page_categories": "Categories",
|
||||
"search_page_favorites": "Favorites",
|
||||
"search_page_motion_photos": "Motion Photos",
|
||||
"search_page_no_objects": "No Objects Info Available",
|
||||
"search_page_no_places": "No Places Info Available",
|
||||
"search_page_people": "People",
|
||||
"search_page_person_add_name_dialog_cancel": "Cancel",
|
||||
"search_page_person_add_name_dialog_hint": "Name",
|
||||
"search_page_person_add_name_dialog_save": "Save",
|
||||
"search_page_person_add_name_dialog_title": "Add a name",
|
||||
"search_page_person_add_name_subtitle": "Find them fast by name with search",
|
||||
"search_page_person_add_name_title": "Add a name",
|
||||
"search_page_person_edit_name": "Edit name",
|
||||
"search_page_places": "Places",
|
||||
"search_page_recently_added": "Recently added",
|
||||
"search_page_screenshots": "Screenshots",
|
||||
"search_page_search_photos_videos": "Search for your photos and videos",
|
||||
"search_page_selfies": "Selfies",
|
||||
"search_page_things": "Things",
|
||||
"search_page_videos": "Videos",
|
||||
"search_page_view_all_button": "View all",
|
||||
"search_page_your_activity": "Your activity",
|
||||
"search_page_your_map": "Your Map",
|
||||
"search_result_page_new_search_hint": "New Search",
|
||||
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
|
||||
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
|
||||
"select_additional_user_for_sharing_page_suggestions": "Suggestions",
|
||||
"select_user_for_sharing_page_err_album": "Failed to create album",
|
||||
"select_user_for_sharing_page_share_suggestions": "Suggestions",
|
||||
"server_endpoint": "Server Endpoint",
|
||||
"server_info_box_app_version": "App Version",
|
||||
"server_info_box_latest_release": "Latest Version",
|
||||
"server_info_box_server_url": "Server URL",
|
||||
"server_info_box_server_version": "Server Version",
|
||||
"setting_image_viewer_help": "The detail viewer loads the small thumbnail first, then loads the medium-size preview (if enabled), finally loads the original (if enabled).",
|
||||
"setting_image_viewer_original_subtitle": "Enable to load the original full-resolution image (large!). Disable to reduce data usage (both network and on device cache).",
|
||||
"setting_image_viewer_original_title": "Load original image",
|
||||
"setting_image_viewer_preview_subtitle": "Enable to load a medium-resolution image. Disable to either directly load the original or only use the thumbnail.",
|
||||
"setting_image_viewer_preview_title": "Load preview image",
|
||||
"setting_image_viewer_title": "Images",
|
||||
"setting_languages_apply": "Apply",
|
||||
"setting_languages_subtitle": "Change the app's language",
|
||||
"setting_languages_title": "Languages",
|
||||
"setting_notifications_notify_failures_grace_period": "Notify background backup failures: {}",
|
||||
"setting_notifications_notify_hours": "{} hours",
|
||||
"setting_notifications_notify_immediately": "immediately",
|
||||
"setting_notifications_notify_minutes": "{} minutes",
|
||||
"setting_notifications_notify_never": "never",
|
||||
"setting_notifications_notify_seconds": "{} seconds",
|
||||
"setting_notifications_single_progress_subtitle": "Detailed upload progress information per asset",
|
||||
"setting_notifications_single_progress_title": "Show background backup detail progress",
|
||||
"setting_notifications_subtitle": "Adjust your notification preferences",
|
||||
"setting_notifications_title": "Notifications",
|
||||
"setting_notifications_total_progress_subtitle": "Overall upload progress (done/total assets)",
|
||||
"setting_notifications_total_progress_title": "Show background backup total progress",
|
||||
"setting_pages_app_bar_settings": "Settings",
|
||||
"settings_require_restart": "Please restart Immich to apply this setting",
|
||||
"setting_video_viewer_looping_subtitle": "Enable to automatically loop a video in the detail viewer.",
|
||||
"setting_video_viewer_looping_title": "Looping",
|
||||
"setting_video_viewer_original_video_subtitle": "When streaming a video from the server, play the original even when a transcode is available. May lead to buffering. Videos available locally are played in original quality regardless of this setting.",
|
||||
"setting_video_viewer_original_video_title": "Force original video",
|
||||
"setting_video_viewer_title": "Videos",
|
||||
"share_add": "Add",
|
||||
"share_add_photos": "Add photos",
|
||||
"share_add_title": "Add a title",
|
||||
"share_assets_selected": "{} selected",
|
||||
"share_create_album": "Create album",
|
||||
"shared_album_activities_input_disable": "Comment is disabled",
|
||||
"shared_album_activities_input_hint": "Say something",
|
||||
"shared_album_activity_remove_content": "Do you want to delete this activity?",
|
||||
"shared_album_activity_remove_title": "Delete Activity",
|
||||
"shared_album_activity_setting_subtitle": "Let others respond",
|
||||
"shared_album_activity_setting_title": "Comments & likes",
|
||||
"shared_album_section_people_action_error": "Error leaving/removing from album",
|
||||
"shared_album_section_people_action_leave": "Remove user from album",
|
||||
"shared_album_section_people_action_remove_user": "Remove user from album",
|
||||
"shared_album_section_people_owner_label": "Owner",
|
||||
"shared_album_section_people_title": "PEOPLE",
|
||||
"share_dialog_preparing": "Preparing...",
|
||||
"shared_intent_upload_button_progress_text": "{} / {} Uploaded",
|
||||
"shared_link_app_bar_title": "Shared Links",
|
||||
"shared_link_clipboard_copied_massage": "Copied to clipboard",
|
||||
"shared_link_clipboard_text": "Link: {}\nPassword: {}",
|
||||
"shared_link_create_app_bar_title": "Create link to share",
|
||||
"shared_link_create_error": "Error while creating shared link",
|
||||
"shared_link_create_info": "Let anyone with the link see the selected photo(s)",
|
||||
"shared_link_create_submit_button": "Create link",
|
||||
"shared_link_edit_allow_download": "Allow public user to download",
|
||||
"shared_link_edit_allow_upload": "Allow public user to upload",
|
||||
"shared_link_edit_app_bar_title": "Edit link",
|
||||
"shared_link_edit_change_expiry": "Change expiration time",
|
||||
"shared_link_edit_description": "Description",
|
||||
"shared_link_edit_description_hint": "Enter the share description",
|
||||
"shared_link_edit_expire_after": "Expire after",
|
||||
"shared_link_edit_expire_after_option_day": "1 day",
|
||||
"shared_link_edit_expire_after_option_days": "{} days",
|
||||
"shared_link_edit_expire_after_option_hour": "1 hour",
|
||||
"shared_link_edit_expire_after_option_hours": "{} hours",
|
||||
"shared_link_edit_expire_after_option_minute": "1 minute",
|
||||
"shared_link_edit_expire_after_option_minutes": "{} minutes",
|
||||
"shared_link_edit_expire_after_option_months": "{} months",
|
||||
"shared_link_edit_expire_after_option_never": "Never",
|
||||
"shared_link_edit_expire_after_option_year": "{} year",
|
||||
"shared_link_edit_password": "Password",
|
||||
"shared_link_edit_password_hint": "Enter the share password",
|
||||
"shared_link_edit_show_meta": "Show metadata",
|
||||
"shared_link_edit_submit_button": "Update link",
|
||||
"shared_link_empty": "You don't have any shared links",
|
||||
"shared_link_error_server_url_fetch": "Cannot fetch the server url",
|
||||
"shared_link_expired": "Expired",
|
||||
"shared_link_expires_day": "Expires in {} day",
|
||||
"shared_link_expires_days": "Expires in {} days",
|
||||
"shared_link_expires_hour": "Expires in {} hour",
|
||||
"shared_link_expires_hours": "Expires in {} hours",
|
||||
"shared_link_expires_minute": "Expires in {} minute",
|
||||
"shared_link_expires_minutes": "Expires in {} minutes",
|
||||
"shared_link_expires_never": "Expires ∞",
|
||||
"shared_link_expires_second": "Expires in {} second",
|
||||
"shared_link_expires_seconds": "Expires in {} seconds",
|
||||
"shared_link_individual_shared": "Individual shared",
|
||||
"shared_link_info_chip_download": "Download",
|
||||
"shared_link_info_chip_metadata": "EXIF",
|
||||
"shared_link_info_chip_upload": "Upload",
|
||||
"shared_link_manage_links": "Manage Shared links",
|
||||
"shared_link_public_album": "Public album",
|
||||
"shared_links": "Shared links",
|
||||
"share_done": "Done",
|
||||
"shared_with_me": "Shared with me",
|
||||
"share_invite": "Invite to album",
|
||||
"sharing_page_album": "Shared albums",
|
||||
"sharing_page_description": "Create shared albums to share photos and videos with people in your network.",
|
||||
"sharing_page_empty_list": "EMPTY LIST",
|
||||
"sharing_silver_appbar_create_shared_album": "New shared album",
|
||||
"sharing_silver_appbar_shared_links": "Shared links",
|
||||
"sharing_silver_appbar_share_partner": "Share with partner",
|
||||
"start_date": "Start date",
|
||||
"sync": "Sync",
|
||||
"sync_albums": "Sync albums",
|
||||
"sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums",
|
||||
"sync_upload_album_setting_subtitle": "Create and upload your photos and videos to the selected albums on Immich",
|
||||
"tab_controller_nav_library": "Library",
|
||||
"tab_controller_nav_photos": "Photos",
|
||||
"tab_controller_nav_search": "Search",
|
||||
"tab_controller_nav_sharing": "Sharing",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({})",
|
||||
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
|
||||
"theme_setting_colorful_interface_title": "Colorful interface",
|
||||
"theme_setting_dark_mode_switch": "Dark mode",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Adjust the quality of the detail image viewer",
|
||||
"theme_setting_image_viewer_quality_title": "Image viewer quality",
|
||||
"theme_setting_primary_color_subtitle": "Pick a color for primary actions and accents.",
|
||||
"theme_setting_primary_color_title": "Primary color",
|
||||
"theme_setting_system_primary_color_title": "Use system color",
|
||||
"theme_setting_system_theme_switch": "Automatic (Follow system setting)",
|
||||
"theme_setting_theme_subtitle": "Choose the app's theme setting",
|
||||
"theme_setting_theme_title": "Theme",
|
||||
"theme_setting_three_stage_loading_subtitle": "Three-stage loading might increase the loading performance but causes significantly higher network load",
|
||||
"theme_setting_three_stage_loading_title": "Enable three-stage loading",
|
||||
"translated_text_options": "Options",
|
||||
"trash": "Trash",
|
||||
"trash_emptied": "Emptied trash",
|
||||
"trash_page_delete": "Delete",
|
||||
"trash_page_delete_all": "Delete All",
|
||||
"trash_page_empty_trash_btn": "Empty trash",
|
||||
"trash_page_empty_trash_dialog_content": "Do you want to empty your trashed assets? These items will be permanently removed from Immich",
|
||||
"trash_page_empty_trash_dialog_ok": "Ok",
|
||||
"trash_page_info": "Trashed items will be permanently deleted after {} days",
|
||||
"trash_page_no_assets": "No trashed assets",
|
||||
"trash_page_restore": "Restore",
|
||||
"trash_page_restore_all": "Restore All",
|
||||
"trash_page_select_assets_btn": "Select assets",
|
||||
"trash_page_select_btn": "Select",
|
||||
"trash_page_title": "Trash ({})",
|
||||
"upload": "Upload",
|
||||
"upload_dialog_cancel": "Cancel",
|
||||
"upload_dialog_info": "Do you want to backup the selected Asset(s) to the server?",
|
||||
"upload_dialog_ok": "Upload",
|
||||
"upload_dialog_title": "Upload Asset",
|
||||
"uploading": "Uploading",
|
||||
"upload_to_immich": "Upload to Immich ({})",
|
||||
"use_current_connection": "use current connection",
|
||||
"validate_endpoint_error": "Please enter a valid URL",
|
||||
"version_announcement_overlay_ack": "Acknowledge",
|
||||
"version_announcement_overlay_release_notes": "release notes",
|
||||
"version_announcement_overlay_text_1": "Hi friend, there is a new release of",
|
||||
"version_announcement_overlay_text_2": "please take your time to visit the ",
|
||||
"version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
|
||||
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89",
|
||||
"videos": "Videos",
|
||||
"viewer_remove_from_stack": "Remove from Stack",
|
||||
"viewer_stack_use_as_main_asset": "Use as Main Asset",
|
||||
"viewer_unstack": "Un-Stack",
|
||||
"wifi_name": "WiFi Name",
|
||||
"your_wifi_name": "Your WiFi name"
|
||||
}
|
||||
@@ -336,9 +336,9 @@
|
||||
"login_form_back_button_text": "חזרה",
|
||||
"login_form_button_text": "התחברות",
|
||||
"login_form_email_hint": "yourmail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/API",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "כתובת נקודת קצה השרת",
|
||||
"login_form_err_http": "נא לציין //:htttp או //:https",
|
||||
"login_form_err_http": "נא לציין //:http או //:https",
|
||||
"login_form_err_invalid_email": "דוא\"ל שגוי",
|
||||
"login_form_err_invalid_url": "כתובת לא חוקית",
|
||||
"login_form_err_leading_whitespace": "רווח לבן מוביל",
|
||||
@@ -670,4 +670,4 @@
|
||||
"viewer_unstack": "ביטול ערימה",
|
||||
"wifi_name": "שם אינטרנט אלחוטי",
|
||||
"your_wifi_name": "שם אינטרנט אלחוטי שלך"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Vissza",
|
||||
"login_form_button_text": "Bejelentkezés",
|
||||
"login_form_email_hint": "email@cimed.hu",
|
||||
"login_form_endpoint_hint": "http(s)://szerver-címe:port/api",
|
||||
"login_form_endpoint_hint": "http://szerver-címe:port",
|
||||
"login_form_endpoint_url": "Szerver címe",
|
||||
"login_form_err_http": "Kérjük, hogy egy http:// vagy https:// címet adj meg",
|
||||
"login_form_err_invalid_email": "Érvénytelen email cím",
|
||||
@@ -670,4 +670,4 @@
|
||||
"viewer_unstack": "Csoport Megszűntetése",
|
||||
"wifi_name": "WiFi Name",
|
||||
"your_wifi_name": "Your WiFi name"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Kembali",
|
||||
"login_form_button_text": "Masuk",
|
||||
"login_form_email_hint": "emailmu@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-server-anda:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-server-anda:port",
|
||||
"login_form_endpoint_url": "URL Endpoint Server",
|
||||
"login_form_err_http": "Harap tentukan http:// atau https://",
|
||||
"login_form_err_invalid_email": "Email Tidak Valid",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Indietro",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "tuaemail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-del-tuo-server:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-del-tuo-server:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Per favore specificare http:// o https://",
|
||||
"login_form_err_invalid_email": "Email non valida",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "戻る",
|
||||
"login_form_button_text": "ログイン",
|
||||
"login_form_email_hint": "hoge@email.com",
|
||||
"login_form_endpoint_hint": "https://example.com:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "サーバーのエンドポイントURL",
|
||||
"login_form_err_http": "http://かhttps://かを指定してください",
|
||||
"login_form_err_invalid_email": "メールアドレスが無効です",
|
||||
@@ -670,4 +670,4 @@
|
||||
"viewer_unstack": "スタックを解除",
|
||||
"wifi_name": "Wi-Fiの名前(SSID)",
|
||||
"your_wifi_name": "Wi-Fiの名前(SSID)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "뒤로",
|
||||
"login_form_button_text": "로그인",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "서버 엔드포인트 URL",
|
||||
"login_form_err_http": "http:// 또는 https://로 시작해야 합니다.",
|
||||
"login_form_err_invalid_email": "유효하지 않은 이메일",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Atpakaļ",
|
||||
"login_form_button_text": "Pieteikties",
|
||||
"login_form_email_hint": "jūsuepasts@email.com",
|
||||
"login_form_endpoint_hint": "http://jūsu-servera-ip:ports/api",
|
||||
"login_form_endpoint_hint": "http://jūsu-servera-ip:ports",
|
||||
"login_form_endpoint_url": "Servera Galapunkta URL",
|
||||
"login_form_err_http": "Lūdzu norādiet http:// vai https://",
|
||||
"login_form_err_invalid_email": "Nederīgs e-pasts",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Tilbake",
|
||||
"login_form_button_text": "Logg inn",
|
||||
"login_form_email_hint": "dinepost@epost.no",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port",
|
||||
"login_form_endpoint_url": "Serverendepunkt-URL",
|
||||
"login_form_err_http": "Vennligst spesifiser http:// eller https://",
|
||||
"login_form_err_invalid_email": "Ugyldig e-postadresse",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Terug",
|
||||
"login_form_button_text": "Inloggen",
|
||||
"login_form_email_hint": "jouwemail@email.nl",
|
||||
"login_form_endpoint_hint": "http://jouw-server-ip:poort/api",
|
||||
"login_form_endpoint_hint": "http://jouw-server-ip:poort",
|
||||
"login_form_endpoint_url": "Server-URL",
|
||||
"login_form_err_http": "Voer http:// of https:// in",
|
||||
"login_form_err_invalid_email": "Ongeldig e-mailadres",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Cofnij",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "twojmail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-twojego-serwera:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-twojego-serwera:port",
|
||||
"login_form_endpoint_url": "URL Serwera",
|
||||
"login_form_err_http": "Proszę określić http:// lub https://",
|
||||
"login_form_err_invalid_email": "Niepoprawny Email",
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"exif_bottom_sheet_location": "LOCALIZAÇÃO",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "E-mail inválido",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Voltar",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "seuemail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-do-seu-servidor:porta/api",
|
||||
"login_form_endpoint_hint": "http://ip-do-seu-servidor:porta",
|
||||
"login_form_endpoint_url": "URL do servidor",
|
||||
"login_form_err_http": "Por favor especifique http:// ou https://",
|
||||
"login_form_err_invalid_email": "Email Inválido",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Înapoi",
|
||||
"login_form_button_text": "Conectare",
|
||||
"login_form_email_hint": "email-ultau@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-server:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-server:port",
|
||||
"login_form_endpoint_url": "URL-ul destinației sever-ului",
|
||||
"login_form_err_http": "Te rugăm specifică http:// sau https://",
|
||||
"login_form_err_invalid_email": "Email invalid",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Назад",
|
||||
"login_form_button_text": "Войти",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "URL-aдрес сервера",
|
||||
"login_form_err_http": "Пожалуйста, укажите протокол http:// или https://",
|
||||
"login_form_err_invalid_email": "Некорректный адрес электронной почты",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Späť",
|
||||
"login_form_button_text": "Prihlásiť sa",
|
||||
"login_form_email_hint": "tvojmail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-tvojho-servera:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-tvojho-servera:port",
|
||||
"login_form_endpoint_url": "URL adresa servera",
|
||||
"login_form_err_http": "Prosím, uveďte http:// alebo https://",
|
||||
"login_form_err_invalid_email": "Neplatný e-mail",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Nazaj",
|
||||
"login_form_button_text": "Prijava",
|
||||
"login_form_email_hint": "vašemail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-vašega-strežnika:vrata/api",
|
||||
"login_form_endpoint_hint": "http://ip-vašega-strežnika:vrata",
|
||||
"login_form_endpoint_url": "URL končne točke strežnika",
|
||||
"login_form_err_http": "Navedi http:// ali https://",
|
||||
"login_form_err_invalid_email": "Neveljaven e-poštni naslov",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Prijavi se",
|
||||
"login_form_email_hint": "vašemail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-vašeg-servera:port/api",
|
||||
"login_form_endpoint_hint": "http://ip-vašeg-servera:port",
|
||||
"login_form_endpoint_url": "URL Servera",
|
||||
"login_form_err_http": "Dopiši http:// ili https://",
|
||||
"login_form_err_invalid_email": "Nevažeći Email",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Back",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Please specify http:// or https://",
|
||||
"login_form_err_invalid_email": "Invalid Email",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Bakåt",
|
||||
"login_form_button_text": "Logga in",
|
||||
"login_form_email_hint": "din.email@email.com",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Var god ange http:// eller https://",
|
||||
"login_form_err_invalid_email": "Ogiltig email",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "กลับ",
|
||||
"login_form_button_text": "เข้าสู่ระบบ",
|
||||
"login_form_email_hint": "อีเมลคุณ@อีเมล.com",
|
||||
"login_form_endpoint_hint": "http://ไอพีเชอร์ฟเวอร์คุณ:พอร์ต/api",
|
||||
"login_form_endpoint_hint": "http://ไอพีเชอร์ฟเวอร์คุณ:พอร์ต",
|
||||
"login_form_endpoint_url": "URL ปลายทางของเซิร์ฟเวอร์",
|
||||
"login_form_err_http": "โปรดระบุ http:// หรือ https://",
|
||||
"login_form_err_invalid_email": "อีเมลไม่ถูกต้อง",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Geri",
|
||||
"login_form_button_text": "Giriş",
|
||||
"login_form_email_hint": "mail@adresiniz.com",
|
||||
"login_form_endpoint_hint": "http://sunucu-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://sunucu-ip:port",
|
||||
"login_form_endpoint_url": "Sunucu Uç Nokta URL",
|
||||
"login_form_err_http": "Lütfen http:// veya https:// olarak belirtin",
|
||||
"login_form_err_invalid_email": "Geçersiz E-posta",
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
"action_common_select": "Вибрати",
|
||||
"action_common_update": "Оновити",
|
||||
"add_a_name": "Додати ім'я",
|
||||
"add_endpoint": "Add endpoint",
|
||||
"add_endpoint": "Додати кінцеву точку",
|
||||
"add_to_album_bottom_sheet_added": "Додано до {album}",
|
||||
"add_to_album_bottom_sheet_already_exists": "Вже є в {album}",
|
||||
"advanced_settings_log_level_title": "Log level: {}",
|
||||
"advanced_settings_log_level_title": "Рівень журналу: {}",
|
||||
"advanced_settings_prefer_remote_subtitle": "Деякі пристрої вельми повільно завантажують мініатюри із елементів на пристрої. Активуйте для завантаження віддалених мініатюр натомість.",
|
||||
"advanced_settings_prefer_remote_title": "Перевага віддаленим зображенням",
|
||||
"advanced_settings_proxy_headers_subtitle": "Визначте заголовки проксі-сервера, які Immich має надсилати з кожним мережевим запитом.",
|
||||
@@ -66,12 +66,12 @@
|
||||
"assets_restored_successfully": "{} елемент(и) успішно відновлено",
|
||||
"assets_trashed": "{} елемент(и) поміщено до кошика",
|
||||
"assets_trashed_from_server": "{} елемент(и) поміщено до кошика на сервері Immich",
|
||||
"asset_viewer_settings_subtitle": "Manage your gallery viewer settings",
|
||||
"asset_viewer_settings_subtitle": "Керувати налаштуваннями переглядача галереї",
|
||||
"asset_viewer_settings_title": "Переглядач зображень",
|
||||
"automatic_endpoint_switching_subtitle": "Connect locally over designated Wi-Fi when available and use alternative connections elsewhere",
|
||||
"automatic_endpoint_switching_title": "Automatic URL switching",
|
||||
"background_location_permission": "Background location permission",
|
||||
"background_location_permission_content": "In order to switch networks when running in the background, Immich must *always* have precise location access so the app can read the Wi-Fi network's name",
|
||||
"automatic_endpoint_switching_subtitle": "Підключатися локально через визначену Wi-Fi мережу, коли вона доступна, і використовувати альтернативні з'єднання в інших випадках",
|
||||
"automatic_endpoint_switching_title": "Автоперемикання URL-адрес",
|
||||
"background_location_permission": "Дозвіл на місцезнаходження у фоні",
|
||||
"background_location_permission_content": "Щоб перемикатися між мережами під час роботи у фоновому режимі, Immich *завжди* повинен мати доступ до точного місцезнаходження, щоб додаток міг зчитувати назву Wi-Fi мережі",
|
||||
"backup_album_selection_page_albums_device": "Альбоми на пристрої ({})",
|
||||
"backup_album_selection_page_albums_tap": "Торкніться, щоб включити,\nторкніться двічі, щоб виключити",
|
||||
"backup_album_selection_page_assets_scatter": "Елементи можуть належати до кількох альбомів водночас. Таким чином, альбоми можуть бути включені або вилучені під час резервного копіювання.",
|
||||
@@ -137,7 +137,7 @@
|
||||
"backup_manual_success": "Успіх",
|
||||
"backup_manual_title": "Стан завантаження",
|
||||
"backup_options_page_title": "Резервне копіювання",
|
||||
"backup_setting_subtitle": "Manage background and foreground upload settings",
|
||||
"backup_setting_subtitle": "Керування завантаженням у фоновому та передньому режимах",
|
||||
"cache_settings_album_thumbnails": "Мініатюри сторінок бібліотеки ({} елементи)",
|
||||
"cache_settings_clear_cache_button": "Очистити кеш",
|
||||
"cache_settings_clear_cache_button_title": "Очищає кеш програми. Це суттєво знизить продуктивність програми, доки кеш не буде перебудовано.",
|
||||
@@ -156,17 +156,17 @@
|
||||
"cache_settings_tile_subtitle": "Керування поведінкою локального сховища",
|
||||
"cache_settings_tile_title": "Локальне сховище",
|
||||
"cache_settings_title": "Налаштування кешування",
|
||||
"cancel": "Cancel",
|
||||
"canceled": "Canceled",
|
||||
"change_display_order": "Change display order",
|
||||
"cancel": "Скасувати",
|
||||
"canceled": "Скасовано",
|
||||
"change_display_order": "Змінити порядок відображення",
|
||||
"change_password_form_confirm_password": "Підтвердити пароль",
|
||||
"change_password_form_description": "Привіт {name},\n\nВи або або вперше входите у систему, або було зроблено запит на зміну вашого пароля. \nВведіть ваш новий пароль.",
|
||||
"change_password_form_new_password": "Новий пароль",
|
||||
"change_password_form_password_mismatch": "Паролі не співпадають",
|
||||
"change_password_form_reenter_new_password": "Повторіть новий пароль",
|
||||
"check_corrupt_asset_backup": "Check for corrupt asset backups",
|
||||
"check_corrupt_asset_backup_button": "Perform check",
|
||||
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
|
||||
"check_corrupt_asset_backup": "Перевірити пошкоджені резервні копії",
|
||||
"check_corrupt_asset_backup_button": "Виконати перевірку",
|
||||
"check_corrupt_asset_backup_description": "Виконуйте цю перевірку лише через Wi-Fi та після того, як усі активи будуть заархівовані. Процес може зайняти кілька хвилин.",
|
||||
"client_cert_dialog_msg_confirm": "OK",
|
||||
"client_cert_enter_password": "Введіть пароль",
|
||||
"client_cert_import": "Імпорт",
|
||||
@@ -181,7 +181,7 @@
|
||||
"common_create_new_album": "Створити новий альбом",
|
||||
"common_server_error": "Будь ласка, перевірте з'єднання, переконайтеся, що сервер доступний і версія програми/сервера сумісна.",
|
||||
"common_shared": "Спільні",
|
||||
"completed": "Completed",
|
||||
"completed": "Завершено",
|
||||
"contextual_search": "Схід сонця на пляжі",
|
||||
"control_bottom_app_bar_add_to_album": "Додати у альбом",
|
||||
"control_bottom_app_bar_album_info": "{} елементи",
|
||||
@@ -199,7 +199,7 @@
|
||||
"control_bottom_app_bar_share": "Поділитися",
|
||||
"control_bottom_app_bar_share_to": "Поділитися",
|
||||
"control_bottom_app_bar_stack": "Стек",
|
||||
"control_bottom_app_bar_trash_from_immich": "Перемістити до кошика",
|
||||
"control_bottom_app_bar_trash_from_immich": "В кошик",
|
||||
"control_bottom_app_bar_unarchive": "Розархівувати",
|
||||
"control_bottom_app_bar_unfavorite": "Видалити з улюблених",
|
||||
"control_bottom_app_bar_upload": "Завантажити",
|
||||
@@ -213,7 +213,7 @@
|
||||
"crop": "Кадрувати",
|
||||
"curated_location_page_title": "Місця",
|
||||
"curated_object_page_title": "Речі",
|
||||
"current_server_address": "Current server address",
|
||||
"current_server_address": "Поточна адреса сервера",
|
||||
"daily_title_text_date": "E, MMM dd",
|
||||
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
||||
"date_format": "E, LLL d, y • h:mm a",
|
||||
@@ -250,10 +250,10 @@
|
||||
"edit_date_time_dialog_timezone": "Часовий пояс",
|
||||
"edit_image_title": "Редагувати",
|
||||
"edit_location_dialog_title": "Місцезнаходження",
|
||||
"end_date": "End date",
|
||||
"enqueued": "Enqueued",
|
||||
"enter_wifi_name": "Enter WiFi name",
|
||||
"error_change_sort_album": "Failed to change album sort order",
|
||||
"end_date": "Дата завершення",
|
||||
"enqueued": "В черзі",
|
||||
"enter_wifi_name": "Введіть назву Wi-Fi",
|
||||
"error_change_sort_album": "Не вдалося змінити порядок сортування альбому",
|
||||
"error_saving_image": "Помилка: {}",
|
||||
"exif_bottom_sheet_description": "Додати опис...",
|
||||
"exif_bottom_sheet_details": "ПОДРОБИЦІ",
|
||||
@@ -265,16 +265,16 @@
|
||||
"experimental_settings_new_asset_list_title": "Експериментальний макет знімків",
|
||||
"experimental_settings_subtitle": "На власний ризик!",
|
||||
"experimental_settings_title": "Експериментальні",
|
||||
"external_network": "External network",
|
||||
"external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
|
||||
"failed": "Failed",
|
||||
"external_network": "Зовнішня мережа",
|
||||
"external_network_sheet_info": "Якщо ви не підключені до бажаної Wi-Fi мережі, додаток підключиться до сервера через першу доступну URL-адресу зверху вниз",
|
||||
"failed": "Не вдалося",
|
||||
"favorites": "Вибране",
|
||||
"favorites_page_no_favorites": "Немає улюблених елементів",
|
||||
"favorites_page_title": "Улюблені",
|
||||
"filename_search": "Ім'я або розширення файлу",
|
||||
"filter": "Фільтр",
|
||||
"get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network",
|
||||
"grant_permission": "Grant permission",
|
||||
"get_wifiname_error": "Не вдалося отримати назву Wi-Fi мережі. Переконайтеся, що ви надали необхідні дозволи та підключені до Wi-Fi мережі",
|
||||
"grant_permission": "Надати дозвіл",
|
||||
"haptic_feedback_switch": "Увімкнути тактильну віддачу",
|
||||
"haptic_feedback_title": "Тактильна віддача",
|
||||
"header_settings_add_header_tip": "Додати заголовок",
|
||||
@@ -320,10 +320,10 @@
|
||||
"library_page_sort_most_oldest_photo": "Найдавніші фото",
|
||||
"library_page_sort_most_recent_photo": "Найновіші фото",
|
||||
"library_page_sort_title": "Назва альбому",
|
||||
"local_network": "Local network",
|
||||
"local_network_sheet_info": "The app will connect to the server through this URL when using the specified Wi-Fi network",
|
||||
"location_permission": "Location permission",
|
||||
"location_permission_content": "In order to use the auto-switching feature, Immich needs precise location permission so it can read the current WiFi network's name",
|
||||
"local_network": "Локальна мережа",
|
||||
"local_network_sheet_info": "Додаток підключатиметься до сервера через цю URL-адресу при використанні вказаної Wi-Fi мережі",
|
||||
"location_permission": "Дозвіл до місцезнаходження",
|
||||
"location_permission_content": "Для використання функції автоперемикання Immich потрібен дозвіл на точне місцезнаходження, щоб зчитувати назву поточної Wi-Fi мережі",
|
||||
"location_picker_choose_on_map": "Обрати на мапі",
|
||||
"location_picker_latitude": "Широта",
|
||||
"location_picker_latitude_error": "Вкажіть дійсну широту",
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Назад",
|
||||
"login_form_button_text": "Увійти",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port",
|
||||
"login_form_endpoint_url": "Адреса точки досупу на сервері",
|
||||
"login_form_err_http": "Вкажіть http:// або https://",
|
||||
"login_form_err_invalid_email": "Хибний імейл",
|
||||
@@ -393,8 +393,8 @@
|
||||
"multiselect_grid_edit_date_time_err_read_only": "Неможливо редагувати дату елементів лише для читання, пропущено",
|
||||
"multiselect_grid_edit_gps_err_read_only": "Неможливо редагувати місцезнаходження елементів лише для читання, пропущено",
|
||||
"my_albums": "Мої альбоми",
|
||||
"networking_settings": "Networking",
|
||||
"networking_subtitle": "Manage the server endpoint settings",
|
||||
"networking_settings": "Мережа",
|
||||
"networking_subtitle": "Керувати налаштуваннями кінцевої точки сервера",
|
||||
"no_assets_to_show": "Елементи відсутні",
|
||||
"no_name": "Без імені",
|
||||
"notification_permission_dialog_cancel": "Скасувати",
|
||||
@@ -403,7 +403,7 @@
|
||||
"notification_permission_list_tile_content": "Надати дозвіл для сповіщень.",
|
||||
"notification_permission_list_tile_enable_button": "Увімкнути Сповіщення",
|
||||
"notification_permission_list_tile_title": "Дозвіл на Сповіщення",
|
||||
"not_selected": "Not selected",
|
||||
"not_selected": "Не вибрано",
|
||||
"on_this_device": "На цьому пристрої",
|
||||
"partner_list_user_photos": "Фотографії {user}",
|
||||
"partner_list_view_all": "Переглянути усі",
|
||||
@@ -417,7 +417,7 @@
|
||||
"partner_page_stop_sharing_title": "Припинити надання ваших знімків?",
|
||||
"partner_page_title": "Партнер",
|
||||
"partners": "\nПартнери",
|
||||
"paused": "Paused",
|
||||
"paused": "Призупинено",
|
||||
"people": "Люди",
|
||||
"permission_onboarding_back": "Назад",
|
||||
"permission_onboarding_continue_anyway": "Все одно продовжити",
|
||||
@@ -430,7 +430,7 @@
|
||||
"permission_onboarding_permission_limited": "Обмежений доступ. Аби дозволити Immich резервне копіювання та керування вашою галереєю, надайте доступ до знімків та відео у Налаштуваннях",
|
||||
"permission_onboarding_request": "Immich потребує доступу до ваших знімків та відео.",
|
||||
"places": "Місця",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
"preferences_settings_subtitle": "Керувати налаштуваннями додатка",
|
||||
"preferences_settings_title": "Параметри",
|
||||
"profile_drawer_app_logs": "Журнал",
|
||||
"profile_drawer_client_out_of_date_major": "Мобільний додаток застарів. Будь ласка, оновіть до останньої мажорної версії.",
|
||||
@@ -445,7 +445,7 @@
|
||||
"profile_drawer_trash": "Кошик",
|
||||
"recently_added": "Нещодавно додані",
|
||||
"recently_added_page_title": "Нещодавні",
|
||||
"save": "Save",
|
||||
"save": "Зберегти",
|
||||
"save_to_gallery": "Зберегти в галерею",
|
||||
"scaffold_body_error_occurred": "Виникла помилка",
|
||||
"search_albums": "Пошук альбому",
|
||||
@@ -491,7 +491,7 @@
|
||||
"search_page_places": "Місця",
|
||||
"search_page_recently_added": "Нещодавно додані",
|
||||
"search_page_screenshots": "Знімки екрану",
|
||||
"search_page_search_photos_videos": "Search for your photos and videos",
|
||||
"search_page_search_photos_videos": "Шукайте ваші фотографії та відео",
|
||||
"search_page_selfies": "Селфі",
|
||||
"search_page_things": "Речі",
|
||||
"search_page_videos": "Відео",
|
||||
@@ -504,7 +504,7 @@
|
||||
"select_additional_user_for_sharing_page_suggestions": "Пропозиції",
|
||||
"select_user_for_sharing_page_err_album": "Не вдалося створити альбом",
|
||||
"select_user_for_sharing_page_share_suggestions": "Пропозиції",
|
||||
"server_endpoint": "Server Endpoint",
|
||||
"server_endpoint": "Кінцева точка сервера",
|
||||
"server_info_box_app_version": "Версія додатка",
|
||||
"server_info_box_latest_release": "Остання версія",
|
||||
"server_info_box_server_url": "URL сервера",
|
||||
@@ -516,7 +516,7 @@
|
||||
"setting_image_viewer_preview_title": "Завантажувати зображення попереднього перегляду",
|
||||
"setting_image_viewer_title": "Зображення",
|
||||
"setting_languages_apply": "Застосувати",
|
||||
"setting_languages_subtitle": "Change the app's language",
|
||||
"setting_languages_subtitle": "Змінити мову додатка",
|
||||
"setting_languages_title": "Мова",
|
||||
"setting_notifications_notify_failures_grace_period": "Повідомити про помилки фонового резервного копіювання: {}",
|
||||
"setting_notifications_notify_hours": "{} годин",
|
||||
@@ -534,8 +534,8 @@
|
||||
"settings_require_restart": "Перезавантажте програму для застосування цього налаштування",
|
||||
"setting_video_viewer_looping_subtitle": "Увімкнути циклічне відтворення відео",
|
||||
"setting_video_viewer_looping_title": "Циклічне відтворення",
|
||||
"setting_video_viewer_original_video_subtitle": "When streaming a video from the server, play the original even when a transcode is available. May lead to buffering. Videos available locally are played in original quality regardless of this setting.",
|
||||
"setting_video_viewer_original_video_title": "Force original video",
|
||||
"setting_video_viewer_original_video_subtitle": "При трансляції відео з сервера відтворювати оригінал, навіть якщо доступне транскодоване відео. Це може призвести до буферизації. Відео, доступні локально, відтворюються в оригінальній якості, незалежно від цього налаштування.",
|
||||
"setting_video_viewer_original_video_title": "Примусово відтворювати оригінальне відео",
|
||||
"setting_video_viewer_title": "Відео",
|
||||
"share_add": "Додати",
|
||||
"share_add_photos": "Додати знімки",
|
||||
@@ -554,7 +554,7 @@
|
||||
"shared_album_section_people_owner_label": "Власник",
|
||||
"shared_album_section_people_title": "ЛЮДИ",
|
||||
"share_dialog_preparing": "Підготовка...",
|
||||
"shared_intent_upload_button_progress_text": "{} / {} Uploaded",
|
||||
"shared_intent_upload_button_progress_text": "{} / {} Завантажено",
|
||||
"shared_link_app_bar_title": "Спільні посилання",
|
||||
"shared_link_clipboard_copied_massage": "Скопійовано в буфер обміну",
|
||||
"shared_link_clipboard_text": "Посилання: {}\nПароль: {}",
|
||||
@@ -649,15 +649,15 @@
|
||||
"trash_page_select_assets_btn": "Вибрані елементи",
|
||||
"trash_page_select_btn": "Вибрати",
|
||||
"trash_page_title": "Кошик ({})",
|
||||
"upload": "Upload",
|
||||
"upload": "Завантажити",
|
||||
"upload_dialog_cancel": "Скасувати",
|
||||
"upload_dialog_info": "Бажаєте створити резервну копію вибраних елементів на сервері?",
|
||||
"upload_dialog_ok": "Завантажити",
|
||||
"upload_dialog_title": "Завантажити Елементи",
|
||||
"uploading": "Uploading",
|
||||
"upload_to_immich": "Upload to Immich ({})",
|
||||
"use_current_connection": "use current connection",
|
||||
"validate_endpoint_error": "Please enter a valid URL",
|
||||
"uploading": "Завантажується",
|
||||
"upload_to_immich": "Завантажити в Immich ({})",
|
||||
"use_current_connection": "використовувати поточне з'єднання",
|
||||
"validate_endpoint_error": "Будь ласка, введіть дійсну URL-адресу.",
|
||||
"version_announcement_overlay_ack": "Прийняти",
|
||||
"version_announcement_overlay_release_notes": "примітки до випуску",
|
||||
"version_announcement_overlay_text_1": "Вітаємо, є новий випуск ",
|
||||
@@ -668,6 +668,6 @@
|
||||
"viewer_remove_from_stack": "Видалити зі стеку",
|
||||
"viewer_stack_use_as_main_asset": "Використовувати як основний елементи",
|
||||
"viewer_unstack": "Розібрати стек",
|
||||
"wifi_name": "WiFi Name",
|
||||
"your_wifi_name": "Your WiFi name"
|
||||
}
|
||||
"wifi_name": "Назва Wi-Fi",
|
||||
"your_wifi_name": "Ваша Wi-Fi мережа"
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "Quay lại",
|
||||
"login_form_button_text": "Đăng nhập",
|
||||
"login_form_email_hint": "emailcuaban@email.com",
|
||||
"login_form_endpoint_hint": "http://địa-chỉ-ip-máy-chủ-bạn:cổng/api",
|
||||
"login_form_endpoint_hint": "http://địa-chỉ-ip-máy-chủ-bạn:cổng",
|
||||
"login_form_endpoint_url": "Địa chỉ máy chủ",
|
||||
"login_form_err_http": "Vui lòng xác định http:// hoặc https://",
|
||||
"login_form_err_invalid_email": "Email không hợp lệ",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "后退",
|
||||
"login_form_button_text": "登录",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http(s)://您的服务器地址:端口/api",
|
||||
"login_form_endpoint_hint": "http://您的服务器地址:端口",
|
||||
"login_form_endpoint_url": "服务器链接地址",
|
||||
"login_form_err_http": "请注明 http:// 或 https://",
|
||||
"login_form_err_invalid_email": "无效的电子邮箱",
|
||||
@@ -670,4 +670,4 @@
|
||||
"viewer_unstack": "取消堆叠",
|
||||
"wifi_name": "Wi-Fi 名称",
|
||||
"your_wifi_name": "您的 Wi-Fi 名称"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "后退",
|
||||
"login_form_button_text": "登录",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http(s)://您的服务器地址:端口/api",
|
||||
"login_form_endpoint_hint": "http://您的服务器地址:端口",
|
||||
"login_form_endpoint_url": "服务器链接地址",
|
||||
"login_form_err_http": "请注明 http:// 或 https://",
|
||||
"login_form_err_invalid_email": "无效的电子邮箱",
|
||||
@@ -670,4 +670,4 @@
|
||||
"viewer_unstack": "取消堆叠",
|
||||
"wifi_name": "Wi-Fi 名称",
|
||||
"your_wifi_name": "您的 Wi-Fi 名称"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
"login_form_back_button_text": "後退",
|
||||
"login_form_button_text": "登入",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http(s)://您的伺服器地址:端口/api",
|
||||
"login_form_endpoint_hint": "http://您的伺服器地址:端口",
|
||||
"login_form_endpoint_url": "伺服器鏈接地址",
|
||||
"login_form_err_http": "請注明 http:// 或 https://",
|
||||
"login_form_err_invalid_email": "電郵無效",
|
||||
@@ -670,4 +670,4 @@
|
||||
"viewer_unstack": "取消堆疊",
|
||||
"wifi_name": "WiFi Name",
|
||||
"your_wifi_name": "Your WiFi name"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,7 +541,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -685,7 +685,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -715,7 +715,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -748,7 +748,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
@@ -791,7 +791,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
@@ -831,7 +831,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.124.0</string>
|
||||
<string>1.125.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@@ -93,7 +93,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>187</string>
|
||||
<string>190</string>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<true/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
|
||||
@@ -19,7 +19,7 @@ platform :ios do
|
||||
desc "iOS Release"
|
||||
lane :release do
|
||||
increment_version_number(
|
||||
version_number: "1.125.1"
|
||||
version_number: "1.125.7"
|
||||
)
|
||||
increment_build_number(
|
||||
build_number: latest_testflight_build_number + 1,
|
||||
|
||||
@@ -262,6 +262,11 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
|
||||
PhotoViewGalleryPageOptions buildAsset(BuildContext context, int index) {
|
||||
var newAsset = loadAsset(index);
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
ref.read(currentAssetProvider.notifier).set(newAsset);
|
||||
});
|
||||
|
||||
final stackId = newAsset.stackId;
|
||||
if (stackId != null && currentIndex.value == index) {
|
||||
final stackElements =
|
||||
|
||||
@@ -83,11 +83,18 @@ class PhotosPage extends HookConsumerWidget {
|
||||
|
||||
Future<void> refreshAssets() async {
|
||||
final fullRefresh = refreshCount.value > 0;
|
||||
await ref.read(assetProvider.notifier).getAllAsset(clear: fullRefresh);
|
||||
|
||||
if (fullRefresh) {
|
||||
Future.wait([
|
||||
ref.read(assetProvider.notifier).getAllAsset(clear: true),
|
||||
ref.read(albumProvider.notifier).refreshRemoteAlbums(),
|
||||
]);
|
||||
|
||||
// refresh was forced: user requested another refresh within 2 seconds
|
||||
refreshCount.value = 0;
|
||||
} else {
|
||||
await ref.read(assetProvider.notifier).getAllAsset(clear: false);
|
||||
|
||||
refreshCount.value++;
|
||||
// set counter back to 0 if user does not request refresh again
|
||||
Timer(const Duration(seconds: 4), () => refreshCount.value = 0);
|
||||
|
||||
@@ -277,7 +277,6 @@ class SearchPage extends HookConsumerWidget {
|
||||
fieldEndHintText: 'end_date'.tr(),
|
||||
initialEntryMode: DatePickerEntryMode.calendar,
|
||||
keyboardType: TextInputType.text,
|
||||
locale: context.locale,
|
||||
);
|
||||
|
||||
if (date == null) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/duration_extensions.dart';
|
||||
import 'package:immich_mobile/widgets/common/dropdown_search_menu.dart';
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
import 'package:timezone/timezone.dart';
|
||||
|
||||
@@ -24,7 +25,7 @@ Future<String?> showDateTimePicker({
|
||||
}
|
||||
|
||||
String _getFormattedOffset(int offsetInMilli, tz.Location location) {
|
||||
return "${location.name} (UTC${Duration(milliseconds: offsetInMilli).formatAsOffset()})";
|
||||
return "${location.name} (${Duration(milliseconds: offsetInMilli).formatAsOffset()})";
|
||||
}
|
||||
|
||||
class _DateTimePicker extends HookWidget {
|
||||
@@ -73,7 +74,6 @@ class _DateTimePicker extends HookWidget {
|
||||
// returns a list of location<name> along with it's offset in duration
|
||||
List<_TimeZoneOffset> getAllTimeZones() {
|
||||
return tz.timeZoneDatabase.locations.values
|
||||
.where((l) => !l.currentTimeZone.abbreviation.contains("0"))
|
||||
.map(_TimeZoneOffset.fromLocation)
|
||||
.sorted()
|
||||
.toList();
|
||||
@@ -133,83 +133,78 @@ class _DateTimePicker extends HookWidget {
|
||||
context.pop(dtWithOffset);
|
||||
}
|
||||
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraint) => AlertDialog(
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(vertical: 32, horizontal: 18),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(
|
||||
"action_common_cancel",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: context.colorScheme.error,
|
||||
return AlertDialog(
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 32, horizontal: 18),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(
|
||||
"action_common_cancel",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: context.colorScheme.error,
|
||||
),
|
||||
).tr(),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: popWithDateTime,
|
||||
child: Text(
|
||||
"action_common_update",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
).tr(),
|
||||
),
|
||||
],
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"edit_date_time_dialog_date_time",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
).tr(),
|
||||
const SizedBox(height: 32),
|
||||
ListTile(
|
||||
tileColor: context.colorScheme.surfaceContainerHighest,
|
||||
shape: ShapeBorder.lerp(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
1,
|
||||
),
|
||||
trailing: Icon(
|
||||
Icons.edit_outlined,
|
||||
size: 18,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
title: Text(
|
||||
DateFormat("dd-MM-yyyy hh:mm a").format(date.value),
|
||||
style: context.textTheme.bodyMedium,
|
||||
).tr(),
|
||||
onTap: pickDate,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: popWithDateTime,
|
||||
child: Text(
|
||||
"action_common_update",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
).tr(),
|
||||
const SizedBox(height: 24),
|
||||
DropdownSearchMenu(
|
||||
trailingIcon: Icon(
|
||||
Icons.arrow_drop_down,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
hintText: "edit_date_time_dialog_timezone".tr(),
|
||||
label: const Text('edit_date_time_dialog_timezone').tr(),
|
||||
textStyle: context.textTheme.bodyMedium,
|
||||
onSelected: (value) => tzOffset.value = value,
|
||||
initialSelection: tzOffset.value,
|
||||
dropdownMenuEntries: menuEntries,
|
||||
),
|
||||
],
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"edit_date_time_dialog_date_time",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
).tr(),
|
||||
const SizedBox(height: 32),
|
||||
ListTile(
|
||||
tileColor: context.colorScheme.surfaceContainerHighest,
|
||||
shape: ShapeBorder.lerp(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
1,
|
||||
),
|
||||
trailing: Icon(
|
||||
Icons.edit_outlined,
|
||||
size: 18,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
title: Text(
|
||||
DateFormat("dd-MM-yyyy hh:mm a").format(date.value),
|
||||
style: context.textTheme.bodyMedium,
|
||||
).tr(),
|
||||
onTap: pickDate,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
DropdownMenu(
|
||||
width: 275,
|
||||
menuHeight: 300,
|
||||
trailingIcon: Icon(
|
||||
Icons.arrow_drop_down,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
hintText: "edit_date_time_dialog_timezone".tr(),
|
||||
label: const Text('edit_date_time_dialog_timezone').tr(),
|
||||
textStyle: context.textTheme.bodyMedium,
|
||||
onSelected: (value) => tzOffset.value = value!,
|
||||
initialSelection: tzOffset.value,
|
||||
dropdownMenuEntries: menuEntries,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
169
mobile/lib/widgets/common/dropdown_search_menu.dart
Normal file
169
mobile/lib/widgets/common/dropdown_search_menu.dart
Normal file
@@ -0,0 +1,169 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
|
||||
class DropdownSearchMenu<T> extends HookWidget {
|
||||
const DropdownSearchMenu({
|
||||
super.key,
|
||||
required this.dropdownMenuEntries,
|
||||
this.initialSelection,
|
||||
this.onSelected,
|
||||
this.trailingIcon,
|
||||
this.hintText,
|
||||
this.label,
|
||||
this.textStyle,
|
||||
this.menuConstraints,
|
||||
});
|
||||
|
||||
final List<DropdownMenuEntry<T>> dropdownMenuEntries;
|
||||
final T? initialSelection;
|
||||
final ValueChanged<T>? onSelected;
|
||||
final Widget? trailingIcon;
|
||||
final String? hintText;
|
||||
final Widget? label;
|
||||
final TextStyle? textStyle;
|
||||
final BoxConstraints? menuConstraints;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final selectedItem = useState<DropdownMenuEntry<T>?>(
|
||||
dropdownMenuEntries
|
||||
.firstWhereOrNull((item) => item.value == initialSelection),
|
||||
);
|
||||
final showTimeZoneDropdown = useState<bool>(false);
|
||||
|
||||
final effectiveConstraints = menuConstraints ??
|
||||
const BoxConstraints(
|
||||
minWidth: 280,
|
||||
maxWidth: 280,
|
||||
minHeight: 0,
|
||||
maxHeight: 280,
|
||||
);
|
||||
|
||||
final inputDecoration = InputDecoration(
|
||||
contentPadding: const EdgeInsets.fromLTRB(12, 4, 12, 4),
|
||||
border: const OutlineInputBorder(),
|
||||
suffixIcon: trailingIcon,
|
||||
label: label,
|
||||
hintText: hintText,
|
||||
).applyDefaults(context.themeData.inputDecorationTheme);
|
||||
|
||||
if (!showTimeZoneDropdown.value) {
|
||||
return ConstrainedBox(
|
||||
constraints: effectiveConstraints,
|
||||
child: GestureDetector(
|
||||
onTap: () => showTimeZoneDropdown.value = true,
|
||||
child: InputDecorator(
|
||||
decoration: inputDecoration,
|
||||
child: selectedItem.value != null
|
||||
? Text(
|
||||
selectedItem.value!.label,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: textStyle,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return ConstrainedBox(
|
||||
constraints: effectiveConstraints,
|
||||
child: Autocomplete<DropdownMenuEntry<T>>(
|
||||
displayStringForOption: (option) => option.label,
|
||||
optionsBuilder: (textEditingValue) {
|
||||
return dropdownMenuEntries.where(
|
||||
(item) => item.label
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.contains(textEditingValue.text.toLowerCase().trim()),
|
||||
);
|
||||
},
|
||||
onSelected: (option) {
|
||||
selectedItem.value = option;
|
||||
showTimeZoneDropdown.value = false;
|
||||
onSelected?.call(option.value);
|
||||
},
|
||||
fieldViewBuilder: (context, textEditingController, focusNode, _) {
|
||||
return TextField(
|
||||
autofocus: true,
|
||||
focusNode: focusNode,
|
||||
controller: textEditingController,
|
||||
decoration: inputDecoration.copyWith(
|
||||
hintText: "edit_date_time_dialog_search_timezone".tr(),
|
||||
),
|
||||
maxLines: 1,
|
||||
style: context.textTheme.bodyMedium,
|
||||
expands: false,
|
||||
onTapOutside: (event) {
|
||||
showTimeZoneDropdown.value = false;
|
||||
focusNode.unfocus();
|
||||
},
|
||||
onSubmitted: (_) {
|
||||
showTimeZoneDropdown.value = false;
|
||||
},
|
||||
);
|
||||
},
|
||||
optionsViewBuilder: (context, onSelected, options) {
|
||||
// This widget is a copy of the default implementation.
|
||||
// We have only changed the `constraints` parameter.
|
||||
return Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: ConstrainedBox(
|
||||
constraints: effectiveConstraints,
|
||||
child: Material(
|
||||
elevation: 4.0,
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
itemCount: options.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final option = options.elementAt(index);
|
||||
return InkWell(
|
||||
onTap: () => onSelected(option),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
final bool highlight =
|
||||
AutocompleteHighlightedOption.of(context) ==
|
||||
index;
|
||||
if (highlight) {
|
||||
SchedulerBinding.instance.addPostFrameCallback(
|
||||
(Duration timeStamp) {
|
||||
Scrollable.ensureVisible(
|
||||
context,
|
||||
alignment: 0.5,
|
||||
);
|
||||
},
|
||||
debugLabel: 'AutocompleteOptions.ensureVisible',
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
color: highlight
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurface
|
||||
.withOpacity(0.12)
|
||||
: null,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
option.label,
|
||||
style: textStyle,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,7 @@ class UserCircleAvatar extends ConsumerWidget {
|
||||
final profileImageUrl =
|
||||
'${Store.get(StoreKey.serverEndpoint)}/users/${user.id}/profile-image?d=${Random().nextInt(1024)}';
|
||||
|
||||
final textIcon = Text(
|
||||
user.name[0].toUpperCase(),
|
||||
final textIcon = DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
@@ -37,6 +36,7 @@ class UserCircleAvatar extends ConsumerWidget {
|
||||
? Colors.black
|
||||
: Colors.white,
|
||||
),
|
||||
child: Text(user.name[0].toUpperCase()),
|
||||
);
|
||||
return CircleAvatar(
|
||||
backgroundColor: user.avatarColor.toColor(),
|
||||
|
||||
@@ -102,7 +102,7 @@ class LocalNetworkPreference extends HookConsumerWidget {
|
||||
final localEndpoint = await _showEditDialog(
|
||||
context,
|
||||
"server_endpoint".tr(),
|
||||
"http://local-ip:2283/api",
|
||||
"http://local-ip:2283",
|
||||
localEndpointText.value,
|
||||
);
|
||||
|
||||
@@ -212,7 +212,7 @@ class LocalNetworkPreference extends HookConsumerWidget {
|
||||
leading: const Icon(Icons.lan_rounded),
|
||||
title: Text("server_endpoint".tr()),
|
||||
subtitle: localEndpointText.value.isEmpty
|
||||
? const Text("http://local-ip:2283/api")
|
||||
? const Text("http://local-ip:2283")
|
||||
: Text(
|
||||
localEndpointText.value,
|
||||
style: context.textTheme.labelLarge?.copyWith(
|
||||
|
||||
10
mobile/openapi/README.md
generated
10
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: 1.125.1
|
||||
- API version: 1.125.7
|
||||
- Generator version: 7.8.0
|
||||
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
||||
|
||||
@@ -93,17 +93,17 @@ Class | Method | HTTP request | Description
|
||||
*AlbumsApi* | [**removeUserFromAlbum**](doc//AlbumsApi.md#removeuserfromalbum) | **DELETE** /albums/{id}/user/{userId} |
|
||||
*AlbumsApi* | [**updateAlbumInfo**](doc//AlbumsApi.md#updatealbuminfo) | **PATCH** /albums/{id} |
|
||||
*AlbumsApi* | [**updateAlbumUser**](doc//AlbumsApi.md#updatealbumuser) | **PUT** /albums/{id}/user/{userId} |
|
||||
*AssetsApi* | [**checkBulkUpload**](doc//AssetsApi.md#checkbulkupload) | **POST** /assets/bulk-upload-check | Checks if assets exist by checksums
|
||||
*AssetsApi* | [**checkExistingAssets**](doc//AssetsApi.md#checkexistingassets) | **POST** /assets/exist | Checks if multiple assets exist on the server and returns all existing - used by background backup
|
||||
*AssetsApi* | [**checkBulkUpload**](doc//AssetsApi.md#checkbulkupload) | **POST** /assets/bulk-upload-check | checkBulkUpload
|
||||
*AssetsApi* | [**checkExistingAssets**](doc//AssetsApi.md#checkexistingassets) | **POST** /assets/exist | checkExistingAssets
|
||||
*AssetsApi* | [**deleteAssets**](doc//AssetsApi.md#deleteassets) | **DELETE** /assets |
|
||||
*AssetsApi* | [**downloadAsset**](doc//AssetsApi.md#downloadasset) | **GET** /assets/{id}/original |
|
||||
*AssetsApi* | [**getAllUserAssetsByDeviceId**](doc//AssetsApi.md#getalluserassetsbydeviceid) | **GET** /assets/device/{deviceId} | Get all asset of a device that are in the database, ID only.
|
||||
*AssetsApi* | [**getAllUserAssetsByDeviceId**](doc//AssetsApi.md#getalluserassetsbydeviceid) | **GET** /assets/device/{deviceId} | getAllUserAssetsByDeviceId
|
||||
*AssetsApi* | [**getAssetInfo**](doc//AssetsApi.md#getassetinfo) | **GET** /assets/{id} |
|
||||
*AssetsApi* | [**getAssetStatistics**](doc//AssetsApi.md#getassetstatistics) | **GET** /assets/statistics |
|
||||
*AssetsApi* | [**getMemoryLane**](doc//AssetsApi.md#getmemorylane) | **GET** /assets/memory-lane |
|
||||
*AssetsApi* | [**getRandom**](doc//AssetsApi.md#getrandom) | **GET** /assets/random |
|
||||
*AssetsApi* | [**playAssetVideo**](doc//AssetsApi.md#playassetvideo) | **GET** /assets/{id}/video/playback |
|
||||
*AssetsApi* | [**replaceAsset**](doc//AssetsApi.md#replaceasset) | **PUT** /assets/{id}/original | Replace the asset with new file, without changing its id
|
||||
*AssetsApi* | [**replaceAsset**](doc//AssetsApi.md#replaceasset) | **PUT** /assets/{id}/original | replaceAsset
|
||||
*AssetsApi* | [**runAssetJobs**](doc//AssetsApi.md#runassetjobs) | **POST** /assets/jobs |
|
||||
*AssetsApi* | [**updateAsset**](doc//AssetsApi.md#updateasset) | **PUT** /assets/{id} |
|
||||
*AssetsApi* | [**updateAssets**](doc//AssetsApi.md#updateassets) | **PUT** /assets |
|
||||
|
||||
16
mobile/openapi/lib/api/assets_api.dart
generated
16
mobile/openapi/lib/api/assets_api.dart
generated
@@ -16,6 +16,8 @@ class AssetsApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// checkBulkUpload
|
||||
///
|
||||
/// Checks if assets exist by checksums
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -48,6 +50,8 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// checkBulkUpload
|
||||
///
|
||||
/// Checks if assets exist by checksums
|
||||
///
|
||||
/// Parameters:
|
||||
@@ -68,6 +72,8 @@ class AssetsApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// checkExistingAssets
|
||||
///
|
||||
/// Checks if multiple assets exist on the server and returns all existing - used by background backup
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -100,6 +106,8 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// checkExistingAssets
|
||||
///
|
||||
/// Checks if multiple assets exist on the server and returns all existing - used by background backup
|
||||
///
|
||||
/// Parameters:
|
||||
@@ -215,6 +223,8 @@ class AssetsApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// getAllUserAssetsByDeviceId
|
||||
///
|
||||
/// Get all asset of a device that are in the database, ID only.
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -248,6 +258,8 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// getAllUserAssetsByDeviceId
|
||||
///
|
||||
/// Get all asset of a device that are in the database, ID only.
|
||||
///
|
||||
/// Parameters:
|
||||
@@ -564,6 +576,8 @@ class AssetsApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// replaceAsset
|
||||
///
|
||||
/// Replace the asset with new file, without changing its id
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -645,6 +659,8 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// replaceAsset
|
||||
///
|
||||
/// Replace the asset with new file, without changing its id
|
||||
///
|
||||
/// Parameters:
|
||||
|
||||
@@ -67,7 +67,7 @@ class AssetBulkUpdateDto {
|
||||
///
|
||||
num? longitude;
|
||||
|
||||
/// Minimum value: 0
|
||||
/// Minimum value: -1
|
||||
/// Maximum value: 5
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
|
||||
2
mobile/openapi/lib/model/update_asset_dto.dart
generated
2
mobile/openapi/lib/model/update_asset_dto.dart
generated
@@ -73,7 +73,7 @@ class UpdateAssetDto {
|
||||
///
|
||||
num? longitude;
|
||||
|
||||
/// Minimum value: 0
|
||||
/// Minimum value: -1
|
||||
/// Maximum value: 5
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
|
||||
@@ -2,7 +2,7 @@ name: immich_mobile
|
||||
description: Immich - selfhosted backup media file on mobile phone
|
||||
|
||||
publish_to: 'none'
|
||||
version: 1.125.1+177
|
||||
version: 1.125.7+182
|
||||
|
||||
environment:
|
||||
sdk: '>=3.3.0 <4.0.0'
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
@Skip('currently failing due to mock HTTP client to download ISAR binaries')
|
||||
@Tags(['pages'])
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -118,72 +122,4 @@ void main() {
|
||||
captured = verify(() => mockSearchApi.searchAssets(captureAny())).captured;
|
||||
expect(captured.first, emptyTextSearch);
|
||||
});
|
||||
|
||||
// COME BACK LATER
|
||||
// testWidgets('contextual search with text combined with media type',
|
||||
// (tester) async {
|
||||
// await tester.pumpConsumerWidget(
|
||||
// const SearchPage(),
|
||||
// overrides: overrides,
|
||||
// );
|
||||
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// expect(
|
||||
// find.byIcon(Icons.abc_rounded),
|
||||
// findsOneWidget,
|
||||
// reason: 'Should have contextual search icon',
|
||||
// );
|
||||
|
||||
// final searchField = find.byKey(const Key('search_text_field'));
|
||||
// expect(searchField, findsOneWidget);
|
||||
|
||||
// await tester.enterText(searchField, 'test');
|
||||
// await tester.testTextInput.receiveAction(TextInputAction.search);
|
||||
|
||||
// var captured = verify(
|
||||
// () => mockSearchApi.searchSmart(captureAny()),
|
||||
// ).captured;
|
||||
|
||||
// expect(
|
||||
// captured.first,
|
||||
// isA<SmartSearchDto>().having((s) => s.query, 'query', 'test'),
|
||||
// );
|
||||
|
||||
// await tester.dragUntilVisible(
|
||||
// find.byKey(const Key('media_type_chip')),
|
||||
// find.byKey(const Key('search_filter_chip_list')),
|
||||
// const Offset(-100, 0),
|
||||
// );
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// await tester.tap(find.byKey(const Key('media_type_chip')));
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// await tester.tap(find.byKey(const Key('search_filter_media_type_image')));
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// await tester.tap(find.byKey(const Key('search_filter_apply')));
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// captured = verify(() => mockSearchApi.searchSmart(captureAny())).captured;
|
||||
|
||||
// expect(
|
||||
// captured.first,
|
||||
// isA<SmartSearchDto>()
|
||||
// .having((s) => s.query, 'query', 'test')
|
||||
// .having((s) => s.type, 'type', AssetTypeEnum.IMAGE),
|
||||
// );
|
||||
|
||||
// await tester.enterText(searchField, '');
|
||||
// await tester.testTextInput.receiveAction(TextInputAction.search);
|
||||
|
||||
// captured = verify(() => mockSearchApi.searchAssets(captureAny())).captured;
|
||||
// expect(
|
||||
// captured.first,
|
||||
// isA<MetadataSearchDto>()
|
||||
// .having((s) => s.originalFileName, 'originalFileName', null)
|
||||
// .having((s) => s.type, 'type', AssetTypeEnum.IMAGE),
|
||||
// );
|
||||
// });
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
@@ -1424,6 +1424,7 @@
|
||||
},
|
||||
"/assets/bulk-upload-check": {
|
||||
"post": {
|
||||
"description": "Checks if assets exist by checksums",
|
||||
"operationId": "checkBulkUpload",
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
@@ -1459,7 +1460,7 @@
|
||||
"api_key": []
|
||||
}
|
||||
],
|
||||
"summary": "Checks if assets exist by checksums",
|
||||
"summary": "checkBulkUpload",
|
||||
"tags": [
|
||||
"Assets"
|
||||
]
|
||||
@@ -1467,6 +1468,7 @@
|
||||
},
|
||||
"/assets/device/{deviceId}": {
|
||||
"get": {
|
||||
"description": "Get all asset of a device that are in the database, ID only.",
|
||||
"operationId": "getAllUserAssetsByDeviceId",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -1504,7 +1506,7 @@
|
||||
"api_key": []
|
||||
}
|
||||
],
|
||||
"summary": "Get all asset of a device that are in the database, ID only.",
|
||||
"summary": "getAllUserAssetsByDeviceId",
|
||||
"tags": [
|
||||
"Assets"
|
||||
]
|
||||
@@ -1512,6 +1514,7 @@
|
||||
},
|
||||
"/assets/exist": {
|
||||
"post": {
|
||||
"description": "Checks if multiple assets exist on the server and returns all existing - used by background backup",
|
||||
"operationId": "checkExistingAssets",
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
@@ -1547,7 +1550,7 @@
|
||||
"api_key": []
|
||||
}
|
||||
],
|
||||
"summary": "Checks if multiple assets exist on the server and returns all existing - used by background backup",
|
||||
"summary": "checkExistingAssets",
|
||||
"tags": [
|
||||
"Assets"
|
||||
]
|
||||
@@ -1903,6 +1906,7 @@
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"description": "Replace the asset with new file, without changing its id",
|
||||
"operationId": "replaceAsset",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -1956,7 +1960,7 @@
|
||||
"api_key": []
|
||||
}
|
||||
],
|
||||
"summary": "Replace the asset with new file, without changing its id",
|
||||
"summary": "replaceAsset",
|
||||
"tags": [
|
||||
"Assets"
|
||||
],
|
||||
@@ -7454,7 +7458,7 @@
|
||||
"info": {
|
||||
"title": "Immich",
|
||||
"description": "Immich API",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"contact": {}
|
||||
},
|
||||
"tags": [],
|
||||
@@ -7951,7 +7955,7 @@
|
||||
},
|
||||
"rating": {
|
||||
"maximum": 5,
|
||||
"minimum": 0,
|
||||
"minimum": -1,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
@@ -12780,7 +12784,7 @@
|
||||
},
|
||||
"rating": {
|
||||
"maximum": 5,
|
||||
"minimum": 0,
|
||||
"minimum": -1,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
|
||||
4
open-api/typescript-sdk/package-lock.json
generated
4
open-api/typescript-sdk/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@immich/sdk",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@immich/sdk",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
"@oazapfts/runtime": "^1.0.2"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/sdk",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"description": "Auto-generated TypeScript SDK for the Immich API",
|
||||
"type": "module",
|
||||
"main": "./build/index.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Immich
|
||||
* 1.125.1
|
||||
* 1.125.7
|
||||
* DO NOT MODIFY - This file has been generated using oazapfts.
|
||||
* See https://www.npmjs.com/package/oazapfts
|
||||
*/
|
||||
@@ -1475,7 +1475,7 @@ export function restoreUserAdmin({ id }: {
|
||||
id: string;
|
||||
}, opts?: Oazapfts.RequestOpts) {
|
||||
return oazapfts.ok(oazapfts.fetchJson<{
|
||||
status: 201;
|
||||
status: 200;
|
||||
data: UserAdminResponseDto;
|
||||
}>(`/admin/users/${encodeURIComponent(id)}/restore`, {
|
||||
...opts,
|
||||
@@ -1703,7 +1703,7 @@ export function updateAssets({ assetBulkUpdateDto }: {
|
||||
})));
|
||||
}
|
||||
/**
|
||||
* Checks if assets exist by checksums
|
||||
* checkBulkUpload
|
||||
*/
|
||||
export function checkBulkUpload({ assetBulkUploadCheckDto }: {
|
||||
assetBulkUploadCheckDto: AssetBulkUploadCheckDto;
|
||||
@@ -1718,7 +1718,7 @@ export function checkBulkUpload({ assetBulkUploadCheckDto }: {
|
||||
})));
|
||||
}
|
||||
/**
|
||||
* Get all asset of a device that are in the database, ID only.
|
||||
* getAllUserAssetsByDeviceId
|
||||
*/
|
||||
export function getAllUserAssetsByDeviceId({ deviceId }: {
|
||||
deviceId: string;
|
||||
@@ -1731,7 +1731,7 @@ export function getAllUserAssetsByDeviceId({ deviceId }: {
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* Checks if multiple assets exist on the server and returns all existing - used by background backup
|
||||
* checkExistingAssets
|
||||
*/
|
||||
export function checkExistingAssets({ checkExistingAssetsDto }: {
|
||||
checkExistingAssetsDto: CheckExistingAssetsDto;
|
||||
@@ -1839,7 +1839,7 @@ export function downloadAsset({ id, key }: {
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* Replace the asset with new file, without changing its id
|
||||
* replaceAsset
|
||||
*/
|
||||
export function replaceAsset({ id, key, assetMediaReplaceDto }: {
|
||||
id: string;
|
||||
|
||||
@@ -40,12 +40,12 @@
|
||||
<a href="README_vi_VN.md">Tiếng Việt</a>
|
||||
</p>
|
||||
|
||||
## ข้อจำกัดความรับผิดชอบ
|
||||
## ข้อควรระวัง
|
||||
|
||||
- ⚠️ โพรเจกต์นี้กำลังอยู่ระหว่างการพัฒนา**ที่มีการเปลี่ยนแปลงบ่อยมาก**
|
||||
- ⚠️ คาดว่าจะมีข้อผิดพลาดและการเปลี่ยนแปลงที่ส่งผลเสีย
|
||||
- ⚠️ **ห้ามใช้แอปนี้เป็นวิธีการเดียวในการจัดเก็บภาพถ่ายและวิดีโอของคุณ**
|
||||
- ⚠️ ปฏิบัติตามแผนการสำรองข้อมูลแบบ [3-2-1](https://www.backblaze.com/blog/the-3-2-1-backup-strategy/) สำหรับภาพถ่ายและวิดีโอที่สำคัญของคุณอยู่เสมอ!
|
||||
- ⚠️ โพรเจกต์นี้กำลังอยู่ระหว่างการพัฒนา**มีการเปลี่ยนแปลงบ่อยมาก**
|
||||
- ⚠️ อาจจะเกิดข้อผิดพลาดและการเปลี่ยนแปลงที่ส่งผลเสีย
|
||||
- ⚠️ **ห้ามใช้ระบบนี้เป็นวิธีการเดียวในการจัดเก็บภาพถ่ายและวิดีโอของคุณ**
|
||||
- ⚠️ ปฏิบัติตามแผนการสำรองข้อมูลแบบ [3-2-1](https://www.backblaze.com/blog/the-3-2-1-backup-strategy/) สำหรับภาพถ่ายและวิดีโอที่สำคัญของคุณอยู่เสมอ
|
||||
|
||||
> [!NOTE]
|
||||
> คุณสามารถหาคู่มือหลัก รวมถึงคู่มือการติดตั้ง ได้ที่ https://immich.app/
|
||||
@@ -79,15 +79,15 @@
|
||||
| :----------------------------------------- | ------ | ------ |
|
||||
| อัปโหลดและดูวิดีโอและภาพถ่าย | ใช่ | ใช่ |
|
||||
| การสำรองข้อมูลอัตโนมัติเมื่อเปิดแอป | ใช่ | N/A |
|
||||
| ป้องกันการซ้ำซ้อนของไฟล์ | ใช่ | ใช่ |
|
||||
| ป้องกันการซ้ำของไฟล์ | ใช่ | ใช่ |
|
||||
| เลือกอัลบั้มสำหรับสำรองข้อมูล | ใช่ | N/A |
|
||||
| ดาวน์โหลดภาพถ่ายและวิดีโอไปยังอุปกรณ์ | ใช่ | ใช่ |
|
||||
| รองรับผู้ใช้หลายคน | ใช่ | ใช่ |
|
||||
| อัลบั้มและอัลบั้มแชร์ | ใช่ | ใช่ |
|
||||
| แถบเลื่อนแบบลากได้ | ใช่ | ใช่ |
|
||||
| รองรับรูปแบบไฟล์ RAW | ใช่ | ใช่ |
|
||||
| ดูข้อมูลเมตา (EXIF, แผนที่) | ใช่ | ใช่ |
|
||||
| ค้นหาจากข้อมูลเมตา วัตถุ ใบหน้า และ CLIP | ใช่ | ใช่ |
|
||||
| ดูข้อมูลเมตาดาต้า (EXIF, แผนที่) | ใช่ | ใช่ |
|
||||
| ค้นหาจากข้อมูลเมตาดาต้า วัตถุ ใบหน้า และ CLIP | ใช่ | ใช่ |
|
||||
| ฟังก์ชันการจัดการผู้ดูแลระบบ | ไม่ใช่ | ใช่ |
|
||||
| การสำรองข้อมูลพื้นหลัง | ใช่ | N/A |
|
||||
| การเลื่อนแบบเสมือน | ใช่ | ใช่ |
|
||||
@@ -100,7 +100,7 @@
|
||||
| การจัดเก็บและรายการโปรด | ใช่ | ใช่ |
|
||||
| แผนที่ทั่วโลก | ใช่ | ใช่ |
|
||||
| การแชร์กับคู่หู | ใช่ | ใช่ |
|
||||
| การจดจำใบหน้าและการจัดกลุ่ม | ใช่ | ใช่ |
|
||||
| ระบบจดจำใบหน้าและการจัดกลุ่ม | ใช่ | ใช่ |
|
||||
| ความทรงจำ (x ปีที่แล้ว) | ใช่ | ใช่ |
|
||||
| รองรับแบบออฟไลน์ | ใช่ | ไม่ใช่ |
|
||||
| แกลเลอรีแบบอ่านอย่างเดียว | ใช่ | ใช่ |
|
||||
@@ -108,13 +108,13 @@
|
||||
|
||||
## การแปลภาษา
|
||||
|
||||
อ่านเพิ่มเติมเกี่ยวกับการแปลภาษา [ที่นี่](https://immich.app/docs/developer/translations)
|
||||
อ่านเพิ่มเติมเกี่ยวกับการแปล [ที่นี่](https://immich.app/docs/developer/translations)
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/immich/">
|
||||
<img src="https://hosted.weblate.org/widget/immich/immich/multi-auto.svg" alt="สถานะการแปล" />
|
||||
</a>
|
||||
|
||||
## กิจกรรมของคลังเก็บข้อมูล
|
||||
## กิจกรรมของ Repository
|
||||
|
||||

|
||||
|
||||
|
||||
4
server/package-lock.json
generated
4
server/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "immich",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "immich",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
"@nestjs/bullmq": "^11.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich",
|
||||
"version": "1.125.1",
|
||||
"version": "1.125.7",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -3,9 +3,11 @@ import { Inject, Module, OnModuleDestroy, OnModuleInit, ValidationPipe } from '@
|
||||
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE, ModuleRef } from '@nestjs/core';
|
||||
import { ScheduleModule, SchedulerRegistry } from '@nestjs/schedule';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { PostgresJSDialect } from 'kysely-postgres-js';
|
||||
import { ClsModule } from 'nestjs-cls';
|
||||
import { KyselyModule } from 'nestjs-kysely';
|
||||
import { OpenTelemetryModule } from 'nestjs-otel';
|
||||
import postgres from 'postgres';
|
||||
import { commands } from 'src/commands';
|
||||
import { IWorker } from 'src/constants';
|
||||
import { controllers } from 'src/controllers';
|
||||
@@ -13,7 +15,6 @@ import { entities } from 'src/entities';
|
||||
import { ImmichWorker } from 'src/enum';
|
||||
import { IEventRepository } from 'src/interfaces/event.interface';
|
||||
import { IJobRepository } from 'src/interfaces/job.interface';
|
||||
import { ITelemetryRepository } from 'src/interfaces/telemetry.interface';
|
||||
import { AuthGuard } from 'src/middleware/auth.guard';
|
||||
import { ErrorInterceptor } from 'src/middleware/error.interceptor';
|
||||
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
|
||||
@@ -22,7 +23,7 @@ import { LoggingInterceptor } from 'src/middleware/logging.interceptor';
|
||||
import { providers, repositories } from 'src/repositories';
|
||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { teardownTelemetry } from 'src/repositories/telemetry.repository';
|
||||
import { teardownTelemetry, TelemetryRepository } from 'src/repositories/telemetry.repository';
|
||||
import { services } from 'src/services';
|
||||
import { CliService } from 'src/services/cli.service';
|
||||
import { DatabaseService } from 'src/services/database.service';
|
||||
@@ -58,7 +59,19 @@ const imports = [
|
||||
},
|
||||
}),
|
||||
TypeOrmModule.forFeature(entities),
|
||||
KyselyModule.forRoot(database.config.kysely),
|
||||
KyselyModule.forRoot({
|
||||
dialect: new PostgresJSDialect({ postgres: postgres(database.config.kysely) }),
|
||||
log(event) {
|
||||
if (event.level === 'error') {
|
||||
console.error('Query failed :', {
|
||||
durationMs: event.queryDurationMillis,
|
||||
error: event.error,
|
||||
sql: event.query.sql,
|
||||
params: event.query.parameters,
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
class BaseModule implements OnModuleInit, OnModuleDestroy {
|
||||
@@ -67,7 +80,7 @@ class BaseModule implements OnModuleInit, OnModuleDestroy {
|
||||
logger: LoggingRepository,
|
||||
@Inject(IEventRepository) private eventRepository: IEventRepository,
|
||||
@Inject(IJobRepository) private jobRepository: IJobRepository,
|
||||
@Inject(ITelemetryRepository) private telemetryRepository: ITelemetryRepository,
|
||||
private telemetryRepository: TelemetryRepository,
|
||||
) {
|
||||
logger.setAppName(this.worker);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import { Reflector } from '@nestjs/core';
|
||||
import { SchedulerRegistry } from '@nestjs/schedule';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { PostgresJSDialect } from 'kysely-postgres-js';
|
||||
import { KyselyModule } from 'nestjs-kysely';
|
||||
import { OpenTelemetryModule } from 'nestjs-otel';
|
||||
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import postgres from 'postgres';
|
||||
import { format } from 'sql-formatter';
|
||||
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
|
||||
import { entities } from 'src/entities';
|
||||
@@ -84,7 +86,7 @@ class SqlGenerator {
|
||||
const moduleFixture = await Test.createTestingModule({
|
||||
imports: [
|
||||
KyselyModule.forRoot({
|
||||
...database.config.kysely,
|
||||
dialect: new PostgresJSDialect({ postgres: postgres(database.config.kysely) }),
|
||||
log: (event) => {
|
||||
if (event.level === 'query') {
|
||||
this.sqlLogger.logQuery(event.query.sql);
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
UploadedFiles,
|
||||
UseInterceptors,
|
||||
} from '@nestjs/common';
|
||||
import { ApiBody, ApiConsumes, ApiHeader, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBody, ApiConsumes, ApiHeader, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { NextFunction, Response } from 'express';
|
||||
import { EndpointLifecycle } from 'src/decorators';
|
||||
import {
|
||||
@@ -94,6 +94,10 @@ export class AssetMediaController {
|
||||
@UseInterceptors(FileUploadInterceptor)
|
||||
@ApiConsumes('multipart/form-data')
|
||||
@EndpointLifecycle({ addedAt: 'v1.106.0' })
|
||||
@ApiOperation({
|
||||
summary: 'replaceAsset',
|
||||
description: 'Replace the asset with new file, without changing its id',
|
||||
})
|
||||
@Authenticated({ sharedLink: true })
|
||||
async replaceAsset(
|
||||
@Auth() auth: AuthDto,
|
||||
@@ -141,6 +145,10 @@ export class AssetMediaController {
|
||||
*/
|
||||
@Post('exist')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({
|
||||
summary: 'checkExistingAssets',
|
||||
description: 'Checks if multiple assets exist on the server and returns all existing - used by background backup',
|
||||
})
|
||||
@Authenticated()
|
||||
checkExistingAssets(
|
||||
@Auth() auth: AuthDto,
|
||||
@@ -154,6 +162,10 @@ export class AssetMediaController {
|
||||
*/
|
||||
@Post('bulk-upload-check')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({
|
||||
summary: 'checkBulkUpload',
|
||||
description: 'Checks if assets exist by checksums',
|
||||
})
|
||||
@Authenticated()
|
||||
checkBulkUpload(
|
||||
@Auth() auth: AuthDto,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { EndpointLifecycle } from 'src/decorators';
|
||||
import { AssetResponseDto, MemoryLaneResponseDto } from 'src/dtos/asset-response.dto';
|
||||
import {
|
||||
@@ -41,6 +41,10 @@ export class AssetController {
|
||||
* Get all asset of a device that are in the database, ID only.
|
||||
*/
|
||||
@Get('/device/:deviceId')
|
||||
@ApiOperation({
|
||||
summary: 'getAllUserAssetsByDeviceId',
|
||||
description: 'Get all asset of a device that are in the database, ID only.',
|
||||
})
|
||||
@Authenticated()
|
||||
getAllUserAssetsByDeviceId(@Auth() auth: AuthDto, @Param() { deviceId }: DeviceIdDto) {
|
||||
return this.service.getUserAssetsByDeviceId(auth, deviceId);
|
||||
|
||||
@@ -3,8 +3,8 @@ import { ApiTags } from '@nestjs/swagger';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { TemplateDto, TemplateResponseDto, TestEmailResponseDto } from 'src/dtos/notification.dto';
|
||||
import { SystemConfigSmtpDto } from 'src/dtos/system-config.dto';
|
||||
import { EmailTemplate } from 'src/interfaces/notification.interface';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { EmailTemplate } from 'src/repositories/notification.repository';
|
||||
import { NotificationService } from 'src/services/notification.service';
|
||||
|
||||
@ApiTags('Notifications')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { UserPreferencesResponseDto, UserPreferencesUpdateDto } from 'src/dtos/user-preferences.dto';
|
||||
@@ -75,6 +75,7 @@ export class UserAdminController {
|
||||
|
||||
@Post(':id/restore')
|
||||
@Authenticated({ permission: Permission.ADMIN_USER_DELETE, admin: true })
|
||||
@HttpCode(HttpStatus.OK)
|
||||
restoreUserAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserAdminResponseDto> {
|
||||
return this.service.restore(auth, id);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import { albumStub } from 'test/fixtures/album.stub';
|
||||
describe('mapAlbum', () => {
|
||||
it('should set start and end dates', () => {
|
||||
const dto = mapAlbum(albumStub.twoAssets, false);
|
||||
expect(dto.startDate).toEqual(new Date('2023-02-22T05:06:29.716Z'));
|
||||
expect(dto.endDate).toEqual(new Date('2023-02-23T05:06:29.716Z'));
|
||||
expect(dto.startDate).toEqual(new Date('2020-12-31T23:59:00.000Z'));
|
||||
expect(dto.endDate).toEqual(new Date('2025-01-01T01:02:03.456Z'));
|
||||
});
|
||||
|
||||
it('should not set start and end dates for empty assets', () => {
|
||||
|
||||
@@ -7,7 +7,6 @@ import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { UserResponseDto, mapUser } from 'src/dtos/user.dto';
|
||||
import { AlbumEntity } from 'src/entities/album.entity';
|
||||
import { AlbumUserRole, AssetOrder } from 'src/enum';
|
||||
import { getAssetDateTime } from 'src/utils/date-time';
|
||||
import { Optional, ValidateBoolean, ValidateUUID } from 'src/validation';
|
||||
|
||||
export class AlbumInfoDto {
|
||||
@@ -165,8 +164,8 @@ export const mapAlbum = (entity: AlbumEntity, withAssets: boolean, auth?: AuthDt
|
||||
const hasSharedLink = entity.sharedLinks?.length > 0;
|
||||
const hasSharedUser = sharedUsers.length > 0;
|
||||
|
||||
let startDate = getAssetDateTime(assets.at(0));
|
||||
let endDate = getAssetDateTime(assets.at(-1));
|
||||
let startDate = assets.at(0)?.localDateTime;
|
||||
let endDate = assets.at(-1)?.localDateTime;
|
||||
// Swap dates if start date is greater than end date.
|
||||
if (startDate && endDate && startDate > endDate) {
|
||||
[startDate, endDate] = [endDate, startDate];
|
||||
|
||||
@@ -52,7 +52,7 @@ export class UpdateAssetBase {
|
||||
@Optional()
|
||||
@IsInt()
|
||||
@Max(5)
|
||||
@Min(0)
|
||||
@Min(-1)
|
||||
rating?: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Img, Link, Section, Text } from '@react-email/components';
|
||||
import * as React from 'react';
|
||||
import { ImmichButton } from 'src/emails/components/button.component';
|
||||
import ImmichLayout from 'src/emails/components/immich.layout';
|
||||
import { AlbumInviteEmailProps } from 'src/interfaces/notification.interface';
|
||||
import { AlbumInviteEmailProps } from 'src/repositories/notification.repository';
|
||||
import { replaceTemplateTags } from 'src/utils/replace-template-tags';
|
||||
|
||||
export const AlbumInviteEmail = ({
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Img, Link, Section, Text } from '@react-email/components';
|
||||
import * as React from 'react';
|
||||
import { ImmichButton } from 'src/emails/components/button.component';
|
||||
import ImmichLayout from 'src/emails/components/immich.layout';
|
||||
import { AlbumUpdateEmailProps } from 'src/interfaces/notification.interface';
|
||||
import { AlbumUpdateEmailProps } from 'src/repositories/notification.repository';
|
||||
import { replaceTemplateTags } from 'src/utils/replace-template-tags';
|
||||
|
||||
export const AlbumUpdateEmail = ({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user