Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
318fba6c97 | ||
|
|
2d63fa80b4 | ||
|
|
1dc211a046 | ||
|
|
f71f379529 | ||
|
|
bee95b4977 | ||
|
|
9f8aaa57b6 | ||
|
|
2c1aab154a | ||
|
|
37cfac27b8 | ||
|
|
11b2e2a6e2 | ||
|
|
d555ee737b | ||
|
|
12a6a7d95a | ||
|
|
caac3bfc95 | ||
|
|
05630776a0 | ||
|
|
72c947cbaf | ||
|
|
53fb3a36f7 | ||
|
|
6b3892987a | ||
|
|
390919c439 | ||
|
|
09ab06ae6c | ||
|
|
ad9373312b | ||
|
|
bd71e087d4 | ||
|
|
c90dcde7cc | ||
|
|
d91cc3616b | ||
|
|
74cd3d66c6 | ||
|
|
e6f9d9a31a | ||
|
|
b71a86142b | ||
|
|
6e4ba6184b | ||
|
|
b37162099e | ||
|
|
dab74662e9 | ||
|
|
3d103046bc | ||
|
|
3ca62d9c55 | ||
|
|
2cd45ed1de | ||
|
|
263598f2cf | ||
|
|
1d1d71c779 | ||
|
|
fd13265131 | ||
|
|
911c35a7f1 | ||
|
|
adb265794c | ||
|
|
8c20d8cb3d | ||
|
|
43359f1d26 | ||
|
|
dc9da7480c | ||
|
|
18647203cc | ||
|
|
be8f2c01a2 | ||
|
|
c8fffe4ade | ||
|
|
43fd7737f1 | ||
|
|
fb4969d5d1 | ||
|
|
3cc4af5947 | ||
|
|
ac39ebddc0 | ||
|
|
29bb1f7ef2 | ||
|
|
b8d2f5b373 | ||
|
|
2139853dd9 | ||
|
|
527aa61a87 | ||
|
|
4261fc8a04 | ||
|
|
7dbddba757 | ||
|
|
16183791f3 | ||
|
|
f38c7a4b7e | ||
|
|
bb0b2a1f53 | ||
|
|
0048662182 | ||
|
|
7bd2455175 | ||
|
|
43e49f36b7 | ||
|
|
e4b3479779 | ||
|
|
6bac9c7e8f | ||
|
|
ff3cde4dfb | ||
|
|
7aab84f2d9 | ||
|
|
3a940711eb | ||
|
|
2b0b2bb1ae | ||
|
|
e39507552f | ||
|
|
b019ab79f9 | ||
|
|
43da8c2a72 | ||
|
|
0b65cea6fd | ||
|
|
a1806390b0 | ||
|
|
5d6559e839 | ||
|
|
29c79ad1d8 |
24
.github/DISCUSSION_TEMPLATE/feature-request.yaml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
title: "[Feature] <feature-name-goes-here>"
|
||||
labels: ["feature"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please use this form to request new feature for Immich
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
label: The feature
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Platform
|
||||
options:
|
||||
- label: Server
|
||||
- label: Web
|
||||
- label: Mobile
|
||||
46
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,46 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: '[BUG] <title>'
|
||||
labels: bug, need triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Note: Please search to see if an issue already exists for the bug you encountered.
|
||||
-->
|
||||
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Task List**
|
||||
|
||||
*Please complete the task list below. We need this information to help us reproduce the bug or point out problems in your setup. You are not providing enough info may delay our effort to help you.*
|
||||
|
||||
- [ ] I have read thoroughly the README setup and installation instructions.
|
||||
- [ ] I have included my `docker-compose` file.
|
||||
- [ ] I have included my redacted `.env` file.
|
||||
- [ ] I have included information on my machine, and environment.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**System**
|
||||
- Phone OS [iOS, Android]: `<version>`
|
||||
- Server Version: `<version>`
|
||||
- Mobile App Version: `<version>`
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
100
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: Report an issue with Immich
|
||||
description: Report an issue with Immich
|
||||
labels: ["bug", "need triage"]
|
||||
title: "[BUG] <title>"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
This issue form is for reporting bugs only!
|
||||
|
||||
If you have a feature or enhancement request, please use the [feature request][fr] section of our [GitHub Discussions][fr].
|
||||
|
||||
[fr]: https://github.com/immich-app/immich/discussions/new?category=feature-request
|
||||
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: The bug
|
||||
description: >-
|
||||
Describe the issue you are experiencing here, to communicate to the
|
||||
maintainers. Tell us what you were trying to do and what happened.
|
||||
|
||||
Provide a clear and concise description of what the problem is.
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Environment
|
||||
|
||||
- type: input
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: The OS that Immich Server is running on
|
||||
placeholder: Ubuntu 22.10, Debian, Arch...etc
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Version of Immich Server
|
||||
placeholder: v1.0.0
|
||||
|
||||
- type: input
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Version of Immich Mobile App
|
||||
placeholder: v1.0.0
|
||||
|
||||
- type: checkboxes
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Platform with the issue
|
||||
options:
|
||||
- label: Server
|
||||
- label: Web
|
||||
- label: Mobile
|
||||
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Your docker-compose.yml content
|
||||
render: YAML
|
||||
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Your .env content
|
||||
description: Please provide the redacted .env content of your setup
|
||||
render: Shell
|
||||
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction steps
|
||||
description: "How do you trigger this bug? Please walk us through it step by step."
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
...
|
||||
render: bash
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: >
|
||||
If you have any additional information for us, use the field below.
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Thank you for submitting the form
|
||||
10
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1 +1,11 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: I have a question or need support
|
||||
url: https://discord.gg/D8JsnBEuKb
|
||||
about: We use GitHub for tracking bugs, please check out our Discord channel for freaky fast support.
|
||||
- name: Feature Request
|
||||
url: https://github.com/immich-app/immich/discussions/new?category=feature-request
|
||||
about: Please use our GitHub Discussion for making feature requests.
|
||||
- name: I'm unsure where to go
|
||||
url: https://discord.gg/D8JsnBEuKb
|
||||
about: If you are unsure where to go, then joining our Discord is recommended; Just ask!
|
||||
|
||||
32
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@@ -1,32 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Request a feature that you would like for the app
|
||||
title: "[Feature]: "
|
||||
labels: ["feature", "need triage"]
|
||||
assignees:
|
||||
- ""
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this feature request!
|
||||
|
||||
- type: textarea
|
||||
id: feature-detail
|
||||
attributes:
|
||||
label: Feature detail
|
||||
placeholder: Describe the feature you would like to see for the app
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: Platform
|
||||
description: Choose the platform for the feature
|
||||
options:
|
||||
- Web
|
||||
- Mobile App
|
||||
- Server
|
||||
validations:
|
||||
required: true
|
||||
16
.github/workflows/build-mobile.yml
vendored
@@ -3,6 +3,10 @@ name: Build Mobile
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
inputs:
|
||||
ref:
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
push:
|
||||
branches: [main]
|
||||
@@ -13,7 +17,17 @@ jobs:
|
||||
runs-on: macos-12
|
||||
|
||||
steps:
|
||||
- name: Determine ref
|
||||
id: get-ref
|
||||
run: |
|
||||
input_ref="${{ inputs.ref }}"
|
||||
github_ref="${{ github.sha }}"
|
||||
ref="${input_ref:-$github_ref}"
|
||||
echo "ref=$ref" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ steps.get-ref.outputs.ref }}
|
||||
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
@@ -25,7 +39,7 @@ jobs:
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: "3.3.10"
|
||||
flutter-version: "3.7.3"
|
||||
cache: true
|
||||
|
||||
- name: Create the Keystore
|
||||
|
||||
3
.github/workflows/docker.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
uses: docker/setup-qemu-action@v2.1.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2.4.0
|
||||
uses: docker/setup-buildx-action@v2.4.1
|
||||
# Workaround to fix error:
|
||||
# failed to push: failed to copy: io: read/write on closed pipe
|
||||
# See https://github.com/docker/build-push-action/issues/761
|
||||
@@ -98,3 +98,4 @@ jobs:
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/immich-build-cache:${{matrix.image}}
|
||||
cache-to: ${{ steps.cache-target.outputs.cache-to }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
|
||||
30
.github/workflows/prepare-release.yml
vendored
@@ -18,14 +18,12 @@ on:
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
build_mobile:
|
||||
uses: ./.github/workflows/build-mobile.yml
|
||||
secrets: inherit
|
||||
|
||||
tag_release:
|
||||
bump_version:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build_mobile
|
||||
|
||||
|
||||
outputs:
|
||||
ref: ${{ steps.push-tag.outputs.commit_long_sha }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -36,6 +34,7 @@ jobs:
|
||||
run: misc/release/pump-version.sh -s "${{ inputs.serverBump }}" -m "${{ inputs.mobileBump }}"
|
||||
|
||||
- name: Commit and tag
|
||||
id: push-tag
|
||||
uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
author_name: Immich Release Bot
|
||||
@@ -43,7 +42,24 @@ jobs:
|
||||
message: "Version ${{ env.IMMICH_VERSION }}"
|
||||
tag: ${{ env.IMMICH_VERSION }}
|
||||
push: true
|
||||
|
||||
build_mobile:
|
||||
uses: ./.github/workflows/build-mobile.yml
|
||||
needs: bump_version
|
||||
secrets: inherit
|
||||
with:
|
||||
ref: ${{ needs.bump_version.outputs.ref }}
|
||||
|
||||
prepare_release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build_mobile
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.ORG_RELEASE_TOKEN }}
|
||||
|
||||
- name: Download APK
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
|
||||
2
.github/workflows/static_analysis.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.3.10'
|
||||
flutter-version: '3.7.3'
|
||||
|
||||
- name: Install dependencies
|
||||
run: dart pub get
|
||||
|
||||
4
.github/workflows/test.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.3.10'
|
||||
flutter-version: '3.7.3'
|
||||
- name: Run tests
|
||||
working-directory: ./mobile
|
||||
run: flutter test
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.3.10'
|
||||
flutter-version: '3.7.3'
|
||||
- name: Run integration tests
|
||||
uses: reactivecircus/android-emulator-runner@v2.27.0
|
||||
with:
|
||||
|
||||
@@ -34,3 +34,11 @@ download:
|
||||
locale_code: pt-BR
|
||||
- file: mobile/assets/i18n/pl-PL.json
|
||||
locale_code: pl-PL
|
||||
- file: mobile/assets/i18n/sk-SK.json
|
||||
locale_code: sk-SK
|
||||
- file: mobile/assets/i18n/zh-CN.json
|
||||
locale_code: zh-CN
|
||||
- file: mobile/assets/i18n/ru-RU.json
|
||||
locale_code: ru-RU
|
||||
- file: mobile/assets/i18n/cs-CZ.json
|
||||
locale_code: cs-CZ
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
FROM node:16-bullseye-slim as builder
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
@@ -6,7 +5,7 @@ ARG DEBIAN_FRONTEND=noninteractive
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install gcc g++ make cmake python3 python3-pip ffmpeg -y
|
||||
RUN apt-get install gcc g++ make cmake python3 python3-pip -y
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
@@ -15,24 +14,17 @@ RUN npm rebuild @tensorflow/tfjs-node --build-from-source
|
||||
|
||||
COPY . .
|
||||
|
||||
|
||||
FROM builder as prod
|
||||
|
||||
RUN npm run build
|
||||
|
||||
RUN npm prune --omit=dev
|
||||
|
||||
|
||||
FROM node:16-bullseye-slim
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y ffmpeg \
|
||||
&& rm -rf /var/cache/apt/lists
|
||||
|
||||
COPY --from=prod /usr/src/app/node_modules ./node_modules
|
||||
COPY --from=prod /usr/src/app/dist ./dist
|
||||
|
||||
|
||||
565
machine-learning/package-lock.json
generated
@@ -23,19 +23,9 @@
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^8.0.0",
|
||||
"@nestjs/core": "^8.0.0",
|
||||
"@nestjs/mapped-types": "^1.0.1",
|
||||
"@nestjs/platform-express": "^8.0.0",
|
||||
"@tensorflow-models/coco-ssd": "^2.2.2",
|
||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||
"@tensorflow/tfjs": "^3.19.0",
|
||||
"@tensorflow/tfjs-converter": "^3.19.0",
|
||||
"@tensorflow/tfjs-core": "^3.19.0",
|
||||
"@tensorflow/tfjs-node": "^3.19.0",
|
||||
"@tensorflow/tfjs-node-gpu": "^3.19.0",
|
||||
"@trpc/server": "^9.20.3",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.2.0"
|
||||
"@tensorflow/tfjs-node": "^3.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^8.2.4",
|
||||
@@ -52,6 +42,7 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"jest": "^27.2.5",
|
||||
"prettier": "^2.3.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"source-map-support": "^0.5.20",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-jest": "^27.0.3",
|
||||
|
||||
@@ -65,6 +65,7 @@ if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
|
||||
|
||||
sed -i "s/^ \"version\": \"$CURRENT_SERVER\",$/ \"version\": \"$NEXT_SERVER\",/" server/package.json
|
||||
sed -i "s/^ \"version\": \"$CURRENT_SERVER\",$/ \"version\": \"$NEXT_SERVER\",/" server/package-lock.json
|
||||
sed -i "s/\"version\": \"$CURRENT_SERVER\",$/\"version\": \"$NEXT_SERVER\",/" server/immich-openapi-specs.json
|
||||
sed -i "s/\"android\.injected\.version\.name\" => \"$CURRENT_SERVER\",/\"android\.injected\.version\.name\" => \"$NEXT_SERVER\",/" mobile/android/fastlane/Fastfile
|
||||
sed -i "s/version_number: \"$CURRENT_SERVER\"$/version_number: \"$NEXT_SERVER\"/" mobile/ios/fastlane/Fastfile
|
||||
fi
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<application android:label="Immich" android:name=".ImmichApp" android:usesCleartextTraffic="true"
|
||||
android:icon="@mipmap/ic_launcher" android:requestLegacyExternalStorage="true">
|
||||
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.EnableImpeller"
|
||||
android:value="false" />
|
||||
|
||||
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
|
||||
|
After Width: | Height: | Size: 12 KiB |
BIN
mobile/android/app/src/main/res/drawable-hdpi/splash.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
BIN
mobile/android/app/src/main/res/drawable-mdpi/splash.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 70 B |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||
</item>
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 39 KiB |
BIN
mobile/android/app/src/main/res/drawable-night/background.png
Normal file
|
After Width: | Height: | Size: 70 B |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||
</item>
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
BIN
mobile/android/app/src/main/res/drawable-v21/background.png
Normal file
|
After Width: | Height: | Size: 70 B |
@@ -1,12 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
<item>
|
||||
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||
</item>
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
||||
|
After Width: | Height: | Size: 14 KiB |
BIN
mobile/android/app/src/main/res/drawable-xhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 34 KiB |
BIN
mobile/android/app/src/main/res/drawable-xxhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 39 KiB |
BIN
mobile/android/app/src/main/res/drawable-xxxhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
mobile/android/app/src/main/res/drawable/background.png
Normal file
|
After Width: | Height: | Size: 70 B |
@@ -1,12 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
<item>
|
||||
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||
</item>
|
||||
<item>
|
||||
<bitmap android:gravity="center" android:src="@drawable/splash"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
||||
20
mobile/android/app/src/main/res/values-night-v31/styles.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
<item name="android:windowSplashScreenBackground">#000000</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -5,6 +5,9 @@
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
|
||||
20
mobile/android/app/src/main/res/values-v31/styles.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
<item name="android:windowSplashScreenBackground">#f6f8fe</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -5,6 +5,9 @@
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
|
||||
@@ -35,8 +35,8 @@ platform :android do
|
||||
task: 'bundle',
|
||||
build_type: 'Release',
|
||||
properties: {
|
||||
"android.injected.version.code" => 67,
|
||||
"android.injected.version.name" => "1.44.0",
|
||||
"android.injected.version.code" => 70,
|
||||
"android.injected.version.name" => "1.47.1",
|
||||
}
|
||||
)
|
||||
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
* reused HTTP client for uploading assets
|
||||
* top padding missing from drag handle in add to album bottom sheet
|
||||
* Improve the gallery to improve scale, double tap, and swipe gesture detection
|
||||
* Uses clamping scroll physics on android
|
||||
* Fix back button closing the app from multi selection in Android
|
||||
* add and delete operation asset in album viewer doesn't update count in album list
|
||||
* Update share_file to latest version and migrate to using cross platform shareXFile
|
||||
@@ -0,0 +1,4 @@
|
||||
fixes back button while multiselecting showing the last selected image
|
||||
fixes dark mode color for invite to album app bar
|
||||
fixed local asset thumbnail size and eliminated fade in
|
||||
Fullscreen image effects
|
||||
@@ -0,0 +1,6 @@
|
||||
* Library page rework (album sorting, favorites).
|
||||
* Tap to enter immersive mode on the gallery viewer.
|
||||
* Removed stay logged in the checkbox and made it enabled by default.
|
||||
* Multiselect add to favorites from the timeline.
|
||||
* Responsive layout improvements with a navigation rail and album grid.
|
||||
* Home screen customization options.
|
||||
@@ -5,17 +5,17 @@
|
||||
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000213">
|
||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000281">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="61.218233">
|
||||
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="142.850758">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="41.974053">
|
||||
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="39.589103">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"album_thumbnail_card_item": "1 položka",
|
||||
"album_thumbnail_card_items": "{} položky",
|
||||
"album_thumbnail_card_shared": "Sdíleno",
|
||||
"album_viewer_appbar_share_delete": "odstranit album",
|
||||
"album_viewer_appbar_share_delete": "Odstranit album",
|
||||
"album_viewer_appbar_share_err_delete": "Nepodařilo se odstranit album",
|
||||
"album_viewer_appbar_share_err_leave": "Nepodařilo se ukončit album",
|
||||
"album_viewer_appbar_share_err_remove": "Při odstraňování souborů z alba se vyskytly problémy.",
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Opustit album",
|
||||
"album_viewer_appbar_share_remove": "Odstranit z alba",
|
||||
"album_viewer_page_share_add_users": "Přidat uživatele",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Nastavení rozložení mřížky fotografií",
|
||||
"asset_list_settings_title": "Fotografická mřížka",
|
||||
"backup_album_selection_page_albums_device": "Alba v zařízení ({})",
|
||||
@@ -42,9 +46,9 @@
|
||||
"backup_controller_page_background_turn_off": "Zakázat službu na pozadí",
|
||||
"backup_controller_page_background_turn_on": "Povolit službu na pozadí",
|
||||
"backup_controller_page_background_wifi": "Jen na WiFi",
|
||||
"backup_controller_page_backup": "Zálohování",
|
||||
"backup_controller_page_backup": "Zálohováno",
|
||||
"backup_controller_page_backup_selected": "Vybrané: ",
|
||||
"backup_controller_page_backup_sub": "Zálohování fotografií a videí",
|
||||
"backup_controller_page_backup_sub": "Zálohované fotografie a videa",
|
||||
"backup_controller_page_cancel": "Zrušit",
|
||||
"backup_controller_page_created": "Vytvořeno: {}",
|
||||
"backup_controller_page_desc_backup": "Zapněte zálohování na popředí, aby se nové položky automaticky nahrávaly na server při otevření aplikace.",
|
||||
@@ -54,7 +58,7 @@
|
||||
"backup_controller_page_id": "ID: {}",
|
||||
"backup_controller_page_info": "Informace o zálohování",
|
||||
"backup_controller_page_none_selected": "Žádné vybrané",
|
||||
"backup_controller_page_remainder": "Zbytek",
|
||||
"backup_controller_page_remainder": "Zůstává",
|
||||
"backup_controller_page_remainder_sub": "Zbývající fotografie a alba, která se mají zálohovat z výběru",
|
||||
"backup_controller_page_select": "Vybrat",
|
||||
"backup_controller_page_server_storage": "Serverové úložiště",
|
||||
@@ -67,9 +71,9 @@
|
||||
"backup_controller_page_total_sub": "Všechny jedinečné fotografie a videa z vybraných alb",
|
||||
"backup_controller_page_turn_off": "Zakázat zálohování na popředí",
|
||||
"backup_controller_page_turn_on": "Povolit zálohování na popředí",
|
||||
"backup_controller_page_uploading_file_info": "Nahrávání informací o souborech",
|
||||
"backup_err_only_album": "Nelze odstranit pouze album",
|
||||
"backup_info_card_assets": "položky",
|
||||
"backup_controller_page_uploading_file_info": "Informace o nahrávaném souboru",
|
||||
"backup_err_only_album": "Nelze odstranit jediné vybrané album",
|
||||
"backup_info_card_assets": "položek",
|
||||
"cache_settings_album_thumbnails": "Náhledy stránek knihovny (položek {})",
|
||||
"cache_settings_clear_cache_button": "Vymazat vyrovnávací paměť",
|
||||
"cache_settings_clear_cache_button_title": "Vymaže vyrovnávací paměť aplikace. To výrazně ovlivní výkon aplikace, dokud se vyrovnávací paměť neobnoví.",
|
||||
@@ -94,9 +98,9 @@
|
||||
"create_shared_album_page_share": "Sdílet",
|
||||
"create_shared_album_page_share_add_assets": "PŘIDAT",
|
||||
"create_shared_album_page_share_select_photos": "Vybrat fotografie",
|
||||
"daily_title_text_date": "EEEE, d MMMM",
|
||||
"daily_title_text_date_year": "EEEE, d MMMM y",
|
||||
"date_format": "EEEE, d MMMM y • H:mm",
|
||||
"daily_title_text_date": "EEEE, d. MMMM",
|
||||
"daily_title_text_date_year": "EEEE, d. MMMM y",
|
||||
"date_format": "EEEE, d. MMMM y • H:mm",
|
||||
"delete_dialog_alert": "Tyto položky budou trvale odstraněny z Immich a z vašeho zařízení.",
|
||||
"delete_dialog_cancel": "Zrušit",
|
||||
"delete_dialog_ok": "Vymazat",
|
||||
@@ -108,16 +112,24 @@
|
||||
"experimental_settings_new_asset_list_title": "Povolení experimentální mřížky fotografií",
|
||||
"experimental_settings_subtitle": "Používejte na vlastní riziko!",
|
||||
"experimental_settings_title": "Experimentální",
|
||||
"favorites_page_title": "Oblíbené",
|
||||
"home_page_add_to_album_conflicts": "Přidány {added} položky do alba {album}. {failed} položky jsou již v albu.",
|
||||
"home_page_add_to_album_success": "Přidány položky {added} do alba {album}.",
|
||||
"home_page_building_timeline": "Vytváraní časové osy",
|
||||
"home_page_first_time_notice": "Pokud aplikaci používáte poprvé, nezapomeňte si vybrat zálohovaná alba, aby se na časové ose mohly nacházet fotografie a videa z vybraných albech.",
|
||||
"library_page_albums": "Alba",
|
||||
"library_page_favorites": "Oblíbené",
|
||||
"library_page_new_album": "Nové album",
|
||||
"login_form_button_text": "Přihlášení",
|
||||
"library_page_sharing": "Sdílení",
|
||||
"library_page_sort_created": "Naposledy vytvořené",
|
||||
"library_page_sort_title": "Podle názvu alba",
|
||||
"login_form_button_text": "Přihlásit se",
|
||||
"login_form_email_hint": "tvůjmail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-tvého-serveru:port/api",
|
||||
"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",
|
||||
"login_form_err_invalid_url": "Neplatná URL",
|
||||
"login_form_err_leading_whitespace": "Úvodní mezera",
|
||||
"login_form_err_trailing_whitespace": "Koncová mezera",
|
||||
"login_form_failed_get_oauth_server_config": "Chyba přihlášení pomocí OAuth, zkontrolujte adresu URL serveru",
|
||||
@@ -158,7 +170,7 @@
|
||||
"setting_notifications_title": "Oznámení",
|
||||
"setting_notifications_total_progress_subtitle": "Celkový průběh nahrávání (hotové/celkové položky)",
|
||||
"setting_notifications_total_progress_title": "Zobrazit celkový průběh zálohování na pozadí",
|
||||
"setting_pages_app_bar_settings": "nastavení",
|
||||
"setting_pages_app_bar_settings": "Nastavení",
|
||||
"settings_require_restart": "Pro použití tohoto nastavení restartujte Immich",
|
||||
"share_add": "Přidat",
|
||||
"share_add_photos": "Přidat fotografie",
|
||||
@@ -168,15 +180,15 @@
|
||||
"share_invite": "Pozvat do alba",
|
||||
"sharing_page_album": "Shared albums",
|
||||
"sharing_page_description": "Vytvářejte sdílená alba a sdílejte fotografie a videa s lidmi ve vaší síti.",
|
||||
"sharing_page_empty_list": "Prázný dopis",
|
||||
"sharing_page_empty_list": "Prázdný dopis",
|
||||
"sharing_silver_appbar_create_shared_album": "Vytvořit sdílené album",
|
||||
"sharing_silver_appbar_share_partner": "Sdílet s partnerem",
|
||||
"tab_controller_nav_library": "Knihovna",
|
||||
"tab_controller_nav_photos": "Fotografie",
|
||||
"tab_controller_nav_search": "Vyhledávání",
|
||||
"tab_controller_nav_sharing": "Sdílení",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Zobrazit indikátor úložiště na dlaždicích zdrojů",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Počet aktiv na řádek ({})",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Zobrazit indikátor úložiště na dlaždicích položek",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Počet položek na řádek ({})",
|
||||
"theme_setting_dark_mode_switch": "Tmavé téma",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Přizpůsobení kvality prohlížeče detailů",
|
||||
"theme_setting_image_viewer_quality_title": "Kvalita prohlížeče obrázků",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Forlad album",
|
||||
"album_viewer_appbar_share_remove": "Fjern fra album",
|
||||
"album_viewer_page_share_add_users": "Tilføj brugere",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Indstillinger for billedgitterlayout",
|
||||
"asset_list_settings_title": "Billedgitter",
|
||||
"backup_album_selection_page_albums_device": "Albummer på enhed ({})",
|
||||
@@ -108,23 +112,30 @@
|
||||
"experimental_settings_new_asset_list_title": "Aktiver eksperimentelt fotogitter",
|
||||
"experimental_settings_subtitle": "Brug på eget ansvar!",
|
||||
"experimental_settings_title": "Eksperimentelle",
|
||||
"favorites_page_title": "Favoritter",
|
||||
"home_page_add_to_album_conflicts": "Tilføjede {added} billeder og videoer til album {album}. {failed} billeder og videoer er allerede i albummet.",
|
||||
"home_page_add_to_album_success": "Tilføjede {added} billeder og videoer til album {album}.",
|
||||
"home_page_building_timeline": "Bygger tidslinjen",
|
||||
"home_page_first_time_notice": "Hvis dette er din første gang i appen, bedes du vælge en backup af albummer så tidlinjen kan blive fyldt med billeder og videoer fra albummerne.",
|
||||
"library_page_albums": "Albummer",
|
||||
"library_page_favorites": "Favoritter",
|
||||
"library_page_new_album": "Nyt album",
|
||||
"library_page_sharing": "Delte",
|
||||
"library_page_sort_created": "Senest oprettet",
|
||||
"library_page_sort_title": "Albumtitel",
|
||||
"login_form_button_text": "Log ind",
|
||||
"login_form_email_hint": "din-email@email.com",
|
||||
"login_form_email_hint": "din-e-mail@e-mail.com",
|
||||
"login_form_endpoint_hint": "http://din-server-ip:port/api",
|
||||
"login_form_endpoint_url": "Server Endpoint URL",
|
||||
"login_form_err_http": "Angiv venligst http:// eller https://",
|
||||
"login_form_err_invalid_email": "Ugyldig email",
|
||||
"login_form_err_invalid_url": "Invalid URL",
|
||||
"login_form_err_invalid_email": "Ugyldig e-mail",
|
||||
"login_form_err_invalid_url": "Ugyldig webadresse",
|
||||
"login_form_err_leading_whitespace": "Mellemrum før",
|
||||
"login_form_err_trailing_whitespace": "Mellemrum efter",
|
||||
"login_form_failed_get_oauth_server_config": "Fejl med at logge på med OAuth. Tjek serveres URL",
|
||||
"login_form_failed_get_oauth_server_config": "Fejl med at logge på med OAuth. Tjek serveres webadresse",
|
||||
"login_form_failed_get_oauth_server_disable": "OAuth er ikke tilgængelig på denne server",
|
||||
"login_form_failed_login": "Der opstod en vejl ved at logge ind. Tjek server URL, email og kodeordet",
|
||||
"login_form_label_email": "Email",
|
||||
"login_form_failed_login": "Der opstod en vejl ved at logge ind. Tjek server webadressen, e-mailen og kodeordet",
|
||||
"login_form_label_email": "E-mail",
|
||||
"login_form_label_password": "Kodeord",
|
||||
"login_form_password_hint": "kodeord",
|
||||
"login_form_save_login": "Forbliv logget ind",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Album verlassen",
|
||||
"album_viewer_appbar_share_remove": "Entferne vom Album",
|
||||
"album_viewer_page_share_add_users": "Nutzer hinzufügen",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Photo grid layout settings",
|
||||
"asset_list_settings_title": "Photo Grid",
|
||||
"backup_album_selection_page_albums_device": "Alben auf dem Gerät ({})",
|
||||
@@ -108,10 +112,17 @@
|
||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"experimental_settings_subtitle": "Use at your own risk!",
|
||||
"experimental_settings_title": "Experimentell",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "Alben",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "Neues Album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"login_form_button_text": "Anmelden",
|
||||
"login_form_email_hint": "deine@email.de",
|
||||
"login_form_endpoint_hint": "http://deine-server-ip:port/api",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Leave album",
|
||||
"album_viewer_appbar_share_remove": "Remove from album",
|
||||
"album_viewer_page_share_add_users": "Add users",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Photo grid layout settings",
|
||||
"asset_list_settings_title": "Photo Grid",
|
||||
"backup_album_selection_page_albums_device": "Albums on device ({})",
|
||||
@@ -108,12 +112,17 @@
|
||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"experimental_settings_subtitle": "Use at your own risk!",
|
||||
"experimental_settings_title": "Experimental",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "Albums",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "New album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Abandonar álbum ",
|
||||
"album_viewer_appbar_share_remove": "Eliminar del álbum ",
|
||||
"album_viewer_page_share_add_users": "Añadir usuarios",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Photo grid layout settings",
|
||||
"asset_list_settings_title": "Photo Grid",
|
||||
"backup_album_selection_page_albums_device": "Álbumes en el dispositivo ({})",
|
||||
@@ -108,10 +112,17 @@
|
||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"experimental_settings_subtitle": "Use at your own risk!",
|
||||
"experimental_settings_title": "Experimental",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "Añadidos {added} elementos al álbum {album}. {failed} elementos ya están añadidos.",
|
||||
"home_page_add_to_album_success": "Añadidos {added} elementos al álbum {album}.",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "Albums",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "New album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"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",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Poistu albumista",
|
||||
"album_viewer_appbar_share_remove": "Poista albumista",
|
||||
"album_viewer_page_share_add_users": "Lisää käyttäjiä",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Kuvaruudukon asettelu",
|
||||
"asset_list_settings_title": "Kuvaruudukko",
|
||||
"backup_album_selection_page_albums_device": "Laitteen albumit ({})",
|
||||
@@ -108,10 +112,17 @@
|
||||
"experimental_settings_new_asset_list_title": "Ota käyttöön kokeellinen kuvaruudukko",
|
||||
"experimental_settings_subtitle": "Käyttö omalla vastuulla!",
|
||||
"experimental_settings_title": "Kokeellinen",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "Lisätty {added} kohdetta albumiin {album}. {failed} kohdetta on jo albumissa.",
|
||||
"home_page_add_to_album_success": "Lisätty {added} kohdetta albumiin {album}.",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "Albumit",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "Uusi albumi",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"login_form_button_text": "Kirjaudu",
|
||||
"login_form_email_hint": "sahkopostisi@esimerkki.fi",
|
||||
"login_form_endpoint_hint": "http://palvelimesi-osoite:portti/api",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Quitter l'album",
|
||||
"album_viewer_appbar_share_remove": "Retirer de l'album",
|
||||
"album_viewer_page_share_add_users": "Ajouter des utilisateurs",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Paramètres de disposition de la grille de photos",
|
||||
"asset_list_settings_title": "Grille de photos",
|
||||
"backup_album_selection_page_albums_device": "Albums sur l'appareil ({})",
|
||||
@@ -35,7 +39,7 @@
|
||||
"backup_controller_page_background_battery_info_title": "Optimisation de la batterie",
|
||||
"backup_controller_page_background_charging": "Seulement pendant la charge",
|
||||
"backup_controller_page_background_configure_error": "Échec de la configuration du service d'arrière-plan",
|
||||
"backup_controller_page_background_delay": "Delay new assets backup: {}",
|
||||
"backup_controller_page_background_delay": "Retarder la sauvegarde des nouveaux éléments d'actif : {}",
|
||||
"backup_controller_page_background_description": "Activez le service d'arrière-plan pour sauvegarder automatiquement tous les nouveaux éléments sans avoir à ouvrir l'application.",
|
||||
"backup_controller_page_background_is_off": "La sauvegarde automatique en arrière-plan est désactivée",
|
||||
"backup_controller_page_background_is_on": "La sauvegarde automatique en arrière-plan est activée",
|
||||
@@ -83,10 +87,10 @@
|
||||
"cache_settings_subtitle": "Contrôler le comportement de mise en cache de l'application mobile Immich",
|
||||
"cache_settings_thumbnail_size": "Taille du cache des miniatures ({} éléments)",
|
||||
"cache_settings_title": "Paramètres de mise en cache",
|
||||
"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_create_new_album": "Create new album",
|
||||
"control_bottom_app_bar_add_to_album": "Ajouter à l'album",
|
||||
"control_bottom_app_bar_album_info": "{} éléments",
|
||||
"control_bottom_app_bar_album_info_shared": "{} éléments - Partagés",
|
||||
"control_bottom_app_bar_create_new_album": "Créer un nouvel album",
|
||||
"control_bottom_app_bar_delete": "Supprimer",
|
||||
"control_bottom_app_bar_share": "Partager",
|
||||
"create_album_page_untitled": "Sans titre",
|
||||
@@ -108,28 +112,35 @@
|
||||
"experimental_settings_new_asset_list_title": "Activez la grille de photos expérimentale",
|
||||
"experimental_settings_subtitle": "Utilisez à vos dépends !",
|
||||
"experimental_settings_title": "Expérimental",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "{added} éléments ajoutés à l'album {album}. Les éléments {failed} sont déjà dans l'album.",
|
||||
"home_page_add_to_album_success": "{added} éléments ajoutés à l'album {album}.",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "Albums",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "Nouvel album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"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_url": "URL du point d'accès au serveur",
|
||||
"login_form_err_http": "Veuillez préciser http:// ou https://",
|
||||
"login_form_err_invalid_email": "Email invalide",
|
||||
"login_form_err_invalid_url": "Invalid URL",
|
||||
"login_form_err_invalid_url": "URL invalide",
|
||||
"login_form_err_leading_whitespace": "Espace en début de ligne",
|
||||
"login_form_err_trailing_whitespace": "Espace de fin de ligne",
|
||||
"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_get_oauth_server_config": "Erreur de connexion par OAuth, vérifiez l\"URL du serveur",
|
||||
"login_form_failed_get_oauth_server_disable": "La fonctionnalité OAuth n'est pas disponible sur ce serveur",
|
||||
"login_form_failed_login": "Erreur de connexion, vérifiez l'url du serveur, l'email et le mot de passe",
|
||||
"login_form_label_email": "Email",
|
||||
"login_form_label_password": "Mot de passe",
|
||||
"login_form_password_hint": "mot de passe",
|
||||
"login_form_save_login": "Rester connecté",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"profile_drawer_app_logs": "Logs",
|
||||
"profile_drawer_app_logs": "Journaux",
|
||||
"profile_drawer_client_server_up_to_date": "Le client et le serveur sont à jour",
|
||||
"profile_drawer_settings": "Paramètres",
|
||||
"profile_drawer_sign_out": "Se déconnecter",
|
||||
@@ -142,17 +153,17 @@
|
||||
"select_additional_user_for_sharing_page_suggestions": "Suggestions",
|
||||
"select_user_for_sharing_page_err_album": "Échec de la création de l'album",
|
||||
"select_user_for_sharing_page_share_suggestions": "Suggestions",
|
||||
"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_help": "Le visualiseur de détails charge d'abord la petite miniature, puis l'aperçu de taille moyenne (s'il est activé), enfin l'original (s'il est activé).",
|
||||
"setting_image_viewer_original_subtitle": "Activez cette option pour charger l'image originale en résolution originale (volumineux !). Désactiver pour réduire l'utilisation des données (réseau et cache de l'appareil).",
|
||||
"setting_image_viewer_original_title": "Charger l'image originale",
|
||||
"setting_image_viewer_preview_subtitle": "Activer pour charger une image de résolution moyenne. Désactiver pour charger directement l'original ou utiliser uniquement la miniature.",
|
||||
"setting_image_viewer_preview_title": "Charger l'image d'aperçu",
|
||||
"setting_notifications_notify_failures_grace_period": "Notifier les échecs de la sauvegarde en arrière-plan : {}",
|
||||
"setting_notifications_notify_hours": "{} heures",
|
||||
"setting_notifications_notify_immediately": "immédiatement",
|
||||
"setting_notifications_notify_minutes": "{} minutes",
|
||||
"setting_notifications_notify_never": "jamais",
|
||||
"setting_notifications_notify_seconds": "{} seconds",
|
||||
"setting_notifications_notify_seconds": "{} secondes",
|
||||
"setting_notifications_single_progress_subtitle": "Informations détaillées sur la progression du transfert par élément",
|
||||
"setting_notifications_single_progress_title": "Afficher la progression du détail de la sauvegarde en arrière-plan",
|
||||
"setting_notifications_subtitle": "Ajustez vos préférences de notification",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Lascia album",
|
||||
"album_viewer_appbar_share_remove": "Rimuovere dall'album ",
|
||||
"album_viewer_page_share_add_users": "Aggiungi utenti",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Impostazion del layout della griglia delle foto",
|
||||
"asset_list_settings_title": "Griglia foto",
|
||||
"backup_album_selection_page_albums_device": "Albums sul device ({})",
|
||||
@@ -108,10 +112,17 @@
|
||||
"experimental_settings_new_asset_list_title": "Attiva griglia di foto sperimentale",
|
||||
"experimental_settings_subtitle": "Usalo a tuo rischio!",
|
||||
"experimental_settings_title": "Sperimentale",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "Aggiunti {added} elementi all'album {album}. {failed} elementi erano già presenti nell'album.",
|
||||
"home_page_add_to_album_success": "Aggiunti {added} elementi all'album {album}",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "Album",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "Nuovo Album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "tuaemail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-del-tuo-server:port/api",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "アルバムから退会",
|
||||
"album_viewer_appbar_share_remove": "アルバムから除外",
|
||||
"album_viewer_page_share_add_users": "ユーザーを追加",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "グリッドに関する設定",
|
||||
"asset_list_settings_title": "グリッド",
|
||||
"backup_album_selection_page_albums_device": "端末上のアルバム数は {} だよ",
|
||||
@@ -108,10 +112,17 @@
|
||||
"experimental_settings_new_asset_list_title": "試験的なグリッドを有効",
|
||||
"experimental_settings_subtitle": "試験的だから自己責任でね",
|
||||
"experimental_settings_title": "試験的",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "アルバム",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "新しいアルバム",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"login_form_button_text": "ログイン",
|
||||
"login_form_email_hint": "example@email.com",
|
||||
"login_form_endpoint_hint": "https://example.com:port/api",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"album_info_card_backup_album_excluded": "UITGESLOTEN",
|
||||
"album_info_card_backup_album_included": "INGESLOTEN",
|
||||
"album_thumbnail_card_item": "1 item",
|
||||
"album_thumbnail_card_items": "{} items",
|
||||
"album_thumbnail_card_shared": " · Gedeeld",
|
||||
"album_viewer_appbar_share_delete": "Verwijder album",
|
||||
"album_viewer_appbar_share_err_delete": "Fout bij verwijderen album",
|
||||
"album_viewer_appbar_share_err_leave": "Fout bij verlaten album",
|
||||
@@ -8,7 +11,13 @@
|
||||
"album_viewer_appbar_share_err_title": "Fout bij wijzigen album titel",
|
||||
"album_viewer_appbar_share_leave": "Verlaat album",
|
||||
"album_viewer_appbar_share_remove": "Verwijder uit album",
|
||||
"album_viewer_page_share_add_users": "Voeg gebruiker toe",
|
||||
"album_viewer_page_share_add_users": "Gebruikers toevoegen",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Foto grid layout instellingen",
|
||||
"asset_list_settings_title": "Foto Grid",
|
||||
"backup_album_selection_page_albums_device": "Albums op apparaat ({})",
|
||||
"backup_album_selection_page_albums_tap": "Tik om in te voegen, dubbel tik om uit te sluiten",
|
||||
"backup_album_selection_page_assets_scatter": "Items kunnen over verschillende albums verdeeld zijn, dus albums kunnen ingesloten of uitgesloten zijn van het backup proces.",
|
||||
@@ -16,137 +25,182 @@
|
||||
"backup_album_selection_page_selection_info": "Selectie info",
|
||||
"backup_album_selection_page_total_assets": "Totaal unieke items",
|
||||
"backup_all": "Alle",
|
||||
"backup_background_service_default_notification": "Controleren op nieuw items…",
|
||||
"backup_background_service_upload_failure_notification": "Fout bij upload {}",
|
||||
"backup_background_service_in_progress_notification": "Backuppen van items…",
|
||||
"backup_background_service_current_upload_notification": "Uploaden {}",
|
||||
"backup_background_service_error_title": "Backup fout",
|
||||
"backup_background_service_connection_failed_message": "Fout bij verbinden server. Opnieuw proberen…",
|
||||
"backup_background_service_backup_failed_message": "Fout bij backuppen items. Opnieuw proberen…",
|
||||
"backup_controller_page_albums": "Backup Albums",
|
||||
"backup_controller_page_backup": "Backup",
|
||||
"backup_controller_page_backup_selected": "Geselecteerd: ",
|
||||
"backup_controller_page_backup_sub": "Foto's en video's gebackupped",
|
||||
"backup_controller_page_background_description": "Gebruik achtergrondservice om automatisch nieuwe items te uploaden naar server zonder de app te openen",
|
||||
"backup_controller_page_background_wifi": "Alleen op WiFi",
|
||||
"backup_background_service_connection_failed_message": "Fout bij verbinden server. Opnieuw proberen…",
|
||||
"backup_background_service_current_upload_notification": "Uploaden {}",
|
||||
"backup_background_service_default_notification": "Controleren op nieuw items…",
|
||||
"backup_background_service_error_title": "Backup fout",
|
||||
"backup_background_service_in_progress_notification": "Back-up maken van items…",
|
||||
"backup_background_service_upload_failure_notification": "Fout bij upload {}",
|
||||
"backup_controller_page_albums": "Back-up albums",
|
||||
"backup_controller_page_background_battery_info_link": "Toon me hoe",
|
||||
"backup_controller_page_background_battery_info_message": "Schakel voor de beste back-up ervaring op de achtergrond alle batterij optimalisaties uit, die de achtergrondactiviteit van Immich beperkt.\n\nAangezien dit apparaatspecifiek is, zoek de vereiste informatie op voor de fabrikant van je apparaat.",
|
||||
"backup_controller_page_background_battery_info_ok": "OK",
|
||||
"backup_controller_page_background_battery_info_title": "Batterij optimalisaties",
|
||||
"backup_controller_page_background_charging": "Alleen tijdens opladen",
|
||||
"backup_controller_page_background_is_on": "Automatische achtergrond backup staat aan",
|
||||
"backup_controller_page_background_is_off": "Automatische achtergrond backup staat uit",
|
||||
"backup_controller_page_background_turn_on": "Zet achtergrondservice aan",
|
||||
"backup_controller_page_background_turn_off": "Zet achtergrondservice uit",
|
||||
"backup_controller_page_background_configure_error": "Achtergrondservice configuratie mislukt",
|
||||
"backup_controller_page_background_delay": "Back-up vertraging nieuwe items: {}",
|
||||
"backup_controller_page_background_description": "Schakel de achtergrondservice in om automatisch een back-up te maken van nieuwe items zonder de app te hoeven openen",
|
||||
"backup_controller_page_background_is_off": "Automatische achtergrond back-up staat uit",
|
||||
"backup_controller_page_background_is_on": "Automatische achtergrond back-up staat aan",
|
||||
"backup_controller_page_background_turn_off": "Zet achtergrondservice uit",
|
||||
"backup_controller_page_background_turn_on": "Zet achtergrondservice aan",
|
||||
"backup_controller_page_background_wifi": "Alleen op WiFi",
|
||||
"backup_controller_page_backup": "Back-up",
|
||||
"backup_controller_page_backup_selected": "Geselecteerd: ",
|
||||
"backup_controller_page_backup_sub": "Geback-upte foto's en video's",
|
||||
"backup_controller_page_cancel": "Annuleren",
|
||||
"backup_controller_page_created": "Gemaakt op: {}",
|
||||
"backup_controller_page_desc_backup": "Configureer backup om automatisch nieuwe items te uploaden naar server.",
|
||||
"backup_controller_page_desc_backup": "Schakel back-up op de voorgrond in om automatisch nieuwe items naar de server te uploaden bij het openen van de app.",
|
||||
"backup_controller_page_excluded": "Uitgezonderd: ",
|
||||
"backup_controller_page_failed": "Mislukt ({})",
|
||||
"backup_controller_page_filename": "Bestandsnaam: {} [{}]",
|
||||
"backup_controller_page_id": "ID: {}",
|
||||
"backup_controller_page_info": "Backup informatie",
|
||||
"backup_controller_page_info": "Back-up informatie",
|
||||
"backup_controller_page_none_selected": "Geen geselecteerd",
|
||||
"backup_controller_page_remainder": "Rest",
|
||||
"backup_controller_page_remainder_sub": "Overgebleven foto's en video's om te backuppen uit selectie",
|
||||
"backup_controller_page_remainder": "Resterend",
|
||||
"backup_controller_page_remainder_sub": "Resterende foto's en video's om een back-up van te maken uit selectie",
|
||||
"backup_controller_page_select": "Selecteer",
|
||||
"backup_controller_page_server_storage": "Server Opslag",
|
||||
"backup_controller_page_start_backup": "Start Backup",
|
||||
"backup_controller_page_status_off": "Backup staat uit",
|
||||
"backup_controller_page_status_on": "Backup staat aan",
|
||||
"backup_controller_page_server_storage": "Server opslag",
|
||||
"backup_controller_page_start_backup": "Back-up uitvoeren",
|
||||
"backup_controller_page_status_off": "Automatische back-up op de voorgrond staat uit",
|
||||
"backup_controller_page_status_on": "Automatische back-up op de voorgrond staat aan",
|
||||
"backup_controller_page_storage_format": "{} van {} gebruikt",
|
||||
"backup_controller_page_to_backup": "Albums om te backuppen",
|
||||
"backup_controller_page_to_backup": "Albums om een back-up van te maken",
|
||||
"backup_controller_page_total": "Totaal",
|
||||
"backup_controller_page_total_sub": "Alle unieke foto's en video's uit geselecteerde albums",
|
||||
"backup_controller_page_turn_off": "Backup uitzetten",
|
||||
"backup_controller_page_turn_on": "Backup aanzetten",
|
||||
"backup_controller_page_turn_off": "Zet back-up op de voorgrond uit",
|
||||
"backup_controller_page_turn_on": "Zet back-up op de voorgrond aan",
|
||||
"backup_controller_page_uploading_file_info": "Bestandsgegevens uploaden",
|
||||
"backup_err_only_album": "Kan niet alleen het album verwijderen",
|
||||
"backup_err_only_album": "Kan het enige album niet verwijderen",
|
||||
"backup_info_card_assets": "items",
|
||||
"cache_settings_album_thumbnails": "Thumbnails bibliotheekpagina ({} items)",
|
||||
"cache_settings_clear_cache_button": "Cache wissen",
|
||||
"cache_settings_clear_cache_button_title": "Wist de cache van de app. Dit zal de presentaties van de app aanzienlijk beïnvloeden totdat de cache opnieuw is opgebouwd.",
|
||||
"cache_settings_image_cache_size": "Grootte afbeeldingscache ({} items)",
|
||||
"cache_settings_statistics_album": "Bibliotheek thumbnails",
|
||||
"cache_settings_statistics_assets": "{} items ({})",
|
||||
"cache_settings_statistics_full": "Volledige afbeeldingen",
|
||||
"cache_settings_statistics_shared": "Gedeeld album thumbnails",
|
||||
"cache_settings_statistics_thumbnail": "Thumbnails",
|
||||
"cache_settings_statistics_title": "Cachegebruik",
|
||||
"cache_settings_subtitle": "Beheer het cachegedrag van de Immich app",
|
||||
"cache_settings_thumbnail_size": "Thumbnail cachegrootte ({} items)",
|
||||
"cache_settings_title": "Cache instellingen",
|
||||
"control_bottom_app_bar_add_to_album": "Toevoegen aan album",
|
||||
"control_bottom_app_bar_album_info": "{} items",
|
||||
"control_bottom_app_bar_album_info_shared": "{} items · Gedeeld",
|
||||
"control_bottom_app_bar_create_new_album": "Maak nieuw album",
|
||||
"control_bottom_app_bar_delete": "Verwijderen",
|
||||
"create_shared_album_page_share": "Delen",
|
||||
"control_bottom_app_bar_share": "Delen",
|
||||
"create_album_page_untitled": "Naamloos",
|
||||
"create_shared_album_page_create": "Aanmaken",
|
||||
"create_shared_album_page_share_add_assets": "VOEG FOTO'S TOE",
|
||||
"create_shared_album_page_share_select_photos": "Selecteer Foto's",
|
||||
"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",
|
||||
"create_shared_album_page_share": "Delen",
|
||||
"create_shared_album_page_share_add_assets": "ITEMS TOEVOEGEN",
|
||||
"create_shared_album_page_share_select_photos": "Selecteer foto's",
|
||||
"daily_title_text_date": "E dd MMM",
|
||||
"daily_title_text_date_year": "E dd MMM yyyy",
|
||||
"date_format": "E d LLL y • H:mm",
|
||||
"delete_dialog_alert": "Deze items zullen permanent verwijderd worden van Immich en je apparaat",
|
||||
"delete_dialog_cancel": "Annuleren",
|
||||
"delete_dialog_ok": "Verwijderen",
|
||||
"delete_dialog_title": "Verwijder permanent",
|
||||
"exif_bottom_sheet_description": "Voeg beschrijving toe...",
|
||||
"delete_dialog_title": "Permanent verwijderen",
|
||||
"exif_bottom_sheet_description": "Beschrijving toevoegen...",
|
||||
"exif_bottom_sheet_details": "DETAILS",
|
||||
"exif_bottom_sheet_location": "LOCATIE",
|
||||
"login_form_button_text": "Login",
|
||||
"experimental_settings_new_asset_list_subtitle": "Werk in uitvoering",
|
||||
"experimental_settings_new_asset_list_title": "Experimenteel foto grid inschakelen",
|
||||
"experimental_settings_subtitle": "Gebruik op eigen risico!",
|
||||
"experimental_settings_title": "Experimenteel",
|
||||
"favorites_page_title": "Favorieten",
|
||||
"home_page_add_to_album_conflicts": "{added} items toegevoegd aan album {album}. {failed} items staan al in het album.",
|
||||
"home_page_add_to_album_success": "{added} items toegevoegd aan album {album}.",
|
||||
"home_page_building_timeline": "Tijdlijn opbouwen",
|
||||
"home_page_first_time_notice": "Als dit de eerste keer is dat je de app gebruikt, zorg er dan voor dat je een back-up album kiest, zodat de tijdlijn gevuld kan worden met foto's en video's uit het album.",
|
||||
"library_page_albums": "Albums",
|
||||
"library_page_favorites": "Favorieten",
|
||||
"library_page_new_album": "Nieuw album",
|
||||
"library_page_sharing": "Gedeeld",
|
||||
"library_page_sort_created": "Meest recent gemaakt",
|
||||
"library_page_sort_title": "Albumtitel",
|
||||
"login_form_button_text": "Inloggen",
|
||||
"login_form_email_hint": "jouwemail@email.com",
|
||||
"login_form_endpoint_hint": "http://jouw-server-ip:port/api",
|
||||
"login_form_endpoint_url": "Server URL",
|
||||
"login_form_err_http": "Voer http:// of https:// in",
|
||||
"login_form_err_invalid_email": "Ongeldige Email",
|
||||
"login_form_err_invalid_email": "Ongeldig e-mailadres",
|
||||
"login_form_err_invalid_url": "Ongeldige URL",
|
||||
"login_form_err_leading_whitespace": "Spatie aan het begin",
|
||||
"login_form_err_trailing_whitespace": "Spatie aan het eind",
|
||||
"login_form_failed_login": "Fout bij inloggen, controleer server url, email en wachtwoord",
|
||||
"login_form_label_email": "Email",
|
||||
"login_form_failed_get_oauth_server_config": "Fout bij inloggen met OAuth, controleer server URL",
|
||||
"login_form_failed_get_oauth_server_disable": "OAuth functie is niet beschikbaar op deze server",
|
||||
"login_form_failed_login": "Fout bij inloggen, controleer server URL, e-mailadres en wachtwoord",
|
||||
"login_form_label_email": "E-mailadres",
|
||||
"login_form_label_password": "Wachtwoord",
|
||||
"login_form_password_hint": "wachtwoord",
|
||||
"login_form_save_login": "Ingelogd blijven",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"profile_drawer_client_server_up_to_date": "Client en Server zijn up-to-date",
|
||||
"profile_drawer_sign_out": "Uitloggen",
|
||||
"profile_drawer_app_logs": "Logboek",
|
||||
"profile_drawer_client_server_up_to_date": "Client en server zijn up-to-date",
|
||||
"profile_drawer_settings": "Instellingen",
|
||||
"search_bar_hint": "Zoek je foto's",
|
||||
"profile_drawer_sign_out": "Uitloggen",
|
||||
"search_bar_hint": "Zoeken naar foto's",
|
||||
"search_page_no_objects": "Geen object gegevens beschikbaar",
|
||||
"search_page_no_places": "Geen locatie gegevens beschikbaar",
|
||||
"search_page_places": "Plaatsen",
|
||||
"search_page_things": "Dingen",
|
||||
"search_result_page_new_search_hint": "Nieuw resultaat",
|
||||
"search_result_page_new_search_hint": "Nieuwe zoekopdracht",
|
||||
"select_additional_user_for_sharing_page_suggestions": "Suggesties",
|
||||
"select_user_for_sharing_page_err_album": "Album aanmaken mislukt",
|
||||
"select_user_for_sharing_page_share_suggestions": "Suggesties",
|
||||
"setting_image_viewer_help": "De gedetailleerde weergave laadt eerst de kleine thumbnail, vervolgens het middelgrote voorbeeld (indien ingeschakeld) en ten slotte het origineel (indien ingeschakeld).",
|
||||
"setting_image_viewer_original_subtitle": "Inschakelen om de originele afbeelding met volledige resolutie (groot!) te laden. Uitschakelen om datagebruik te verminderen (zowel netwerk- als apparaatcache).",
|
||||
"setting_image_viewer_original_title": "Originele afbeelding laden",
|
||||
"setting_image_viewer_preview_subtitle": "Schakel in om een afbeelding met middelgrote resolutie te laden. Schakel uit om alleen het origineel direct te laden of alleen de thumbnail te gebruiken.",
|
||||
"setting_image_viewer_preview_title": "Voorbeeldafbeelding laden",
|
||||
"setting_notifications_notify_failures_grace_period": "Meld back-upfouten op de achtergrond: {}",
|
||||
"setting_notifications_notify_hours": "{} uur",
|
||||
"setting_notifications_notify_immediately": "meteen",
|
||||
"setting_notifications_notify_minutes": "{} minuten",
|
||||
"setting_notifications_notify_never": "nooit",
|
||||
"setting_notifications_notify_seconds": "{} seconden",
|
||||
"setting_notifications_single_progress_subtitle": "Gedetaileerde informatie over de uploadvoortgang per item",
|
||||
"setting_notifications_single_progress_title": "Toon gedetailleerde informatie over back-ups op de achtergrond",
|
||||
"setting_notifications_subtitle": "Werk je notificatievoorkeuren bij",
|
||||
"setting_notifications_title": "Notificaties",
|
||||
"setting_notifications_total_progress_subtitle": "Algehele uploadvoortgang (voltooid/totaal aantal items)",
|
||||
"setting_notifications_total_progress_title": "Toon de totale voortgang van achtergrond back-up",
|
||||
"setting_pages_app_bar_settings": "Instellingen",
|
||||
"settings_require_restart": "Start Immich opnieuw op om deze instelling toe te passen",
|
||||
"share_add": "Toevoegen",
|
||||
"share_add_photos": "Foto's toevoegen",
|
||||
"share_add_title": "Titel toevoegen",
|
||||
"share_create_album": "Album aanmaken",
|
||||
"share_dialog_preparing": "Voorbereiden...",
|
||||
"share_invite": "Uitnodigen voor album",
|
||||
"sharing_page_album": "Gedeelde albums",
|
||||
"sharing_page_description": "Maak gedeelde albums om foto's en video's te delen met mensen in je netwerk.",
|
||||
"sharing_page_empty_list": "LEGE LIJST",
|
||||
"sharing_silver_appbar_create_shared_album": "Maak gedeeld album",
|
||||
"sharing_silver_appbar_share_partner": "Delen met partner",
|
||||
"tab_controller_nav_library": "Bibliotheek",
|
||||
"tab_controller_nav_photos": "Foto's",
|
||||
"tab_controller_nav_search": "Zoeken",
|
||||
"tab_controller_nav_sharing": "Delen",
|
||||
"tab_controller_nav_library": "Bibliotheek",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Laat ruimte indicator zien bij item tegels",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Aantal items per rij ({})",
|
||||
"theme_setting_dark_mode_switch": "Donkere modus",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Pas de kwaliteit aan van de gedetailleerde foto weergave",
|
||||
"theme_setting_image_viewer_quality_title": "Foto weergave kwaliteit",
|
||||
"theme_setting_system_theme_switch": "Automatisch (volg systeeminstelling)",
|
||||
"theme_setting_theme_subtitle": "Kies de thema instelling van de app",
|
||||
"theme_setting_theme_title": "Thema",
|
||||
"theme_setting_three_stage_loading_subtitle": "Laden in drie fasen kan de laadprestaties verbeteren, maar veroorzaakt een aanzienlijk hogere netwerkbelasting",
|
||||
"theme_setting_three_stage_loading_title": "Schakel laden in drie fasen in",
|
||||
"version_announcement_overlay_ack": "Bevestig",
|
||||
"version_announcement_overlay_release_notes": "release opmerkingen",
|
||||
"version_announcement_overlay_text_1": "Er is een nieuwe versie beschikbaar van",
|
||||
"version_announcement_overlay_text_2": "neem je tijd en bezoek de ",
|
||||
"version_announcement_overlay_text_3": " controleer of je docker-compose en .env up-to-date zijn om te voorkomen dat er misconfiguraties zijn, in het bijzonder als je gebruik maakt van WatchTower of een ander mechanisme dat je server automatisch configureert.",
|
||||
"version_announcement_overlay_title": "Nieuwe server versie beschikbaar \uD83C\uDF89",
|
||||
"album_thumbnail_card_item": "1 item",
|
||||
"album_thumbnail_card_items": "{} items",
|
||||
"album_thumbnail_card_shared": " · Gedeeld",
|
||||
"library_page_albums": "Albums",
|
||||
"library_page_new_album": "Nieuw album",
|
||||
"create_album_page_untitled": "Naamloos",
|
||||
"share_dialog_preparing": "Voorbereiden...",
|
||||
"control_bottom_app_bar_share": "Delen",
|
||||
"setting_pages_app_bar_settings": "Instellingen",
|
||||
"theme_setting_theme_title": "Thema",
|
||||
"theme_setting_theme_subtitle": "Kies de thema instelling van de app",
|
||||
"theme_setting_system_theme_switch": "Automatisch (volg systeeminstelling)",
|
||||
"theme_setting_dark_mode_switch": "Donkere modus",
|
||||
"theme_setting_image_viewer_quality_title": "Foto weergave kwaliteit",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Pas de kwaliteit aan van de gedetailleerde foto weergave",
|
||||
"theme_setting_three_stage_loading_title": "Drie-laags laden inschakelen",
|
||||
"theme_setting_three_stage_loading_subtitle": "Three-stage loading might increase the loading performance but causes significantly higher network load",
|
||||
"asset_list_settings_title": "Foto Grid",
|
||||
"asset_list_settings_subtitle": "Foto grid layout instellingen",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Laat ruimte indicator zien bij item tegels",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Aantal items per rij ({})",
|
||||
"setting_notifications_title": "Notificaties",
|
||||
"setting_notifications_subtitle": "Werk je notificatievoorkeuren bij",
|
||||
"setting_notifications_notify_failures_grace_period": "Melding achtergrond backup fouten: {}",
|
||||
"setting_notifications_notify_immediately": "meteen",
|
||||
"setting_notifications_notify_minutes": "{} minuten",
|
||||
"setting_notifications_notify_hours": "{} uur",
|
||||
"setting_notifications_notify_never": "nooit"
|
||||
}
|
||||
"version_announcement_overlay_text_3": " controleer of je docker-compose en .env up-to-date zijn om te voorkomen dat er misconfiguraties zijn, in het bijzonder als je gebruik maakt van WatchTower of een ander mechanisme dat je serverapplicatie automatisch bijwerkt.",
|
||||
"version_announcement_overlay_title": "Nieuwe serverversie beschikbaar \uD83C\uDF89"
|
||||
}
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Opuść album",
|
||||
"album_viewer_appbar_share_remove": "Usuń z albumu",
|
||||
"album_viewer_page_share_add_users": "Dodaj użytkowników",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Ustawienia układu siatki zdjęć",
|
||||
"asset_list_settings_title": "Siatka Zdjęć",
|
||||
"backup_album_selection_page_albums_device": "Albumy na urządzeniu ({})",
|
||||
@@ -108,10 +112,17 @@
|
||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"experimental_settings_subtitle": "Use at your own risk!",
|
||||
"experimental_settings_title": "Experimental",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "Albumy",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "Nowy album",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"login_form_button_text": "Login",
|
||||
"login_form_email_hint": "twojmail@email.com",
|
||||
"login_form_endpoint_hint": "http://ip-twojego-serwera:port/api",
|
||||
|
||||
@@ -1,194 +1,206 @@
|
||||
{
|
||||
"album_info_card_backup_album_excluded": "EXCLUDED",
|
||||
"album_info_card_backup_album_included": "INCLUDED",
|
||||
"album_thumbnail_card_item": "1 item",
|
||||
"album_thumbnail_card_items": "{} items",
|
||||
"album_thumbnail_card_shared": " · Shared",
|
||||
"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_page_share_add_users": "Add users",
|
||||
"asset_list_settings_subtitle": "Photo grid layout settings",
|
||||
"asset_list_settings_title": "Photo Grid",
|
||||
"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",
|
||||
"album_info_card_backup_album_excluded": "ИСКЛЮЧЕН",
|
||||
"album_info_card_backup_album_included": "ВКЛЮЧЕН",
|
||||
"album_thumbnail_card_item": "1 объект",
|
||||
"album_thumbnail_card_items": "{} объектов",
|
||||
"album_thumbnail_card_shared": "· Общий",
|
||||
"album_viewer_appbar_share_delete": "Удалить альбом",
|
||||
"album_viewer_appbar_share_err_delete": "Невозможно удалить альбом",
|
||||
"album_viewer_appbar_share_err_leave": "Невозможно покинуть альбом",
|
||||
"album_viewer_appbar_share_err_remove": "Возникли проблемы с удалением объектов из альбома",
|
||||
"album_viewer_appbar_share_err_title": "Ошибка переименования альбома",
|
||||
"album_viewer_appbar_share_leave": "Покинуть альбом",
|
||||
"album_viewer_appbar_share_remove": "Удалить из альбома",
|
||||
"album_viewer_page_share_add_users": "Добавить пользователей",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Настройки макета сетки фотографий",
|
||||
"asset_list_settings_title": "Сетка фотографий",
|
||||
"backup_album_selection_page_albums_device": "Альбомов на устройстве ({})",
|
||||
"backup_album_selection_page_albums_tap": "Нажмите, чтобы включить, нажмите дважды, чтобы исключить",
|
||||
"backup_album_selection_page_assets_scatter": "Объекты могут быть разбросаны по нескольким альбомам. Таким образом, альбомы могут быть включены или исключены из процесса резервного копирования.",
|
||||
"backup_album_selection_page_select_albums": "Выбрать альбомы",
|
||||
"backup_album_selection_page_selection_info": "Информация о выборе",
|
||||
"backup_album_selection_page_total_assets": "Всего уникальных объектов",
|
||||
"backup_all": "Все",
|
||||
"backup_background_service_backup_failed_message": "Не удалось выполнить резервное копирование. Повторная попытка…",
|
||||
"backup_background_service_connection_failed_message": "Не удалось подключиться к серверу. Повторная попытка...",
|
||||
"backup_background_service_current_upload_notification": "Uploading {}",
|
||||
"backup_background_service_default_notification": "Checking for new assets…",
|
||||
"backup_background_service_current_upload_notification": "Загружается {}",
|
||||
"backup_background_service_default_notification": "Поиск новых объектов…",
|
||||
"backup_background_service_error_title": "Ошибка резервного копирования",
|
||||
"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_background_service_in_progress_notification": "Резервное копирование ваших объектов…",
|
||||
"backup_background_service_upload_failure_notification": "Ошибка загрузки {}",
|
||||
"backup_controller_page_albums": "Резервное копирование альбомов",
|
||||
"backup_controller_page_background_battery_info_link": "Показать как",
|
||||
"backup_controller_page_background_battery_info_message": "Для наилучшего фонового резервного копирования отключите любые настройки оптимизации батареи, ограничивающие фоновую активность для Immich.\n\nПоскольку это зависит от устройства, найдите необходимую информацию для производителя вашего устройства.",
|
||||
"backup_controller_page_background_battery_info_ok": "ОК",
|
||||
"backup_controller_page_background_battery_info_title": "Battery optimizations",
|
||||
"backup_controller_page_background_battery_info_title": "\nОптимизация батареи",
|
||||
"backup_controller_page_background_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": "Выключить фоновый сервис",
|
||||
"backup_controller_page_background_turn_on": "Включить фоновый сервис",
|
||||
"backup_controller_page_background_wifi": "Только на 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_background_configure_error": "Не удалось настроить фоновую службу",
|
||||
"backup_controller_page_background_delay": "Отложить резервное копирование новых объектов: {}",
|
||||
"backup_controller_page_background_description": "Включите фоновую службу для автоматического резервного копирования любых новых объектов без необходимости открывать приложение",
|
||||
"backup_controller_page_background_is_off": "Автоматическое резервное копирование в фоновом режиме отключено",
|
||||
"backup_controller_page_background_is_on": "Автоматическое резервное копирование в фоновом режиме включено",
|
||||
"backup_controller_page_background_turn_off": "Выключить фоновую службу",
|
||||
"backup_controller_page_background_turn_on": "Включить фоновую службу",
|
||||
"backup_controller_page_background_wifi": "Только через WiFi",
|
||||
"backup_controller_page_backup": "Резервное копирование",
|
||||
"backup_controller_page_backup_selected": "Выбрано: ",
|
||||
"backup_controller_page_backup_sub": "Загруженные фото и видео",
|
||||
"backup_controller_page_cancel": "Отмена",
|
||||
"backup_controller_page_created": "Создано на: {}",
|
||||
"backup_controller_page_desc_backup": "Включите резервное копирование в активном режиме, чтобы автоматически загружать новые активы на сервер при открытии приложения.",
|
||||
"backup_controller_page_excluded": "Исключены:",
|
||||
"backup_controller_page_failed": "Неудачных ({})",
|
||||
"backup_controller_page_filename": "Имя файла: {} [{}]",
|
||||
"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 backup",
|
||||
"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",
|
||||
"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_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_title": "Caching Settings",
|
||||
"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_create_new_album": "Create new album",
|
||||
"backup_controller_page_info": "Информация о резервном копировании",
|
||||
"backup_controller_page_none_selected": "Ничего не выбрано",
|
||||
"backup_controller_page_remainder": "Осталось",
|
||||
"backup_controller_page_remainder_sub": "Оставшиеся фото и видео для резервного копирования из выбранного",
|
||||
"backup_controller_page_select": "Выбор",
|
||||
"backup_controller_page_server_storage": "Хранилище на сервере",
|
||||
"backup_controller_page_start_backup": "Начать резервное копирование",
|
||||
"backup_controller_page_status_off": "Автоматическое резервное копирование в активном режиме выключено",
|
||||
"backup_controller_page_status_on": "Автоматическое резервное копирование в активном режиме включено",
|
||||
"backup_controller_page_storage_format": "{} из {} использовано",
|
||||
"backup_controller_page_to_backup": "Альбомы для резервного копирования",
|
||||
"backup_controller_page_total": "Всего",
|
||||
"backup_controller_page_total_sub": "Все уникальные фото и видео из выбранных альбомов",
|
||||
"backup_controller_page_turn_off": "Выключить резервное копирование в активном режиме",
|
||||
"backup_controller_page_turn_on": "Включить резервное копирование в активном режиме",
|
||||
"backup_controller_page_uploading_file_info": "Загрузка информации о файле",
|
||||
"backup_err_only_album": "Невозможно удалить единственный альбом",
|
||||
"backup_info_card_assets": "объекты",
|
||||
"cache_settings_album_thumbnails": "Миниатюры страниц библиотеки ({} объектов)",
|
||||
"cache_settings_clear_cache_button": "Очистить кэш",
|
||||
"cache_settings_clear_cache_button_title": "Очищает кэш приложения. Это значительно повлияет на производительность приложения, до тех пор, пока кэш не будет перестроен заново.",
|
||||
"cache_settings_image_cache_size": "Размер кэша изображений ({} объектов)",
|
||||
"cache_settings_statistics_album": "Миниатюры библиотеки",
|
||||
"cache_settings_statistics_assets": "{} объектов ({})",
|
||||
"cache_settings_statistics_full": "Полные изображения",
|
||||
"cache_settings_statistics_shared": "Миниатюры общих альбомов",
|
||||
"cache_settings_statistics_thumbnail": "Миниатюры",
|
||||
"cache_settings_statistics_title": "Размер кэша",
|
||||
"cache_settings_subtitle": "Управление кэшированием мобильного приложения Immich",
|
||||
"cache_settings_thumbnail_size": "Размер кэша эскизов ({} объектов)",
|
||||
"cache_settings_title": "Настройки кэширования",
|
||||
"control_bottom_app_bar_add_to_album": "Добавить в альбом",
|
||||
"control_bottom_app_bar_album_info": "{} файлов",
|
||||
"control_bottom_app_bar_album_info_shared": "{} файлов · Общий",
|
||||
"control_bottom_app_bar_create_new_album": "\nСоздать новый альбом",
|
||||
"control_bottom_app_bar_delete": "Удалить",
|
||||
"control_bottom_app_bar_share": "Поделиться",
|
||||
"create_album_page_untitled": "Untitled",
|
||||
"create_album_page_untitled": "Без названия",
|
||||
"create_shared_album_page_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",
|
||||
"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",
|
||||
"create_shared_album_page_share": "Поделиться",
|
||||
"create_shared_album_page_share_add_assets": "ДОБАВИТЬ ОБЪЕКТЫ",
|
||||
"create_shared_album_page_share_select_photos": "Выберите фотографии",
|
||||
"daily_title_text_date": "ДН, МММ дд",
|
||||
"daily_title_text_date_year": "ДН, МММ дд, гггг",
|
||||
"date_format": "ДН, LLL д, г • ч:мм a",
|
||||
"delete_dialog_alert": "Эти объекты будут безвозвратно удалены из приложения, а также с вашего устройства",
|
||||
"delete_dialog_cancel": "Отменить",
|
||||
"delete_dialog_ok": "Удалить",
|
||||
"delete_dialog_title": "Удалить навсегда",
|
||||
"exif_bottom_sheet_description": "Add Description...",
|
||||
"exif_bottom_sheet_details": "DETAILS",
|
||||
"exif_bottom_sheet_location": "LOCATION",
|
||||
"experimental_settings_new_asset_list_subtitle": "Work in progress",
|
||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"exif_bottom_sheet_description": "Добавить описание...",
|
||||
"exif_bottom_sheet_details": "ПОДРОБНОСТИ",
|
||||
"exif_bottom_sheet_location": "МЕСТОПОЛОЖЕНИЕ",
|
||||
"experimental_settings_new_asset_list_subtitle": "Работа ведётся",
|
||||
"experimental_settings_new_asset_list_title": "Включить экспериментальную сетку фотографий",
|
||||
"experimental_settings_subtitle": "Используйте на свой страх и риск!",
|
||||
"experimental_settings_title": "Экспериментальное",
|
||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||
"experimental_settings_title": "Экспериментальные функции",
|
||||
"favorites_page_title": "Избранное",
|
||||
"home_page_add_to_album_conflicts": "Добавлено {added} объектов в альбом {album}. Объекты {failed} уже есть в альбоме.",
|
||||
"home_page_add_to_album_success": "Добавлено {added} объектов в альбом {album}.",
|
||||
"home_page_building_timeline": "Построение временной шкалы",
|
||||
"home_page_first_time_notice": "Если вы используете приложение впервые, убедитесь, что вы выбрали резервный(е) альбом(ы), чтобы временная шкала могла заполнить фотографии и видео в альбоме(ах).",
|
||||
"library_page_albums": "Альбомы",
|
||||
"library_page_favorites": "Избранное",
|
||||
"library_page_new_album": "Новый альбом",
|
||||
"login_form_button_text": "Login",
|
||||
"library_page_sharing": "Общие",
|
||||
"library_page_sort_created": "По новизне",
|
||||
"library_page_sort_title": "По названию альбома",
|
||||
"login_form_button_text": "Войти",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"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_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_endpoint_url": "URL Адрес сервера",
|
||||
"login_form_err_http": "Пожалуйста, укажите http:// или https://",
|
||||
"login_form_err_invalid_email": "Неверный адрес Email",
|
||||
"login_form_err_invalid_url": "Неверная ссылка",
|
||||
"login_form_err_leading_whitespace": "Пробел до",
|
||||
"login_form_err_trailing_whitespace": "Пробел после",
|
||||
"login_form_failed_get_oauth_server_config": "Ошибка авторизации с использованием OAuth, проверьте URL-адрес сервера",
|
||||
"login_form_failed_get_oauth_server_disable": "Функция OAuth недоступна на этом сервере.",
|
||||
"login_form_failed_login": "Ошибка при входе в систему, проверьте URL-адрес сервера, адрес электронной почты и пароль",
|
||||
"login_form_label_email": "Email",
|
||||
"login_form_label_password": "Password",
|
||||
"login_form_password_hint": "password",
|
||||
"login_form_save_login": "Stay logged in",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"profile_drawer_app_logs": "Logs",
|
||||
"profile_drawer_client_server_up_to_date": "Client and Server are up-to-date",
|
||||
"login_form_label_password": "Пароль",
|
||||
"login_form_password_hint": "пароль",
|
||||
"login_form_save_login": "Оставаться в системе",
|
||||
"monthly_title_text_date_format": "ММММ г",
|
||||
"profile_drawer_app_logs": "Журналы",
|
||||
"profile_drawer_client_server_up_to_date": "Клиент и сервер обновлены",
|
||||
"profile_drawer_settings": "Настройки",
|
||||
"profile_drawer_sign_out": "Выйти",
|
||||
"search_bar_hint": "Search your photos",
|
||||
"search_page_no_objects": "No Objects Info Available",
|
||||
"search_page_no_places": "No Places Info Available",
|
||||
"search_bar_hint": "Поиск фотографий",
|
||||
"search_page_no_objects": "Нет доступной информации об объектах",
|
||||
"search_page_no_places": "Информация о местах отсутствует",
|
||||
"search_page_places": "Места",
|
||||
"search_page_things": "Предметы",
|
||||
"search_result_page_new_search_hint": "Новый Поиск",
|
||||
"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",
|
||||
"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_notifications_notify_failures_grace_period": "Notify background backup failures: {}",
|
||||
"search_result_page_new_search_hint": "Новый поиск",
|
||||
"select_additional_user_for_sharing_page_suggestions": "Предложения",
|
||||
"select_user_for_sharing_page_err_album": "\nНе удалось создать альбом",
|
||||
"select_user_for_sharing_page_share_suggestions": "Предложения",
|
||||
"setting_image_viewer_help": "Средство просмотра деталей сначала загружает маленькую миниатюру, затем загружает предварительный просмотр среднего размера (если включено) и, наконец, загружает оригинал (если включено).",
|
||||
"setting_image_viewer_original_subtitle": "Включите загрузку оригинального изображения в полном разрешении (большое!). Отключите, чтобы уменьшить объем данных (как в сети, так и в кеше устройства).",
|
||||
"setting_image_viewer_original_title": "Загрузить исходное изображение",
|
||||
"setting_image_viewer_preview_subtitle": "Включите загрузку изображения среднего разрешения. Отключите, чтобы загрузить оригинал напрямую или использовать только миниатюру.",
|
||||
"setting_image_viewer_preview_title": "Загрузить изображение для предварительного просмотра",
|
||||
"setting_notifications_notify_failures_grace_period": "Уведомлять об ошибках фонового резервного копирования: {}",
|
||||
"setting_notifications_notify_hours": "{} часов",
|
||||
"setting_notifications_notify_immediately": "немедленно",
|
||||
"setting_notifications_notify_minutes": "{} минут",
|
||||
"setting_notifications_notify_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_notify_seconds": "{} секунд",
|
||||
"setting_notifications_single_progress_subtitle": "Подробная информация о ходе загрузки для каждого объекта",
|
||||
"setting_notifications_single_progress_title": "Показать ход выполнения фонового резервного копирования",
|
||||
"setting_notifications_subtitle": "Настроить параметры уведомлений",
|
||||
"setting_notifications_title": "Уведомления",
|
||||
"setting_notifications_total_progress_subtitle": "Overall upload progress (done/total assets)",
|
||||
"setting_notifications_total_progress_title": "Show background backup total progress",
|
||||
"setting_notifications_total_progress_subtitle": "Общий прогресс загрузки (выполнено/всего объектов)",
|
||||
"setting_notifications_total_progress_title": "Показать общий прогресс фонового резервного копирования",
|
||||
"setting_pages_app_bar_settings": "Настройки",
|
||||
"settings_require_restart": "Please restart Immich to apply this setting",
|
||||
"share_add": "Add",
|
||||
"share_add_photos": "Add photos",
|
||||
"share_add_title": "Add a title",
|
||||
"share_create_album": "Create album",
|
||||
"share_dialog_preparing": "Preparing...",
|
||||
"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": "Create shared album",
|
||||
"sharing_silver_appbar_share_partner": "Share with partner",
|
||||
"tab_controller_nav_library": "Library",
|
||||
"tab_controller_nav_photos": "Photos",
|
||||
"settings_require_restart": "Пожалуйста, перезапустите приложение, чтобы изменения вступили в силу",
|
||||
"share_add": "Добавить",
|
||||
"share_add_photos": "Добавить фото",
|
||||
"share_add_title": "Добавить название",
|
||||
"share_create_album": "Создать альбом",
|
||||
"share_dialog_preparing": "Подготовка...",
|
||||
"share_invite": "\nПригласить в альбом",
|
||||
"sharing_page_album": "Общие альбомы",
|
||||
"sharing_page_description": "Создавайте общие альбомы, чтобы делиться фотографиями и видео с людьми в вашей сети.",
|
||||
"sharing_page_empty_list": "ПУСТОЙ СПИСОК",
|
||||
"sharing_silver_appbar_create_shared_album": "Создать общий альбом",
|
||||
"sharing_silver_appbar_share_partner": "Поделиться с партнером",
|
||||
"tab_controller_nav_library": "Библиотека",
|
||||
"tab_controller_nav_photos": "Фото",
|
||||
"tab_controller_nav_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 ({})",
|
||||
"tab_controller_nav_sharing": "Общие",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Показать индикатор хранилища на плитках объектов",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Количество объектов в строке ({})",
|
||||
"theme_setting_dark_mode_switch": "Тёмная тема",
|
||||
"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_system_theme_switch": "Автоматически (следовать системным настройкам)",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Настройте качество просмотра подробного изображения",
|
||||
"theme_setting_image_viewer_quality_title": "Качество просмотра изображений",
|
||||
"theme_setting_system_theme_switch": "Автоматически (Как в системе)",
|
||||
"theme_setting_theme_subtitle": "Выберите настройки темы приложения",
|
||||
"theme_setting_theme_title": "Тема",
|
||||
"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",
|
||||
"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.",
|
||||
"theme_setting_three_stage_loading_subtitle": "Трехэтапная загрузка может повысить производительность загрузки, но вызывает значительно более высокую нагрузку на сеть",
|
||||
"theme_setting_three_stage_loading_title": "Включить трехэтапную загрузку",
|
||||
"version_announcement_overlay_ack": "Подтверждение",
|
||||
"version_announcement_overlay_release_notes": "примечания к выпуску",
|
||||
"version_announcement_overlay_text_1": "Привет друг, вышел новый релиз",
|
||||
"version_announcement_overlay_text_2": "пожалуйста, найдите время, чтобы посетить",
|
||||
"version_announcement_overlay_text_3": " и убедитесь, что ваши настройки docker-compose и .env обновлены, чтобы предотвратить любые неправильные настройки, особенно если вы используете WatchTower или любой другой механизм, который обрабатывает обновление вашего серверного приложения автоматически.",
|
||||
"version_announcement_overlay_title": "Доступна новая версия сервера \uD83C\uDF89"
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
"album_thumbnail_card_item": "1 položka",
|
||||
"album_thumbnail_card_items": "{} položky",
|
||||
"album_thumbnail_card_shared": "Zdieľané",
|
||||
"album_viewer_appbar_share_delete": "odstrániť album",
|
||||
"album_viewer_appbar_share_delete": "Odstrániť album",
|
||||
"album_viewer_appbar_share_err_delete": "Nepodarilo sa odstrániť album",
|
||||
"album_viewer_appbar_share_err_leave": "Nepodarilo sa ukončiť album",
|
||||
"album_viewer_appbar_share_err_remove": "Pri odstraňovaní súborov z albumu sa vyskytli problémy.",
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "Opustiť album",
|
||||
"album_viewer_appbar_share_remove": "Odstrániť z albumu",
|
||||
"album_viewer_page_share_add_users": "Pridať používateľov",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "Nastavenia rozloženia mriežky fotografií",
|
||||
"asset_list_settings_title": "Fotografická mriežka",
|
||||
"backup_album_selection_page_albums_device": "Albumy v zariadení ({})",
|
||||
@@ -42,9 +46,9 @@
|
||||
"backup_controller_page_background_turn_off": "Zakázať službu na pozadí",
|
||||
"backup_controller_page_background_turn_on": "Povoliť službu na pozadí",
|
||||
"backup_controller_page_background_wifi": "Len na WiFi",
|
||||
"backup_controller_page_backup": "Zálohovanie",
|
||||
"backup_controller_page_backup": "Zálohované",
|
||||
"backup_controller_page_backup_selected": "Vybrané: ",
|
||||
"backup_controller_page_backup_sub": "Zálohovanie fotografií a videí",
|
||||
"backup_controller_page_backup_sub": "Zálohované fotografie a videa",
|
||||
"backup_controller_page_cancel": "Zrušiť",
|
||||
"backup_controller_page_created": "Vytvorené: {}",
|
||||
"backup_controller_page_desc_backup": "Zapnite zálohovanie na popredí, aby sa nové položky automaticky nahrávali na server pri otvorení aplikácie.",
|
||||
@@ -54,7 +58,7 @@
|
||||
"backup_controller_page_id": "ID: {}",
|
||||
"backup_controller_page_info": "Informácie o zálohovaní",
|
||||
"backup_controller_page_none_selected": "Žiadne vybrané",
|
||||
"backup_controller_page_remainder": "Zvyšok",
|
||||
"backup_controller_page_remainder": "Zostáva",
|
||||
"backup_controller_page_remainder_sub": "Zostávajúce fotografie a albumy, ktoré sa majú zálohovať z výberu",
|
||||
"backup_controller_page_select": "Vybrať",
|
||||
"backup_controller_page_server_storage": "Serverové úložisko",
|
||||
@@ -67,9 +71,9 @@
|
||||
"backup_controller_page_total_sub": "Všetky jedinečné fotografie a videá z vybraných albumov",
|
||||
"backup_controller_page_turn_off": "Zakázať zálohovanie na popredí",
|
||||
"backup_controller_page_turn_on": "Povoliť zálohovanie na popredí",
|
||||
"backup_controller_page_uploading_file_info": "Nahrávanie informácií o súboroch",
|
||||
"backup_err_only_album": "Nie je možné odstrániť iba album",
|
||||
"backup_info_card_assets": "položky",
|
||||
"backup_controller_page_uploading_file_info": "Informácia o nahrávanom súbore",
|
||||
"backup_err_only_album": "Nie je možné odstrániť jediný vybraný album",
|
||||
"backup_info_card_assets": "položiek",
|
||||
"cache_settings_album_thumbnails": "Náhľady stránok knižnice (položiek {})",
|
||||
"cache_settings_clear_cache_button": "Vymazať vyrovnávaciu pamäť",
|
||||
"cache_settings_clear_cache_button_title": "Vymaže vyrovnávaciu pamäť aplikácie. To výrazne ovplyvní výkon aplikácie, kým sa vyrovnávacia pamäť neobnoví.",
|
||||
@@ -94,9 +98,9 @@
|
||||
"create_shared_album_page_share": "Zdieľať",
|
||||
"create_shared_album_page_share_add_assets": "PRIDAŤ",
|
||||
"create_shared_album_page_share_select_photos": "Vybrať fotografie",
|
||||
"daily_title_text_date": "EEEE, d MMMM",
|
||||
"daily_title_text_date_year": "EEEE, d MMMM y",
|
||||
"date_format": "EEEE, d MMMM y • H:mm",
|
||||
"daily_title_text_date": "EEEE, d. MMMM",
|
||||
"daily_title_text_date_year": "EEEE, d. MMMM y",
|
||||
"date_format": "EEEE, d. MMMM y • H:mm",
|
||||
"delete_dialog_alert": "Tieto položky budú natrvalo odstránené z Immich a z vášho zariadenia.",
|
||||
"delete_dialog_cancel": "Zrušiť",
|
||||
"delete_dialog_ok": "Vymazať",
|
||||
@@ -108,16 +112,24 @@
|
||||
"experimental_settings_new_asset_list_title": "Povolenie experimentálnej mriežky fotografií",
|
||||
"experimental_settings_subtitle": "Používajte na vlastné riziko!",
|
||||
"experimental_settings_title": "Experimentálne",
|
||||
"favorites_page_title": "Obľúbené",
|
||||
"home_page_add_to_album_conflicts": "Pridané {added} položky do albumu {album}. {failed} položky sú už v albume.",
|
||||
"home_page_add_to_album_success": "Pridané {added} položky do albumu {album}.",
|
||||
"home_page_building_timeline": "Vytváranie časovej osi",
|
||||
"home_page_first_time_notice": "Ak aplikáciu používate prvýkrát, nezabudnite si vybrať zálohované albumy, aby sa na časovej osi mohli nachádzať fotografie a videá z vybraných albumoch.",
|
||||
"library_page_albums": "Albumy",
|
||||
"library_page_favorites": "Obľúbené",
|
||||
"library_page_new_album": "Nový album",
|
||||
"login_form_button_text": "Prihlásenie",
|
||||
"library_page_sharing": "Zdieľanie",
|
||||
"library_page_sort_created": "Najnovšie vytvorené",
|
||||
"library_page_sort_title": "Podľa názvu albumu",
|
||||
"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_url": "URL adresa servera",
|
||||
"login_form_err_http": "Prosím, uveďte http:// alebo https://",
|
||||
"login_form_err_invalid_email": "Neplatný e-mail",
|
||||
"login_form_err_invalid_url": "Neplatná URL",
|
||||
"login_form_err_leading_whitespace": "Úvodná medzera",
|
||||
"login_form_err_trailing_whitespace": "Koncové medzera",
|
||||
"login_form_failed_get_oauth_server_config": "Chyba prihlásenia pomocou OAuth, skontrolujte adresu URL servera",
|
||||
@@ -141,7 +153,7 @@
|
||||
"select_additional_user_for_sharing_page_suggestions": "Návrhy",
|
||||
"select_user_for_sharing_page_err_album": "Nepodarilo sa vytvoriť album",
|
||||
"select_user_for_sharing_page_share_suggestions": "Návrhy",
|
||||
"setting_image_viewer_help": "V prehliadači detailov sa najprv načíta malá miniatúra, potom sa načíta náhľad strednej veľkosti (ak je povoleny) a nakoniec sa načíta originál (ak je povolený).",
|
||||
"setting_image_viewer_help": "V prehliadači detailov sa najprv načíta malá miniatúra, potom sa načíta náhľad strednej veľkosti (ak je povolený) a nakoniec sa načíta originál (ak je povolený).",
|
||||
"setting_image_viewer_original_subtitle": "Umožňuje načítať pôvodný obrázok v plnom rozlíšení (veľký!). Zakázať pre zníženie používania dát (v sieti aj v medzipamäti zariadenia).",
|
||||
"setting_image_viewer_original_title": "Načítať pôvodný obrázok",
|
||||
"setting_image_viewer_preview_subtitle": "Umožňuje načítať obrázok so stredným rozlíšením. Zakážte, ak chcete priamo načítať originál alebo použiť iba miniatúru.",
|
||||
@@ -158,7 +170,7 @@
|
||||
"setting_notifications_title": "Oznámenia",
|
||||
"setting_notifications_total_progress_subtitle": "Celkový priebeh nahrávania (hotové/celkové položky)",
|
||||
"setting_notifications_total_progress_title": "Zobraziť celkový priebeh zálohovania na pozadí",
|
||||
"setting_pages_app_bar_settings": "nastavenia",
|
||||
"setting_pages_app_bar_settings": "Nastavenia",
|
||||
"settings_require_restart": "Na použitie tohto nastavenia reštartujte Immich",
|
||||
"share_add": "Pridať",
|
||||
"share_add_photos": "Pridať fotografie",
|
||||
@@ -168,15 +180,15 @@
|
||||
"share_invite": "Pozvať do albumu",
|
||||
"sharing_page_album": "Shared albums",
|
||||
"sharing_page_description": "Vytvárajte zdieľané albumy a zdieľajte fotografie a videá s ľuďmi vo vašej sieti.",
|
||||
"sharing_page_empty_list": "Prázny list",
|
||||
"sharing_page_empty_list": "Prázdny list",
|
||||
"sharing_silver_appbar_create_shared_album": "Vytvoriť zdieľaný album",
|
||||
"sharing_silver_appbar_share_partner": "Zdieľať s partnerom",
|
||||
"tab_controller_nav_library": "Knižnica",
|
||||
"tab_controller_nav_photos": "Fotografie",
|
||||
"tab_controller_nav_search": "Vyhľadávanie",
|
||||
"tab_controller_nav_sharing": "Zdieľanie",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Zobraziť indikátor úložiska na dlaždiciach zdrojov",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Počet aktív na riadok ({})",
|
||||
"theme_setting_asset_list_storage_indicator_title": "Zobraziť indikátor úložiska na dlaždiciach položiek",
|
||||
"theme_setting_asset_list_tiles_per_row_title": "Počet položiek na riadok ({})",
|
||||
"theme_setting_dark_mode_switch": "Tmavá téma",
|
||||
"theme_setting_image_viewer_quality_subtitle": "Prispôsobenie kvality prehliadača detailov",
|
||||
"theme_setting_image_viewer_quality_title": "Kvalita prehliadača obrázkov",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"album_viewer_appbar_share_leave": "退出相册",
|
||||
"album_viewer_appbar_share_remove": "从相册中移除",
|
||||
"album_viewer_page_share_add_users": "新增用户",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||
"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_settings_subtitle": "照片预览设置",
|
||||
"asset_list_settings_title": "照片预览",
|
||||
"backup_album_selection_page_albums_device": "设备上的相册({})",
|
||||
@@ -108,16 +112,24 @@
|
||||
"experimental_settings_new_asset_list_title": "启用实验性的照片宫格",
|
||||
"experimental_settings_subtitle": "使用风险自负!",
|
||||
"experimental_settings_title": "实验功能",
|
||||
"favorites_page_title": "Favorites",
|
||||
"home_page_add_to_album_conflicts": "添加{added}张到相册{album}。{failed} 项已经处于该相册中。",
|
||||
"home_page_add_to_album_success": "添加了{added}张到相册{album}。",
|
||||
"home_page_building_timeline": "Building the timeline",
|
||||
"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).",
|
||||
"library_page_albums": "相册",
|
||||
"library_page_favorites": "Favorites",
|
||||
"library_page_new_album": "新建相册",
|
||||
"library_page_sharing": "Sharing",
|
||||
"library_page_sort_created": "Most recently created",
|
||||
"library_page_sort_title": "Album title",
|
||||
"login_form_button_text": "登录",
|
||||
"login_form_email_hint": "youremail@email.com",
|
||||
"login_form_endpoint_hint": "http://your-server-ip:port/api",
|
||||
"login_form_endpoint_url": "服务器地址",
|
||||
"login_form_err_http": "请检查http://或https://",
|
||||
"login_form_err_invalid_email": "请输入正确的邮箱",
|
||||
"login_form_err_invalid_url": "Invalid URL",
|
||||
"login_form_err_leading_whitespace": "前面空格",
|
||||
"login_form_err_trailing_whitespace": "后面空格",
|
||||
"login_form_failed_get_oauth_server_config": "使用 OAuth 时出错,请检查服务器 地址",
|
||||
|
||||
BIN
mobile/assets/immich-splash-android12.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
mobile/assets/immich-splash.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
138
mobile/flutter_native_splash.yaml
Normal file
@@ -0,0 +1,138 @@
|
||||
flutter_native_splash:
|
||||
# This package generates native code to customize Flutter's default white native splash screen
|
||||
# with background color and splash image.
|
||||
# Customize the parameters below, and run the following command in the terminal:
|
||||
# flutter pub run flutter_native_splash:create
|
||||
# To restore Flutter's default white splash screen, run the following command in the terminal:
|
||||
# flutter pub run flutter_native_splash:remove
|
||||
|
||||
# color or background_image is the only required parameter. Use color to set the background
|
||||
# of your splash screen to a solid color. Use background_image to set the background of your
|
||||
# splash screen to a png image. This is useful for gradients. The image will be stretch to the
|
||||
# size of the app. Only one parameter can be used, color and background_image cannot both be set.
|
||||
#background_image: "assets/immich-logo-no-outline.png"
|
||||
color: "#f6f8fe"
|
||||
|
||||
# Optional parameters are listed below. To enable a parameter, uncomment the line by removing
|
||||
# the leading # character.
|
||||
|
||||
# The image parameter allows you to specify an image used in the splash screen. It must be a
|
||||
# png file and should be sized for 4x pixel density.
|
||||
image: assets/immich-splash.png
|
||||
|
||||
# The branding property allows you to specify an image used as branding in the splash screen.
|
||||
# It must be a png file. It is supported for Android, iOS and the Web. For Android 12,
|
||||
# see the Android 12 section below.
|
||||
#branding: assets/dart.png
|
||||
|
||||
# To position the branding image at the bottom of the screen you can use bottom, bottomRight,
|
||||
# and bottomLeft. The default values is bottom if not specified or specified something else.
|
||||
#branding_mode: bottom
|
||||
|
||||
# The color_dark, background_image_dark, image_dark, branding_dark are parameters that set the background
|
||||
# and image when the device is in dark mode. If they are not specified, the app will use the
|
||||
# parameters from above. If the image_dark parameter is specified, color_dark or
|
||||
# background_image_dark must be specified. color_dark and background_image_dark cannot both be
|
||||
# set.
|
||||
color_dark: "#000000"
|
||||
#background_image_dark: "assets/dark-background.png"
|
||||
#image_dark: assets/splash-invert.png
|
||||
#branding_dark: assets/dart_dark.png
|
||||
|
||||
# Android 12 handles the splash screen differently than previous versions. Please visit
|
||||
# https://developer.android.com/guide/topics/ui/splash-screen
|
||||
# Following are Android 12 specific parameter.
|
||||
android_12:
|
||||
# The image parameter sets the splash screen icon image. If this parameter is not specified,
|
||||
# the app's launcher icon will be used instead.
|
||||
# Please note that the splash screen will be clipped to a circle on the center of the screen.
|
||||
# App icon with an icon background: This should be 960×960 pixels, and fit within a circle
|
||||
# 640 pixels in diameter.
|
||||
# App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
|
||||
# 768 pixels in diameter.
|
||||
image: assets/immich-splash-android12.png
|
||||
|
||||
# Splash screen background color.
|
||||
#color: "#42a5f5"
|
||||
|
||||
# App icon background color.
|
||||
#icon_background_color: "#111111"
|
||||
|
||||
# The branding property allows you to specify an image used as branding in the splash screen.
|
||||
#branding: assets/dart.png
|
||||
|
||||
# The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that
|
||||
# apply when the device is in dark mode. If they are not specified, the app will use the
|
||||
# parameters from above.
|
||||
#image_dark: assets/android12splash-invert.png
|
||||
#color_dark: "#042a49"
|
||||
#icon_background_color_dark: "#eeeeee"
|
||||
|
||||
# The android, ios and web parameters can be used to disable generating a splash screen on a given
|
||||
# platform.
|
||||
#android: false
|
||||
#ios: false
|
||||
#web: false
|
||||
|
||||
# Platform specific images can be specified with the following parameters, which will override
|
||||
# the respective parameter. You may specify all, selected, or none of these parameters:
|
||||
#color_android: "#42a5f5"
|
||||
#color_dark_android: "#042a49"
|
||||
#color_ios: "#42a5f5"
|
||||
#color_dark_ios: "#042a49"
|
||||
#color_web: "#42a5f5"
|
||||
#color_dark_web: "#042a49"
|
||||
#image_android: assets/splash-android.png
|
||||
#image_dark_android: assets/splash-invert-android.png
|
||||
#image_ios: assets/splash-ios.png
|
||||
#image_dark_ios: assets/splash-invert-ios.png
|
||||
#image_web: assets/splash-web.png
|
||||
#image_dark_web: assets/splash-invert-web.png
|
||||
#background_image_android: "assets/background-android.png"
|
||||
#background_image_dark_android: "assets/dark-background-android.png"
|
||||
#background_image_ios: "assets/background-ios.png"
|
||||
#background_image_dark_ios: "assets/dark-background-ios.png"
|
||||
#background_image_web: "assets/background-web.png"
|
||||
#background_image_dark_web: "assets/dark-background-web.png"
|
||||
#branding_android: assets/brand-android.png
|
||||
#branding_dark_android: assets/dart_dark-android.png
|
||||
#branding_ios: assets/brand-ios.png
|
||||
#branding_dark_ios: assets/dart_dark-ios.png
|
||||
|
||||
# The position of the splash image can be set with android_gravity, ios_content_mode, and
|
||||
# web_image_mode parameters. All default to center.
|
||||
#
|
||||
# android_gravity can be one of the following Android Gravity (see
|
||||
# https://developer.android.com/reference/android/view/Gravity): bottom, center,
|
||||
# center_horizontal, center_vertical, clip_horizontal, clip_vertical, end, fill, fill_horizontal,
|
||||
# fill_vertical, left, right, start, or top.
|
||||
#android_gravity: center
|
||||
#
|
||||
# ios_content_mode can be one of the following iOS UIView.ContentMode (see
|
||||
# https://developer.apple.com/documentation/uikit/uiview/contentmode): scaleToFill,
|
||||
# scaleAspectFit, scaleAspectFill, center, top, bottom, left, right, topLeft, topRight,
|
||||
# bottomLeft, or bottomRight.
|
||||
#ios_content_mode: center
|
||||
#
|
||||
# web_image_mode can be one of the following modes: center, contain, stretch, and cover.
|
||||
#web_image_mode: center
|
||||
|
||||
# The screen orientation can be set in Android with the android_screen_orientation parameter.
|
||||
# Valid parameters can be found here:
|
||||
# https://developer.android.com/guide/topics/manifest/activity-element#screen
|
||||
#android_screen_orientation: sensorLandscape
|
||||
|
||||
# To hide the notification bar, use the fullscreen parameter. Has no effect in web since web
|
||||
# has no notification bar. Defaults to false.
|
||||
# NOTE: Unlike Android, iOS will not automatically show the notification bar when the app loads.
|
||||
# To show the notification bar, add the following code to your Flutter app:
|
||||
# WidgetsFlutterBinding.ensureInitialized();
|
||||
# SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]);
|
||||
#fullscreen: true
|
||||
|
||||
# If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
|
||||
# with the info_plist_files parameter. Remove only the # characters in the three lines below,
|
||||
# do not remove any spaces:
|
||||
#info_plist_files:
|
||||
# - 'ios/Runner/Info-Debug.plist'
|
||||
# - 'ios/Runner/Info-Release.plist'
|
||||
@@ -7,7 +7,8 @@ void main() async {
|
||||
await ImmichTestHelper.initialize();
|
||||
|
||||
group("Login input validation test", () {
|
||||
immichWidgetTest("Test leading/trailing whitespace", (tester, helper) async {
|
||||
immichWidgetTest("Test leading/trailing whitespace",
|
||||
(tester, helper) async {
|
||||
await helper.loginHelper.waitForLoginScreen();
|
||||
await helper.loginHelper.acknowledgeNewServerVersion();
|
||||
|
||||
@@ -17,15 +18,21 @@ void main() async {
|
||||
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
expect(find.text("login_form_err_leading_whitespace".tr()), findsOneWidget);
|
||||
expect(
|
||||
find.text("login_form_err_leading_whitespace".tr()),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
await helper.loginHelper.enterCredentials(
|
||||
email: "demo@immich.app ",
|
||||
email: "demo@immich.app ",
|
||||
);
|
||||
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
expect(find.text("login_form_err_trailing_whitespace".tr()), findsOneWidget);
|
||||
expect(
|
||||
find.text("login_form_err_trailing_whitespace".tr()),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
immichWidgetTest("Test invalid email", (tester, helper) async {
|
||||
@@ -33,13 +40,12 @@ void main() async {
|
||||
await helper.loginHelper.acknowledgeNewServerVersion();
|
||||
|
||||
await helper.loginHelper.enterCredentials(
|
||||
email: "demo.immich.app",
|
||||
email: "demo.immich.app",
|
||||
);
|
||||
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
expect(find.text("login_form_err_invalid_email".tr()), findsOneWidget);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:immich_mobile/shared/models/store.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:immich_mobile/main.dart' as app;
|
||||
@@ -34,8 +36,12 @@ class ImmichTestHelper {
|
||||
// Clear all data from Hive
|
||||
await Hive.deleteFromDisk();
|
||||
await app.openBoxes();
|
||||
// Clear all data from Isar (reuse existing instance if available)
|
||||
final db = Isar.getInstance() ?? await app.loadDb();
|
||||
await Store.clear();
|
||||
await db.writeTxn(() => db.clear());
|
||||
// Load main Widget
|
||||
await tester.pumpWidget(app.getMainWidget());
|
||||
await tester.pumpWidget(app.getMainWidget(db));
|
||||
// Post run tasks
|
||||
await tester.pumpAndSettle();
|
||||
await EasyLocalization.ensureInitialized();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
platform :ios, '11.0'
|
||||
# platform :ios, '11.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
@@ -34,19 +34,8 @@ target 'Runner' do
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
# post_install do |installer|
|
||||
# installer.pods_project.targets.each do |target|
|
||||
# flutter_additional_ios_build_settings(target)
|
||||
# end
|
||||
# end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
|
||||
config.build_settings['ENABLE_BITCODE'] = 'YES'
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
|
||||
end
|
||||
end
|
||||
end
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,7 @@
|
||||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- flutter_native_splash (0.0.1):
|
||||
- Flutter
|
||||
- flutter_udid (0.0.1):
|
||||
- Flutter
|
||||
- SAMKeychain
|
||||
@@ -15,18 +17,22 @@ PODS:
|
||||
- Flutter
|
||||
- integration_test (0.0.1):
|
||||
- Flutter
|
||||
- isar_flutter_libs (1.0.0):
|
||||
- Flutter
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- path_provider_ios (0.0.1):
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- photo_manager (2.0.0):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- SAMKeychain (1.5.3)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_ios (0.0.1):
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- sqflite (0.0.2):
|
||||
- Flutter
|
||||
- FMDB (>= 2.7.5)
|
||||
@@ -40,16 +46,18 @@ PODS:
|
||||
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
- flutter_udid (from `.symlinks/plugins/flutter_udid/ios`)
|
||||
- flutter_web_auth (from `.symlinks/plugins/flutter_web_auth/ios`)
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
||||
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
||||
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`)
|
||||
@@ -64,6 +72,8 @@ SPEC REPOS:
|
||||
EXTERNAL SOURCES:
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_native_splash:
|
||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||
flutter_udid:
|
||||
:path: ".symlinks/plugins/flutter_udid/ios"
|
||||
flutter_web_auth:
|
||||
@@ -74,16 +84,18 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
integration_test:
|
||||
:path: ".symlinks/plugins/integration_test/ios"
|
||||
isar_flutter_libs:
|
||||
:path: ".symlinks/plugins/isar_flutter_libs/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
path_provider_ios:
|
||||
:path: ".symlinks/plugins/path_provider_ios/ios"
|
||||
path_provider_foundation:
|
||||
:path: ".symlinks/plugins/path_provider_foundation/ios"
|
||||
photo_manager:
|
||||
:path: ".symlinks/plugins/photo_manager/ios"
|
||||
share_plus:
|
||||
:path: ".symlinks/plugins/share_plus/ios"
|
||||
shared_preferences_ios:
|
||||
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
url_launcher_ios:
|
||||
@@ -95,24 +107,26 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||
flutter_udid: 0848809dbed4c055175747ae6a45a8b4f6771e1c
|
||||
flutter_web_auth: c25208760459cec375a3c39f6a8759165ca0fa4d
|
||||
fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037
|
||||
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
|
||||
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
|
||||
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
|
||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
||||
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
|
||||
photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604
|
||||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
||||
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
|
||||
shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
|
||||
url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2
|
||||
video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff
|
||||
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
||||
|
||||
PODFILE CHECKSUM: 05c3056158482c567a3e0cdab1351ceeee238a07
|
||||
PODFILE CHECKSUM: c798208781ca5116c4a3d5927d689946791f0189
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 51;
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -201,6 +201,7 @@
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
@@ -237,6 +238,7 @@
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
@@ -341,7 +343,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
NEW_SETTING = "";
|
||||
SDKROOT = iphoneos;
|
||||
@@ -360,7 +362,8 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 82;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)";
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -425,7 +428,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
NEW_SETTING = "";
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@@ -475,7 +478,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
NEW_SETTING = "";
|
||||
SDKROOT = iphoneos;
|
||||
@@ -495,7 +498,8 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 82;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)";
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -522,7 +526,8 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 82;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)";
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
|
||||
22
mobile/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "background.png",
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "darkbackground.png",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
mobile/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png
vendored
Normal file
|
After Width: | Height: | Size: 70 B |
BIN
mobile/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png
vendored
Normal file
|
After Width: | Height: | Size: 70 B |
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 68 B After Width: | Height: | Size: 27 KiB |
@@ -16,13 +16,19 @@
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" image="LaunchBackground" translatesAutoresizingMaskIntoConstraints="NO" id="tWc-Dq-wcI"/>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"></imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="3T2-ad-Qdv"/>
|
||||
<constraint firstItem="tWc-Dq-wcI" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="RPx-PI-7Xg"/>
|
||||
<constraint firstItem="tWc-Dq-wcI" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="SdS-ul-q2q"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tWc-Dq-wcI" secondAttribute="trailing" id="Swv-Gf-Rwn"/>
|
||||
<constraint firstAttribute="trailing" secondItem="YRO-k0-Ey4" secondAttribute="trailing" id="TQA-XW-tRk"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="duK-uY-Gun"/>
|
||||
<constraint firstItem="tWc-Dq-wcI" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="kV7-tw-vXt"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="xPn-NY-SIU"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
@@ -32,6 +38,7 @@
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
<image name="LaunchImage" width="320" height="320"/>
|
||||
<image name="LaunchBackground" width="1" height="1"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -1,105 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Immich</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>immich_mobile</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.43.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>82</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true />
|
||||
<key>MGLMapboxMetricsEnabledSettingShownInApp</key>
|
||||
<true />
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true />
|
||||
</dict>
|
||||
<key>NSLocationAlwaysUsageDescription</key>
|
||||
<string>Enable location setting to show position of assets on map</string>
|
||||
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>Enable location setting to show position of assets on map</string>
|
||||
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We need to access the camera to let you take beautiful video using this app</string>
|
||||
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>We need to access the microphone to let you take beautiful video using this app</string>
|
||||
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true />
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true />
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false />
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true />
|
||||
|
||||
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>https</string>
|
||||
</array>
|
||||
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>cs</string>
|
||||
<string>da</string>
|
||||
<string>de</string>
|
||||
<string>en</string>
|
||||
<string>es</string>
|
||||
<string>fi</string>
|
||||
<string>fr</string>
|
||||
<string>it</string>
|
||||
<string>ja</string>
|
||||
<string>ko</string>
|
||||
<string>nl</string>
|
||||
<string>pl</string>
|
||||
<string>pt</string>
|
||||
<string>ru</string>
|
||||
<string>sk</string>
|
||||
<string>zh</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Immich</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>immich_mobile</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>MGLMapboxMetricsEnabledSettingShownInApp</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSLocationAlwaysUsageDescription</key>
|
||||
<string>Enable location setting to show position of assets on map</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>Enable location setting to show position of assets on map</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We need to access the camera to let you take beautiful video using this app</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>We need to access the microphone to let you take beautiful video using this app</string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>https</string>
|
||||
</array>
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>cs</string>
|
||||
<string>da</string>
|
||||
<string>de</string>
|
||||
<string>en</string>
|
||||
<string>es</string>
|
||||
<string>fi</string>
|
||||
<string>fr</string>
|
||||
<string>it</string>
|
||||
<string>ja</string>
|
||||
<string>ko</string>
|
||||
<string>nl</string>
|
||||
<string>pl</string>
|
||||
<string>pt</string>
|
||||
<string>ru</string>
|
||||
<string>sk</string>
|
||||
<string>zh</string>
|
||||
</array>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -19,7 +19,7 @@ platform :ios do
|
||||
desc "iOS Beta"
|
||||
lane :beta do
|
||||
increment_version_number(
|
||||
version_number: "1.44.0"
|
||||
version_number: "1.47.1"
|
||||
)
|
||||
increment_build_number(
|
||||
build_number: latest_testflight_build_number + 1,
|
||||
|
||||
@@ -5,32 +5,32 @@
|
||||
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000396">
|
||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000283">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="2.478301">
|
||||
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="2.755864">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="3.846552">
|
||||
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="7.319767">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="2.367554">
|
||||
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="1.376562">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="4: build_app" time="75.618447">
|
||||
<testcase classname="fastlane.lanes" name="4: build_app" time="105.396514">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="47.502114">
|
||||
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="86.092896">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ const String deviceIdKey = 'immichBoxDeviceIdKey'; // Key 2
|
||||
const String isLoggedInKey = 'immichIsLoggedInKey'; // Key 3
|
||||
const String serverEndpointKey = 'immichBoxServerEndpoint'; // Key 4
|
||||
const String assetEtagKey = 'immichAssetEtagKey'; // Key 5
|
||||
const String userIdKey = 'immichUserIdKey'; // Key 6
|
||||
|
||||
// Login Info
|
||||
const String hiveLoginInfoBox = "immichLoginInfoBox"; // Box
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:io';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -16,8 +17,10 @@ import 'package:immich_mobile/modules/login/providers/authentication.provider.da
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/routing/tab_navigation_observer.dart';
|
||||
import 'package:immich_mobile/shared/models/immich_logger_message.model.dart';
|
||||
import 'package:immich_mobile/shared/models/store.dart';
|
||||
import 'package:immich_mobile/shared/providers/app_state.provider.dart';
|
||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
||||
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||
import 'package:immich_mobile/shared/providers/release_info.provider.dart';
|
||||
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
|
||||
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
||||
@@ -25,11 +28,16 @@ import 'package:immich_mobile/shared/services/immich_logger.service.dart';
|
||||
import 'package:immich_mobile/shared/views/immich_loading_overlay.dart';
|
||||
import 'package:immich_mobile/shared/views/version_announcement_overlay.dart';
|
||||
import 'package:immich_mobile/utils/immich_app_theme.dart';
|
||||
import 'package:immich_mobile/utils/migration.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'constants/hive_box.dart';
|
||||
|
||||
void main() async {
|
||||
await initApp();
|
||||
runApp(getMainWidget());
|
||||
final db = await loadDb();
|
||||
await migrateHiveToStoreIfNecessary();
|
||||
runApp(getMainWidget(db));
|
||||
}
|
||||
|
||||
Future<void> openBoxes() async {
|
||||
@@ -69,13 +77,27 @@ Future<void> initApp() async {
|
||||
ImmichLogger().init();
|
||||
}
|
||||
|
||||
Widget getMainWidget() {
|
||||
Future<Isar> loadDb() async {
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
Isar db = await Isar.open(
|
||||
[StoreValueSchema],
|
||||
directory: dir.path,
|
||||
maxSizeMiB: 256,
|
||||
);
|
||||
Store.init(db);
|
||||
return db;
|
||||
}
|
||||
|
||||
Widget getMainWidget(Isar db) {
|
||||
return EasyLocalization(
|
||||
supportedLocales: locales,
|
||||
path: translationsPath,
|
||||
useFallbackTranslations: true,
|
||||
fallbackLocale: locales.first,
|
||||
child: const ProviderScope(child: ImmichApp()),
|
||||
child: ProviderScope(
|
||||
overrides: [dbProvider.overrideWithValue(db)],
|
||||
child: const ImmichApp(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -155,6 +177,8 @@ class ImmichAppState extends ConsumerState<ImmichApp>
|
||||
var router = ref.watch(appRouterProvider);
|
||||
ref.watch(releaseInfoProvider.notifier).checkGithubReleaseInfo();
|
||||
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
|
||||
return MaterialApp(
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
|
||||
@@ -2,24 +2,26 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
|
||||
import 'package:immich_mobile/modules/album/services/album_cache.service.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
|
||||
class AlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
class AlbumNotifier extends StateNotifier<List<Album>> {
|
||||
AlbumNotifier(this._albumService, this._albumCacheService) : super([]);
|
||||
final AlbumService _albumService;
|
||||
final AlbumCacheService _albumCacheService;
|
||||
|
||||
_cacheState() {
|
||||
void _cacheState() {
|
||||
_albumCacheService.put(state);
|
||||
}
|
||||
|
||||
getAllAlbums() async {
|
||||
Future<void> getAllAlbums() async {
|
||||
if (await _albumCacheService.isValid() && state.isEmpty) {
|
||||
state = await _albumCacheService.get();
|
||||
final albums = await _albumCacheService.get();
|
||||
if (albums != null) {
|
||||
state = albums;
|
||||
}
|
||||
}
|
||||
|
||||
List<AlbumResponseDto>? albums =
|
||||
await _albumService.getAlbums(isShared: false);
|
||||
final albums = await _albumService.getAlbums(isShared: false);
|
||||
|
||||
if (albums != null) {
|
||||
state = albums;
|
||||
@@ -27,17 +29,16 @@ class AlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
}
|
||||
}
|
||||
|
||||
deleteAlbum(String albumId) {
|
||||
state = state.where((album) => album.id != albumId).toList();
|
||||
void deleteAlbum(Album album) {
|
||||
state = state.where((a) => a.id != album.id).toList();
|
||||
_cacheState();
|
||||
}
|
||||
|
||||
Future<AlbumResponseDto?> createAlbum(
|
||||
Future<Album?> createAlbum(
|
||||
String albumTitle,
|
||||
Set<Asset> assets,
|
||||
) async {
|
||||
AlbumResponseDto? album =
|
||||
await _albumService.createAlbum(albumTitle, assets, []);
|
||||
Album? album = await _albumService.createAlbum(albumTitle, assets, []);
|
||||
|
||||
if (album != null) {
|
||||
state = [...state, album];
|
||||
@@ -49,8 +50,7 @@ class AlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
}
|
||||
}
|
||||
|
||||
final albumProvider =
|
||||
StateNotifierProvider<AlbumNotifier, List<AlbumResponseDto>>((ref) {
|
||||
final albumProvider = StateNotifierProvider<AlbumNotifier, List<Album>>((ref) {
|
||||
return AlbumNotifier(
|
||||
ref.watch(albumServiceProvider),
|
||||
ref.watch(albumCacheServiceProvider),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/album/models/album_viewer_page_state.model.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
|
||||
class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
|
||||
AlbumViewerNotifier(this.ref)
|
||||
@@ -30,14 +31,12 @@ class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
|
||||
}
|
||||
|
||||
Future<bool> changeAlbumTitle(
|
||||
String albumId,
|
||||
String ownerId,
|
||||
Album album,
|
||||
String newAlbumTitle,
|
||||
) async {
|
||||
AlbumService service = ref.watch(albumServiceProvider);
|
||||
|
||||
bool isSuccess =
|
||||
await service.changeTitleAlbum(albumId, ownerId, newAlbumTitle);
|
||||
bool isSuccess = await service.changeTitleAlbum(album, newAlbumTitle);
|
||||
|
||||
if (isSuccess) {
|
||||
state = state.copyWith(editTitleText: "", isEditAlbum: false);
|
||||
|
||||
@@ -2,30 +2,31 @@ import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
|
||||
import 'package:immich_mobile/modules/album/services/album_cache.service.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:immich_mobile/shared/models/user.dart';
|
||||
|
||||
class SharedAlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
class SharedAlbumNotifier extends StateNotifier<List<Album>> {
|
||||
SharedAlbumNotifier(this._albumService, this._sharedAlbumCacheService)
|
||||
: super([]);
|
||||
|
||||
final AlbumService _albumService;
|
||||
final SharedAlbumCacheService _sharedAlbumCacheService;
|
||||
|
||||
_cacheState() {
|
||||
void _cacheState() {
|
||||
_sharedAlbumCacheService.put(state);
|
||||
}
|
||||
|
||||
Future<AlbumResponseDto?> createSharedAlbum(
|
||||
Future<Album?> createSharedAlbum(
|
||||
String albumName,
|
||||
Set<Asset> assets,
|
||||
List<String> sharedUserIds,
|
||||
Iterable<Asset> assets,
|
||||
Iterable<User> sharedUsers,
|
||||
) async {
|
||||
try {
|
||||
var newAlbum = await _albumService.createAlbum(
|
||||
albumName,
|
||||
assets,
|
||||
sharedUserIds,
|
||||
sharedUsers,
|
||||
);
|
||||
|
||||
if (newAlbum != null) {
|
||||
@@ -41,13 +42,15 @@ class SharedAlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
}
|
||||
}
|
||||
|
||||
getAllSharedAlbums() async {
|
||||
Future<void> getAllSharedAlbums() async {
|
||||
if (await _sharedAlbumCacheService.isValid() && state.isEmpty) {
|
||||
state = await _sharedAlbumCacheService.get();
|
||||
final albums = await _sharedAlbumCacheService.get();
|
||||
if (albums != null) {
|
||||
state = albums;
|
||||
}
|
||||
}
|
||||
|
||||
List<AlbumResponseDto>? sharedAlbums =
|
||||
await _albumService.getAlbums(isShared: true);
|
||||
List<Album>? sharedAlbums = await _albumService.getAlbums(isShared: true);
|
||||
|
||||
if (sharedAlbums != null) {
|
||||
state = sharedAlbums;
|
||||
@@ -55,16 +58,16 @@ class SharedAlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
}
|
||||
}
|
||||
|
||||
deleteAlbum(String albumId) async {
|
||||
state = state.where((album) => album.id != albumId).toList();
|
||||
void deleteAlbum(Album album) {
|
||||
state = state.where((a) => a.id != album.id).toList();
|
||||
_cacheState();
|
||||
}
|
||||
|
||||
Future<bool> leaveAlbum(String albumId) async {
|
||||
var res = await _albumService.leaveAlbum(albumId);
|
||||
Future<bool> leaveAlbum(Album album) async {
|
||||
var res = await _albumService.leaveAlbum(album);
|
||||
|
||||
if (res) {
|
||||
state = state.where((album) => album.id != albumId).toList();
|
||||
state = state.where((a) => a.id != album.id).toList();
|
||||
_cacheState();
|
||||
return true;
|
||||
} else {
|
||||
@@ -73,10 +76,10 @@ class SharedAlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
}
|
||||
|
||||
Future<bool> removeAssetFromAlbum(
|
||||
String albumId,
|
||||
List<String> assetIds,
|
||||
Album album,
|
||||
Iterable<Asset> assets,
|
||||
) async {
|
||||
var res = await _albumService.removeAssetFromAlbum(albumId, assetIds);
|
||||
var res = await _albumService.removeAssetFromAlbum(album, assets);
|
||||
|
||||
if (res) {
|
||||
return true;
|
||||
@@ -87,15 +90,15 @@ class SharedAlbumNotifier extends StateNotifier<List<AlbumResponseDto>> {
|
||||
}
|
||||
|
||||
final sharedAlbumProvider =
|
||||
StateNotifierProvider<SharedAlbumNotifier, List<AlbumResponseDto>>((ref) {
|
||||
StateNotifierProvider<SharedAlbumNotifier, List<Album>>((ref) {
|
||||
return SharedAlbumNotifier(
|
||||
ref.watch(albumServiceProvider),
|
||||
ref.watch(sharedAlbumCacheServiceProvider),
|
||||
);
|
||||
});
|
||||
|
||||
final sharedAlbumDetailProvider = FutureProvider.autoDispose
|
||||
.family<AlbumResponseDto?, String>((ref, albumId) async {
|
||||
final sharedAlbumDetailProvider =
|
||||
FutureProvider.autoDispose.family<Album?, String>((ref, albumId) async {
|
||||
final AlbumService sharedAlbumService = ref.watch(albumServiceProvider);
|
||||
|
||||
return await sharedAlbumService.getAlbumDetail(albumId);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/shared/models/user.dart';
|
||||
import 'package:immich_mobile/shared/services/user.service.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
final suggestedSharedUsersProvider =
|
||||
FutureProvider.autoDispose<List<UserResponseDto>>((ref) async {
|
||||
FutureProvider.autoDispose<List<User>>((ref) async {
|
||||
UserService userService = ref.watch(userServiceProvider);
|
||||
|
||||
return await userService.getAllUsersInfo(isAll: false) ?? [];
|
||||
return await userService.getAllUsers(isAll: false) ?? [];
|
||||
});
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:immich_mobile/shared/models/user.dart';
|
||||
import 'package:immich_mobile/shared/providers/api.provider.dart';
|
||||
import 'package:immich_mobile/shared/services/api.service.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
@@ -18,29 +20,31 @@ class AlbumService {
|
||||
|
||||
AlbumService(this._apiService);
|
||||
|
||||
Future<List<AlbumResponseDto>?> getAlbums({required bool isShared}) async {
|
||||
Future<List<Album>?> getAlbums({required bool isShared}) async {
|
||||
try {
|
||||
return await _apiService.albumApi
|
||||
final dto = await _apiService.albumApi
|
||||
.getAllAlbums(shared: isShared ? isShared : null);
|
||||
return dto?.map(Album.remote).toList();
|
||||
} catch (e) {
|
||||
debugPrint("Error getAllSharedAlbum ${e.toString()}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<AlbumResponseDto?> createAlbum(
|
||||
Future<Album?> createAlbum(
|
||||
String albumName,
|
||||
Iterable<Asset> assets,
|
||||
List<String> sharedUserIds,
|
||||
) async {
|
||||
Iterable<Asset> assets, [
|
||||
Iterable<User> sharedUsers = const [],
|
||||
]) async {
|
||||
try {
|
||||
return await _apiService.albumApi.createAlbum(
|
||||
final dto = await _apiService.albumApi.createAlbum(
|
||||
CreateAlbumDto(
|
||||
albumName: albumName,
|
||||
assetIds: assets.map((asset) => asset.id).toList(),
|
||||
sharedWithUserIds: sharedUserIds,
|
||||
assetIds: assets.map((asset) => asset.remoteId!).toList(),
|
||||
sharedWithUserIds: sharedUsers.map((e) => e.id).toList(),
|
||||
),
|
||||
);
|
||||
return dto != null ? Album.remote(dto) : null;
|
||||
} catch (e) {
|
||||
debugPrint("Error createSharedAlbum ${e.toString()}");
|
||||
return null;
|
||||
@@ -50,14 +54,14 @@ class AlbumService {
|
||||
/*
|
||||
* Creates names like Untitled, Untitled (1), Untitled (2), ...
|
||||
*/
|
||||
String _getNextAlbumName(List<AlbumResponseDto>? albums) {
|
||||
String _getNextAlbumName(List<Album>? albums) {
|
||||
const baseName = "Untitled";
|
||||
|
||||
if (albums != null) {
|
||||
for (int round = 0; round < albums.length; round++) {
|
||||
final proposedName = "$baseName${round == 0 ? "" : " ($round)"}";
|
||||
|
||||
if (albums.where((a) => a.albumName == proposedName).isEmpty) {
|
||||
if (albums.where((a) => a.name == proposedName).isEmpty) {
|
||||
return proposedName;
|
||||
}
|
||||
}
|
||||
@@ -65,7 +69,7 @@ class AlbumService {
|
||||
return baseName;
|
||||
}
|
||||
|
||||
Future<AlbumResponseDto?> createAlbumWithGeneratedName(
|
||||
Future<Album?> createAlbumWithGeneratedName(
|
||||
Iterable<Asset> assets,
|
||||
) async {
|
||||
return createAlbum(
|
||||
@@ -75,9 +79,10 @@ class AlbumService {
|
||||
);
|
||||
}
|
||||
|
||||
Future<AlbumResponseDto?> getAlbumDetail(String albumId) async {
|
||||
Future<Album?> getAlbumDetail(String albumId) async {
|
||||
try {
|
||||
return await _apiService.albumApi.getAlbumInfo(albumId);
|
||||
final dto = await _apiService.albumApi.getAlbumInfo(albumId);
|
||||
return dto != null ? Album.remote(dto) : null;
|
||||
} catch (e) {
|
||||
debugPrint('Error [getAlbumDetail] ${e.toString()}');
|
||||
return null;
|
||||
@@ -86,12 +91,12 @@ class AlbumService {
|
||||
|
||||
Future<AddAssetsResponseDto?> addAdditionalAssetToAlbum(
|
||||
Iterable<Asset> assets,
|
||||
String albumId,
|
||||
Album album,
|
||||
) async {
|
||||
try {
|
||||
var result = await _apiService.albumApi.addAssetsToAlbum(
|
||||
albumId,
|
||||
AddAssetsDto(assetIds: assets.map((asset) => asset.id).toList()),
|
||||
album.remoteId!,
|
||||
AddAssetsDto(assetIds: assets.map((asset) => asset.remoteId!).toList()),
|
||||
);
|
||||
return result;
|
||||
} catch (e) {
|
||||
@@ -102,11 +107,11 @@ class AlbumService {
|
||||
|
||||
Future<bool> addAdditionalUserToAlbum(
|
||||
List<String> sharedUserIds,
|
||||
String albumId,
|
||||
Album album,
|
||||
) async {
|
||||
try {
|
||||
var result = await _apiService.albumApi.addUsersToAlbum(
|
||||
albumId,
|
||||
album.remoteId!,
|
||||
AddUsersDto(sharedUserIds: sharedUserIds),
|
||||
);
|
||||
|
||||
@@ -117,9 +122,9 @@ class AlbumService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteAlbum(String albumId) async {
|
||||
Future<bool> deleteAlbum(Album album) async {
|
||||
try {
|
||||
await _apiService.albumApi.deleteAlbum(albumId);
|
||||
await _apiService.albumApi.deleteAlbum(album.remoteId!);
|
||||
return true;
|
||||
} catch (e) {
|
||||
debugPrint("Error deleteAlbum ${e.toString()}");
|
||||
@@ -127,10 +132,9 @@ class AlbumService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> leaveAlbum(String albumId) async {
|
||||
Future<bool> leaveAlbum(Album album) async {
|
||||
try {
|
||||
await _apiService.albumApi.removeUserFromAlbum(albumId, "me");
|
||||
|
||||
await _apiService.albumApi.removeUserFromAlbum(album.remoteId!, "me");
|
||||
return true;
|
||||
} catch (e) {
|
||||
debugPrint("Error deleteAlbum ${e.toString()}");
|
||||
@@ -139,13 +143,15 @@ class AlbumService {
|
||||
}
|
||||
|
||||
Future<bool> removeAssetFromAlbum(
|
||||
String albumId,
|
||||
List<String> assetIds,
|
||||
Album album,
|
||||
Iterable<Asset> assets,
|
||||
) async {
|
||||
try {
|
||||
await _apiService.albumApi.removeAssetFromAlbum(
|
||||
albumId,
|
||||
RemoveAssetsDto(assetIds: assetIds),
|
||||
album.remoteId!,
|
||||
RemoveAssetsDto(
|
||||
assetIds: assets.map((e) => e.remoteId!).toList(growable: false),
|
||||
),
|
||||
);
|
||||
|
||||
return true;
|
||||
@@ -156,17 +162,17 @@ class AlbumService {
|
||||
}
|
||||
|
||||
Future<bool> changeTitleAlbum(
|
||||
String albumId,
|
||||
String ownerId,
|
||||
Album album,
|
||||
String newAlbumTitle,
|
||||
) async {
|
||||
try {
|
||||
await _apiService.albumApi.updateAlbumInfo(
|
||||
albumId,
|
||||
album.remoteId!,
|
||||
UpdateAlbumDto(
|
||||
albumName: newAlbumTitle,
|
||||
),
|
||||
);
|
||||
album.name = newAlbumTitle;
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,32 +1,30 @@
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/shared/services/json_cache.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
class BaseAlbumCacheService extends JsonCache<List<AlbumResponseDto>> {
|
||||
class BaseAlbumCacheService extends JsonCache<List<Album>> {
|
||||
BaseAlbumCacheService(super.cacheFileName);
|
||||
|
||||
@override
|
||||
void put(List<AlbumResponseDto> data) {
|
||||
void put(List<Album> data) {
|
||||
putRawData(data.map((e) => e.toJson()).toList());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<AlbumResponseDto>> get() async {
|
||||
Future<List<Album>?> get() async {
|
||||
try {
|
||||
final mapList = await readRawData() as List<dynamic>;
|
||||
|
||||
final responseData = mapList
|
||||
.map((e) => AlbumResponseDto.fromJson(e))
|
||||
.whereNotNull()
|
||||
.toList();
|
||||
final responseData =
|
||||
mapList.map((e) => Album.fromJson(e)).whereNotNull().toList();
|
||||
|
||||
return responseData;
|
||||
} catch (e) {
|
||||
await invalidate();
|
||||
debugPrint(e.toString());
|
||||
return [];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,10 +38,9 @@ class SharedAlbumCacheService extends BaseAlbumCacheService {
|
||||
}
|
||||
|
||||
final albumCacheServiceProvider = Provider(
|
||||
(ref) => AlbumCacheService(),
|
||||
(ref) => AlbumCacheService(),
|
||||
);
|
||||
|
||||
final sharedAlbumCacheServiceProvider = Provider(
|
||||
(ref) => SharedAlbumCacheService(),
|
||||
(ref) => SharedAlbumCacheService(),
|
||||
);
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart
|
||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
|
||||
import 'package:immich_mobile/modules/album/ui/add_to_album_sliverlist.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:immich_mobile/shared/ui/drag_sheet.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_toast.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
class AddToAlbumBottomSheet extends HookConsumerWidget {
|
||||
/// The asset to add to an album
|
||||
@@ -39,22 +39,22 @@ class AddToAlbumBottomSheet extends HookConsumerWidget {
|
||||
[],
|
||||
);
|
||||
|
||||
void addToAlbum(AlbumResponseDto album) async {
|
||||
void addToAlbum(Album album) async {
|
||||
final result = await albumService.addAdditionalAssetToAlbum(
|
||||
assets,
|
||||
album.id,
|
||||
album,
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
if (result.alreadyInAlbum.isNotEmpty) {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: 'Already in ${album.albumName}',
|
||||
msg: 'Already in ${album.name}',
|
||||
);
|
||||
} else {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: 'Added to ${album.albumName}',
|
||||
msg: 'Added to ${album.name}',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class AddToAlbumBottomSheet extends HookConsumerWidget {
|
||||
children: [
|
||||
Text(
|
||||
'Add to album',
|
||||
style: Theme.of(context).textTheme.headline2,
|
||||
style: Theme.of(context).textTheme.displayMedium,
|
||||
),
|
||||
TextButton.icon(
|
||||
icon: const Icon(Icons.add),
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/album/ui/album_thumbnail_listtile.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
|
||||
class AddToAlbumSliverList extends HookConsumerWidget {
|
||||
|
||||
/// The asset to add to an album
|
||||
final List<AlbumResponseDto> albums;
|
||||
final List<AlbumResponseDto> sharedAlbums;
|
||||
final void Function(AlbumResponseDto) onAddToAlbum;
|
||||
final List<Album> albums;
|
||||
final List<Album> sharedAlbums;
|
||||
final void Function(Album) onAddToAlbum;
|
||||
|
||||
const AddToAlbumSliverList({
|
||||
Key? key,
|
||||
@@ -21,36 +20,36 @@ class AddToAlbumSliverList extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
childCount: albums.length + (sharedAlbums.isEmpty ? 0 : 1),
|
||||
(context, index) {
|
||||
// Build shared expander
|
||||
if (index == 0 && sharedAlbums.isNotEmpty) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: ExpansionTile(
|
||||
title: const Text('Shared'),
|
||||
tilePadding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
leading: const Icon(Icons.group),
|
||||
children: sharedAlbums.map((album) =>
|
||||
AlbumThumbnailListTile(
|
||||
childCount: albums.length + (sharedAlbums.isEmpty ? 0 : 1),
|
||||
(context, index) {
|
||||
// Build shared expander
|
||||
if (index == 0 && sharedAlbums.isNotEmpty) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: ExpansionTile(
|
||||
title: const Text('Shared'),
|
||||
tilePadding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
leading: const Icon(Icons.group),
|
||||
children: sharedAlbums
|
||||
.map(
|
||||
(album) => AlbumThumbnailListTile(
|
||||
album: album,
|
||||
onTap: () => onAddToAlbum(album),
|
||||
),
|
||||
).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Build albums list
|
||||
final offset = index - (sharedAlbums.isNotEmpty ? 1 : 0);
|
||||
final album = albums[offset];
|
||||
return AlbumThumbnailListTile(
|
||||
album: album,
|
||||
onTap: () => onAddToAlbum(album),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
|
||||
// Build albums list
|
||||
final offset = index - (sharedAlbums.isNotEmpty ? 1 : 0);
|
||||
final album = albums[offset];
|
||||
return AlbumThumbnailListTile(
|
||||
album: album,
|
||||
onTap: () => onAddToAlbum(album),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,107 +1,121 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:immich_mobile/constants/hive_box.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
class AlbumThumbnailCard extends StatelessWidget {
|
||||
final Function()? onTap;
|
||||
|
||||
const AlbumThumbnailCard({
|
||||
Key? key,
|
||||
required this.album,
|
||||
this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
final AlbumResponseDto album;
|
||||
final Album album;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var box = Hive.box(userInfoBox);
|
||||
var cardSize = MediaQuery.of(context).size.width / 2 - 18;
|
||||
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
var cardSize = constraints.maxWidth;
|
||||
|
||||
buildEmptyThumbnail() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isDarkMode ? Colors.grey[800] : Colors.grey[200],
|
||||
),
|
||||
child: SizedBox(
|
||||
height: cardSize,
|
||||
width: cardSize,
|
||||
child: const Center(
|
||||
child: Icon(Icons.no_photography),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
buildAlbumThumbnail() {
|
||||
return CachedNetworkImage(
|
||||
width: cardSize,
|
||||
height: cardSize,
|
||||
fit: BoxFit.cover,
|
||||
fadeInDuration: const Duration(milliseconds: 200),
|
||||
imageUrl: getAlbumThumbnailUrl(
|
||||
album,
|
||||
type: ThumbnailFormat.JPEG,
|
||||
),
|
||||
httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
|
||||
cacheKey: getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG),
|
||||
);
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
AutoRouter.of(context).push(AlbumViewerRoute(albumId: album.id));
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 32.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: album.albumThumbnailAssetId == null
|
||||
? buildEmptyThumbnail()
|
||||
: buildAlbumThumbnail(),
|
||||
buildEmptyThumbnail() {
|
||||
return Container(
|
||||
height: cardSize,
|
||||
width: cardSize,
|
||||
decoration: BoxDecoration(
|
||||
color: isDarkMode ? Colors.grey[800] : Colors.grey[200],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: SizedBox(
|
||||
width: cardSize,
|
||||
child: Text(
|
||||
album.albumName,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.no_photography,
|
||||
size: cardSize * .15,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
album.assetCount == 1
|
||||
? 'album_thumbnail_card_item'
|
||||
: 'album_thumbnail_card_items',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
).tr(args: ['${album.assetCount}']),
|
||||
if (album.shared)
|
||||
const Text(
|
||||
'album_thumbnail_card_shared',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
);
|
||||
}
|
||||
|
||||
buildAlbumThumbnail() {
|
||||
return CachedNetworkImage(
|
||||
width: cardSize,
|
||||
height: cardSize,
|
||||
fit: BoxFit.cover,
|
||||
fadeInDuration: const Duration(milliseconds: 200),
|
||||
imageUrl: getAlbumThumbnailUrl(
|
||||
album,
|
||||
type: ThumbnailFormat.JPEG,
|
||||
),
|
||||
httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
|
||||
cacheKey:
|
||||
getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG),
|
||||
);
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Flex(
|
||||
direction: Axis.vertical,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: cardSize,
|
||||
height: cardSize,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: album.albumThumbnailAssetId == null
|
||||
? buildEmptyThumbnail()
|
||||
: buildAlbumThumbnail(),
|
||||
),
|
||||
),
|
||||
).tr()
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: SizedBox(
|
||||
width: cardSize,
|
||||
child: Text(
|
||||
album.name,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
album.assetCount == 1
|
||||
? 'album_thumbnail_card_item'
|
||||
: 'album_thumbnail_card_items',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
).tr(args: ['${album.assetCount}']),
|
||||
if (album.shared)
|
||||
const Text(
|
||||
'album_thumbnail_card_shared',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
).tr()
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:immich_mobile/constants/hive_box.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
@@ -15,7 +16,7 @@ class AlbumThumbnailListTile extends StatelessWidget {
|
||||
this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
final AlbumResponseDto album;
|
||||
final Album album;
|
||||
final void Function()? onTap;
|
||||
|
||||
@override
|
||||
@@ -80,7 +81,7 @@ class AlbumThumbnailListTile extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
album.albumName,
|
||||
album.name,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
|
||||
@@ -34,7 +34,7 @@ class AlbumTitleTextField extends ConsumerWidget {
|
||||
focusNode: albumTitleTextFieldFocusNode,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
color: Colors.grey[700],
|
||||
color: isDarkTheme ? Colors.grey[300] : Colors.grey[700],
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
controller: albumTitleController,
|
||||
|
||||
@@ -9,21 +9,19 @@ import 'package:immich_mobile/modules/album/providers/asset_selection.provider.d
|
||||
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_toast.dart';
|
||||
import 'package:immich_mobile/shared/views/immich_loading_overlay.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
const AlbumViewerAppbar({
|
||||
Key? key,
|
||||
required this.albumInfo,
|
||||
required this.album,
|
||||
required this.userId,
|
||||
required this.albumId,
|
||||
}) : super(key: key);
|
||||
|
||||
final AlbumResponseDto albumInfo;
|
||||
final Album album;
|
||||
final String userId;
|
||||
final String albumId;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -34,19 +32,18 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
final newAlbumTitle = ref.watch(albumViewerProvider).editTitleText;
|
||||
final isEditAlbum = ref.watch(albumViewerProvider).isEditAlbum;
|
||||
|
||||
void onDeleteAlbumPressed(String albumId) async {
|
||||
void onDeleteAlbumPressed() async {
|
||||
ImmichLoadingOverlayController.appLoader.show();
|
||||
|
||||
bool isSuccess =
|
||||
await ref.watch(albumServiceProvider).deleteAlbum(albumId);
|
||||
bool isSuccess = await ref.watch(albumServiceProvider).deleteAlbum(album);
|
||||
|
||||
if (isSuccess) {
|
||||
if (albumInfo.shared) {
|
||||
ref.watch(sharedAlbumProvider.notifier).deleteAlbum(albumId);
|
||||
if (album.shared) {
|
||||
ref.watch(sharedAlbumProvider.notifier).deleteAlbum(album);
|
||||
AutoRouter.of(context)
|
||||
.navigate(const TabControllerRoute(children: [SharingRoute()]));
|
||||
} else {
|
||||
ref.watch(albumProvider.notifier).deleteAlbum(albumId);
|
||||
ref.watch(albumProvider.notifier).deleteAlbum(album);
|
||||
AutoRouter.of(context)
|
||||
.navigate(const TabControllerRoute(children: [LibraryRoute()]));
|
||||
}
|
||||
@@ -62,11 +59,11 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
ImmichLoadingOverlayController.appLoader.hide();
|
||||
}
|
||||
|
||||
void onLeaveAlbumPressed(String albumId) async {
|
||||
void onLeaveAlbumPressed() async {
|
||||
ImmichLoadingOverlayController.appLoader.show();
|
||||
|
||||
bool isSuccess =
|
||||
await ref.watch(sharedAlbumProvider.notifier).leaveAlbum(albumId);
|
||||
await ref.watch(sharedAlbumProvider.notifier).leaveAlbum(album);
|
||||
|
||||
if (isSuccess) {
|
||||
AutoRouter.of(context)
|
||||
@@ -84,20 +81,20 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
ImmichLoadingOverlayController.appLoader.hide();
|
||||
}
|
||||
|
||||
void onRemoveFromAlbumPressed(String albumId) async {
|
||||
void onRemoveFromAlbumPressed() async {
|
||||
ImmichLoadingOverlayController.appLoader.show();
|
||||
|
||||
bool isSuccess =
|
||||
await ref.watch(sharedAlbumProvider.notifier).removeAssetFromAlbum(
|
||||
albumId,
|
||||
selectedAssetsInAlbum.map((a) => a.id).toList(),
|
||||
album,
|
||||
selectedAssetsInAlbum,
|
||||
);
|
||||
|
||||
if (isSuccess) {
|
||||
Navigator.pop(context);
|
||||
ref.watch(assetSelectionProvider.notifier).disableMultiselection();
|
||||
ref.watch(albumProvider.notifier).getAllAlbums();
|
||||
ref.invalidate(sharedAlbumDetailProvider(albumId));
|
||||
ref.invalidate(sharedAlbumDetailProvider(album.id));
|
||||
} else {
|
||||
Navigator.pop(context);
|
||||
ImmichToast.show(
|
||||
@@ -113,27 +110,27 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
|
||||
buildBottomSheetActionButton() {
|
||||
if (isMultiSelectionEnable) {
|
||||
if (albumInfo.ownerId == userId) {
|
||||
if (album.ownerId == userId) {
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.delete_sweep_rounded),
|
||||
title: const Text(
|
||||
'album_viewer_appbar_share_remove',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
).tr(),
|
||||
onTap: () => onRemoveFromAlbumPressed(albumId),
|
||||
onTap: () => onRemoveFromAlbumPressed(),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox();
|
||||
}
|
||||
} else {
|
||||
if (albumInfo.ownerId == userId) {
|
||||
if (album.ownerId == userId) {
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.delete_forever_rounded),
|
||||
title: const Text(
|
||||
'album_viewer_appbar_share_delete',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
).tr(),
|
||||
onTap: () => onDeleteAlbumPressed(albumId),
|
||||
onTap: () => onDeleteAlbumPressed(),
|
||||
);
|
||||
} else {
|
||||
return ListTile(
|
||||
@@ -142,7 +139,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
'album_viewer_appbar_share_leave',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
).tr(),
|
||||
onTap: () => onLeaveAlbumPressed(albumId),
|
||||
onTap: () => onLeaveAlbumPressed(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -180,7 +177,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
onPressed: () async {
|
||||
bool isSuccess = await ref
|
||||
.watch(albumViewerProvider.notifier)
|
||||
.changeAlbumTitle(albumId, userId, newAlbumTitle);
|
||||
.changeAlbumTitle(album, newAlbumTitle);
|
||||
|
||||
if (!isSuccess) {
|
||||
ImmichToast.show(
|
||||
|
||||
@@ -3,21 +3,20 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/album_viewer.provider.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
|
||||
class AlbumViewerEditableTitle extends HookConsumerWidget {
|
||||
final AlbumResponseDto albumInfo;
|
||||
final Album album;
|
||||
final FocusNode titleFocusNode;
|
||||
const AlbumViewerEditableTitle({
|
||||
Key? key,
|
||||
required this.albumInfo,
|
||||
required this.album,
|
||||
required this.titleFocusNode,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final titleTextEditController =
|
||||
useTextEditingController(text: albumInfo.albumName);
|
||||
final titleTextEditController = useTextEditingController(text: album.name);
|
||||
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
void onFocusModeChange() {
|
||||
@@ -50,9 +49,7 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(titleFocusNode);
|
||||
|
||||
ref
|
||||
.watch(albumViewerProvider.notifier)
|
||||
.setEditTitleText(albumInfo.albumName);
|
||||
ref.watch(albumViewerProvider.notifier).setEditTitleText(album.name);
|
||||
ref.watch(albumViewerProvider.notifier).enableEditAlbum();
|
||||
|
||||
if (titleTextEditController.text == 'Untitled') {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/favorite/providers/favorite_provider.dart';
|
||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/asset_selection.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
@@ -26,6 +27,7 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
ref.watch(assetSelectionProvider).selectedAssetsInAlbumViewer;
|
||||
final isMultiSelectionEnable =
|
||||
ref.watch(assetSelectionProvider).isMultiselectEnable;
|
||||
final isFavorite = ref.watch(favoriteProvider).contains(asset.id);
|
||||
|
||||
viewAsset() {
|
||||
AutoRouter.of(context).push(
|
||||
@@ -85,9 +87,23 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
right: 10,
|
||||
bottom: 5,
|
||||
child: Icon(
|
||||
(deviceId != asset.deviceId)
|
||||
? Icons.cloud_done_outlined
|
||||
: Icons.photo_library_rounded,
|
||||
asset.isRemote
|
||||
? (deviceId == asset.deviceId
|
||||
? Icons.cloud_done_outlined
|
||||
: Icons.cloud_outlined)
|
||||
: Icons.cloud_off_outlined,
|
||||
color: Colors.white,
|
||||
size: 18,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
buildAssetFavoriteIcon() {
|
||||
return const Positioned(
|
||||
left: 10,
|
||||
bottom: 5,
|
||||
child: Icon(
|
||||
Icons.star,
|
||||
color: Colors.white,
|
||||
size: 18,
|
||||
),
|
||||
@@ -141,6 +157,7 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
child: Stack(
|
||||
children: [
|
||||
buildThumbnailImage(),
|
||||
if (isFavorite) buildAssetFavoriteIcon(),
|
||||
if (showStorageIndicator) buildAssetStoreLocationIcon(),
|
||||
if (!asset.isImage) buildVideoLabel(),
|
||||
if (isMultiSelectionEnable) buildAssetSelectionIcon(),
|
||||
|
||||
@@ -121,7 +121,7 @@ class SelectionThumbnailImage extends HookConsumerWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
asset.duration.substring(0, 7),
|
||||
asset.duration.toString().substring(0, 7),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
|
||||
@@ -19,11 +19,10 @@ import 'package:immich_mobile/modules/album/ui/album_viewer_thumbnail.dart';
|
||||
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
|
||||
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_sliver_persistent_app_bar_delegate.dart';
|
||||
import 'package:immich_mobile/shared/views/immich_loading_overlay.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
class AlbumViewerPage extends HookConsumerWidget {
|
||||
final String albumId;
|
||||
@@ -34,16 +33,16 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
FocusNode titleFocusNode = useFocusNode();
|
||||
ScrollController scrollController = useScrollController();
|
||||
var albumInfo = ref.watch(sharedAlbumDetailProvider(albumId));
|
||||
final album = ref.watch(sharedAlbumDetailProvider(albumId));
|
||||
|
||||
final userId = ref.watch(authenticationProvider).userId;
|
||||
|
||||
/// Find out if the assets in album exist on the device
|
||||
/// If they exist, add to selected asset state to show they are already selected.
|
||||
void onAddPhotosPressed(AlbumResponseDto albumInfo) async {
|
||||
void onAddPhotosPressed(Album albumInfo) async {
|
||||
if (albumInfo.assets.isNotEmpty == true) {
|
||||
ref.watch(assetSelectionProvider.notifier).addNewAssets(
|
||||
albumInfo.assets.map((e) => Asset.remote(e)).toList(),
|
||||
albumInfo.assets,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -60,7 +59,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
var addAssetsResult =
|
||||
await ref.watch(albumServiceProvider).addAdditionalAssetToAlbum(
|
||||
returnPayload.selectedAdditionalAsset,
|
||||
albumId,
|
||||
albumInfo,
|
||||
);
|
||||
|
||||
if (addAssetsResult != null &&
|
||||
@@ -78,10 +77,10 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
void onAddUsersPressed(AlbumResponseDto albumInfo) async {
|
||||
void onAddUsersPressed(Album album) async {
|
||||
List<String>? sharedUserIds =
|
||||
await AutoRouter.of(context).push<List<String>?>(
|
||||
SelectAdditionalUserForSharingRoute(albumInfo: albumInfo),
|
||||
SelectAdditionalUserForSharingRoute(album: album),
|
||||
);
|
||||
|
||||
if (sharedUserIds != null) {
|
||||
@@ -89,7 +88,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
|
||||
var isSuccess = await ref
|
||||
.watch(albumServiceProvider)
|
||||
.addAdditionalUserToAlbum(sharedUserIds, albumId);
|
||||
.addAdditionalUserToAlbum(sharedUserIds, album);
|
||||
|
||||
if (isSuccess) {
|
||||
ref.invalidate(sharedAlbumDetailProvider(albumId));
|
||||
@@ -99,18 +98,18 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildTitle(AlbumResponseDto albumInfo) {
|
||||
Widget buildTitle(Album album) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 16),
|
||||
child: userId == albumInfo.ownerId
|
||||
child: userId == album.ownerId
|
||||
? AlbumViewerEditableTitle(
|
||||
albumInfo: albumInfo,
|
||||
album: album,
|
||||
titleFocusNode: titleFocusNode,
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: Text(
|
||||
albumInfo.albumName,
|
||||
album.name,
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -120,30 +119,22 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildAlbumDateRange(AlbumResponseDto albumInfo) {
|
||||
String startDate = "";
|
||||
DateTime parsedStartDate =
|
||||
DateTime.parse(albumInfo.assets.first.createdAt);
|
||||
DateTime parsedEndDate = DateTime.parse(
|
||||
albumInfo.assets.last.createdAt,
|
||||
); //Need default.
|
||||
|
||||
if (parsedStartDate.year == parsedEndDate.year) {
|
||||
startDate = DateFormat('LLL d').format(parsedStartDate);
|
||||
} else {
|
||||
startDate = DateFormat('LLL d, y').format(parsedStartDate);
|
||||
}
|
||||
|
||||
String endDate = DateFormat('LLL d, y').format(parsedEndDate);
|
||||
Widget buildAlbumDateRange(Album album) {
|
||||
final DateTime startDate = album.assets.first.createdAt;
|
||||
final DateTime endDate = album.assets.last.createdAt; //Need default.
|
||||
final String startDateText =
|
||||
DateFormat(startDate.year == endDate.year ? 'LLL d' : 'LLL d, y')
|
||||
.format(startDate);
|
||||
final String endDateText = DateFormat('LLL d, y').format(endDate);
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 16.0,
|
||||
top: 8.0,
|
||||
bottom: albumInfo.shared ? 0.0 : 8.0,
|
||||
bottom: album.shared ? 0.0 : 8.0,
|
||||
),
|
||||
child: Text(
|
||||
"$startDate-$endDate",
|
||||
"$startDateText-$endDateText",
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -153,15 +144,14 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildHeader(AlbumResponseDto albumInfo) {
|
||||
Widget buildHeader(Album album) {
|
||||
return SliverToBoxAdapter(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTitle(albumInfo),
|
||||
if (albumInfo.assets.isNotEmpty == true)
|
||||
buildAlbumDateRange(albumInfo),
|
||||
if (albumInfo.shared)
|
||||
buildTitle(album),
|
||||
if (album.assets.isNotEmpty == true) buildAlbumDateRange(album),
|
||||
if (album.shared)
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ListView.builder(
|
||||
@@ -185,7 +175,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
}),
|
||||
itemCount: albumInfo.sharedUsers.length,
|
||||
itemCount: album.sharedUsers.length,
|
||||
),
|
||||
)
|
||||
],
|
||||
@@ -193,12 +183,12 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildImageGrid(AlbumResponseDto albumInfo) {
|
||||
Widget buildImageGrid(Album album) {
|
||||
final appSettingService = ref.watch(appSettingsServiceProvider);
|
||||
final bool showStorageIndicator =
|
||||
appSettingService.getSetting(AppSettingsEnum.storageIndicator);
|
||||
|
||||
if (albumInfo.assets.isNotEmpty) {
|
||||
if (album.assets.isNotEmpty) {
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.only(top: 10.0),
|
||||
sliver: SliverGrid(
|
||||
@@ -211,13 +201,12 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(BuildContext context, int index) {
|
||||
return AlbumViewerThumbnail(
|
||||
asset: Asset.remote(albumInfo.assets[index]),
|
||||
assetList:
|
||||
albumInfo.assets.map((e) => Asset.remote(e)).toList(),
|
||||
asset: album.assets[index],
|
||||
assetList: album.assets,
|
||||
showStorageIndicator: showStorageIndicator,
|
||||
);
|
||||
},
|
||||
childCount: albumInfo.assetCount,
|
||||
childCount: album.assetCount,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -225,7 +214,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
return const SliverToBoxAdapter();
|
||||
}
|
||||
|
||||
Widget buildControlButton(AlbumResponseDto albumInfo) {
|
||||
Widget buildControlButton(Album album) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, top: 8, bottom: 8),
|
||||
child: SizedBox(
|
||||
@@ -235,13 +224,13 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
children: [
|
||||
AlbumActionOutlinedButton(
|
||||
iconData: Icons.add_photo_alternate_outlined,
|
||||
onPressed: () => onAddPhotosPressed(albumInfo),
|
||||
onPressed: () => onAddPhotosPressed(album),
|
||||
labelText: "share_add_photos".tr(),
|
||||
),
|
||||
if (userId == albumInfo.ownerId)
|
||||
if (userId == album.ownerId)
|
||||
AlbumActionOutlinedButton(
|
||||
iconData: Icons.person_add_alt_rounded,
|
||||
onPressed: () => onAddUsersPressed(albumInfo),
|
||||
onPressed: () => onAddUsersPressed(album),
|
||||
labelText: "album_viewer_page_share_add_users".tr(),
|
||||
),
|
||||
],
|
||||
@@ -251,7 +240,10 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
Future<bool> onWillPop() async {
|
||||
final isMultiselectEnable = ref.read(assetSelectionProvider).selectedAssetsInAlbumViewer.isNotEmpty;
|
||||
final isMultiselectEnable = ref
|
||||
.read(assetSelectionProvider)
|
||||
.selectedAssetsInAlbumViewer
|
||||
.isNotEmpty;
|
||||
if (isMultiselectEnable) {
|
||||
ref.watch(assetSelectionProvider.notifier).removeAll();
|
||||
return false;
|
||||
@@ -260,7 +252,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
return true;
|
||||
}
|
||||
|
||||
Widget buildBody(AlbumResponseDto albumInfo) {
|
||||
Widget buildBody(Album album) {
|
||||
return WillPopScope(
|
||||
onWillPop: onWillPop,
|
||||
child: GestureDetector(
|
||||
@@ -274,7 +266,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
child: CustomScrollView(
|
||||
controller: scrollController,
|
||||
slivers: [
|
||||
buildHeader(albumInfo),
|
||||
buildHeader(album),
|
||||
SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: ImmichSliverPersistentAppBarDelegate(
|
||||
@@ -282,11 +274,11 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
maxHeight: 50,
|
||||
child: Container(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: buildControlButton(albumInfo),
|
||||
child: buildControlButton(album),
|
||||
),
|
||||
),
|
||||
),
|
||||
buildImageGrid(albumInfo)
|
||||
buildImageGrid(album)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -295,13 +287,12 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: albumInfo.when(
|
||||
data: (AlbumResponseDto? data) {
|
||||
appBar: album.when(
|
||||
data: (Album? data) {
|
||||
if (data != null) {
|
||||
return AlbumViewerAppbar(
|
||||
albumInfo: data,
|
||||
album: data,
|
||||
userId: userId,
|
||||
albumId: albumId,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
@@ -309,7 +300,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
error: (e, _) => null,
|
||||
loading: () => null,
|
||||
),
|
||||
body: albumInfo.when(
|
||||
body: album.when(
|
||||
data: (albumInfo) => albumInfo != null
|
||||
? buildBody(albumInfo)
|
||||
: const Center(
|
||||
|
||||