Compare commits

...

95 Commits

Author SHA1 Message Date
Alex
a384798779 Up version for release 2022-11-30 11:18:06 -06:00
Alex
d31eddf32f chore(mobile) Improve mobile UI (#1038) 2022-11-30 10:58:07 -06:00
Fynn Petersen-Frey
1068c4ad23 feat(server,web): activate ETags for all API endpoints and asset serving (#1031)
This greatly reduces the network traffic by app/web.
2022-11-29 15:45:47 -06:00
Alex
cbc979263e chore(mobile): Improve readability of logs page (#1033) 2022-11-28 14:14:22 -06:00
Fynn Petersen-Frey
765181bbc0 chore(mobile): improve CSV log export (#1032) 2022-11-28 10:17:27 -06:00
Fynn Petersen-Frey
d82dec9773 fix(mobile): fix cache invalidation on logout (#1030)
await all the cache-invalidation operations during logout and catch errors to actually perform all operations.
2022-11-28 10:01:09 -06:00
Alex
024177515d feat(mobile) Add in app logging to show app's log information (#1014) 2022-11-27 14:34:19 -06:00
Alex Tran
fb3b36a569 Added test for user.service 2022-11-26 15:09:06 -06:00
Alex
614743c8f4 fix(server): Prevent delete admin user (#1023) 2022-11-26 15:02:23 -06:00
Fynn Petersen-Frey
47f5e4134e feat(mobile): use cached asset info if unchanged instead of downloading all assets (#1017)
* feat(mobile): use cached asset info if unchanged instead of downloading all assets

This adds an HTTP ETag to the getAllAssets endpoint and client-side support in the app.
If locally cache content is identical to the content on the server, the potentially large list of all assets does not need to be downloaded.

* use ts import instead of require
2022-11-26 10:16:02 -06:00
denck007
efa7b3ba54 Fix(web): navbar color overlap and scroll bar incorrect z index (#1018)
* fix(web): Navbar color overlaps tall images

* fix(web): Scroll bar date behind navbar when scrubbing (fixes issue #757)
2022-11-25 20:52:01 -06:00
Alex
1e9d67ec39 Up mobile version for hotfix release 2022-11-24 15:50:18 -06:00
Alex
80d0ddca9a fix(mobile): Fix not able to show device asset on Android 13 (#1016) 2022-11-24 15:47:55 -06:00
Kiel Hurley
976d347623 feat(server,web,mobile): Use binary prefixes for data sizes (#1009) 2022-11-24 11:39:27 -06:00
Alex Tran
df0a059a02 Up patch version 2022-11-21 20:26:03 -06:00
Alex
cc697486fc fix(server): Deleted shared users cause problem with album retrival and creation (#1002)
* fix(server): Deleted shared users cause problem with album retrival and creation

* Remove dead code
2022-11-21 20:24:56 -06:00
Alex
2227a6f5f3 Added custom buildscript for XCodeCloud 2022-11-21 13:54:30 -06:00
Alex
a9320f06e8 Added v1.36 release note to website 2022-11-21 12:53:25 -06:00
Alex
39b7ab66d4 chore(mobile): clean up linter problems (#1000) 2022-11-21 06:13:14 -06:00
Alex Tran
bc9ee1d611 Added hotfix release note 2022-11-21 05:41:44 -06:00
Alex
56ce747ffc fix(mobile): freeze on splash screen due to accessing bad state (#998) 2022-11-21 05:29:43 -06:00
Alex
a2f3b2199a fix(server): Admin user not created (#996) 2022-11-20 23:25:03 -06:00
Alex Tran
88b8d34aa6 Update .env.example file 2022-11-20 16:44:33 -06:00
Alex Tran
21fd08e0fb Update Readme 2022-11-20 14:42:09 -06:00
Alex Tran
37a4f4a39f Update redirect picture in documentation 2022-11-20 14:18:53 -06:00
Alex Tran
9d2c30298e Added changelog for mobile 2022-11-20 14:11:33 -06:00
Alex Tran
6f5d60fb62 Up version for release 2022-11-20 13:13:27 -06:00
Alex
41ffa0c015 fix(server): Server freezes when getting statistic (#994)
* fix(server): Server freezes when getting statistic
* remove dead code
2022-11-20 13:09:31 -06:00
Alex
b3e51cc849 feat(mobile) Add OAuth Login On Mobile (#990)
* Added return type for oauth/callback

* Remove console.log

* Redirect app

* Wording

* Added loading state change

* Added OAuth login on mobile

* Return correct status for  correct redirection

* Auto discovery OAuth Login
2022-11-20 11:43:10 -06:00
Alex Tran
e01e4e6530 Fixed motion play icon in light mode mobile 2022-11-19 15:23:49 -06:00
Alex Tran
6ed072f67b Added migration needed for OIDC 2022-11-18 23:22:27 -06:00
Alex
8bc64be77b feat: support iOS LivePhoto backup (#950) 2022-11-18 23:12:54 -06:00
Brandon Rothweiler
83e2cabbcc Update contribution-guidelines.md (#985) 2022-11-16 23:30:58 -06:00
Alex
7de7619fd1 Update contribution-guidelines.md 2022-11-16 23:15:26 -06:00
bo0tzz
afae5fd972 web(feat): Add support for actions when clicking notifications (#966)
* feat(web): Add button to close notification popups

* feat(web): Add support for actions on notification click

* feat(web): Open CLI docs when clicking asset upload count message

* test(web): Add action field to notification-card tests

* chore(web): Formatting

* feat(web): Allow HTML in notification message

* feat(web): Do not use link element in file upload count notification

* feat(web): Prevent notification discard button from triggering action

* feat(web): Add noop action support for notifications

* chore(web): Remove unused function argument
2022-11-16 23:11:15 -06:00
bo0tzz
70cd313082 Add navbar button to copy image (#961)
* Add navbar button to copy image

* Use global event for copy image

* merge upstream

* Fixed missing required props

* feat(web): Show notification after copying image to clipboard

* chore(web): Fix typescript error

* chore(web): Formatting

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2022-11-16 15:04:37 -06:00
Alex
e799f35dd2 chore(server) refactor serveFile and downloadFile endpoint (#978) 2022-11-16 00:11:16 -06:00
Kiel Hurley
1db255fd3e Disallow all robots (#977)
Blank `Disallow` disallows nothing
2022-11-15 21:36:04 -06:00
Jason Rasmussen
909e4820d6 chore(web,mobile): update github repo url (#974) 2022-11-15 20:30:44 -06:00
be bright
4727671c79 Update Korean translation with the latest version. (#971) 2022-11-15 09:52:24 -06:00
Jason Rasmussen
f2f255e6e6 feat(server): multi archive downloads (#956) 2022-11-15 09:51:56 -06:00
Jason Rasmussen
b5d75e2016 feat(server,web): system config for admin (#959)
* feat: add admin config module for user configured config, uses it for ffmpeg

* feat: add api endpoint to retrieve admin config settings and values

* feat: add settings panel to admin page on web (wip)

* feat: add api endpoint to update the admin config

* chore: re-generate openapi spec after rebase

* refactor: move from admin config to system config naming

* chore: move away from UseGuards to new @Authenticated decorator

* style: dark mode styling for lists and fix conflicting colors

* wip: 2 column design, no edit button

* refactor: system config

* chore: generate open api

* chore: rm broken test

* chore: cleanup types

* refactor: config module names

Co-authored-by: Zack Pollard <zackpollard@ymail.com>
Co-authored-by: Zack Pollard <zack.pollard@moonpig.com>
2022-11-14 22:39:32 -06:00
Jason Rasmussen
d3c35ec9c5 feat(server,web): OIDC Implementation (#884)
* chore: merge

* feat: nullable password

* feat: server debugger

* chore: regenerate api

* feat: auto-register flag

* refactor: oauth endpoints

* chore: regenerate api

* fix: default scope configuration

* refactor: pass in redirect uri from client

* chore: docs

* fix: bugs

* refactor: auth services and user repository

* fix: select password

* fix: tests

* fix: get signing algorithm from discovery document

* refactor: cookie constants

* feat: oauth logout

* test: auth services

* fix: query param check

* fix: regenerate open-api
2022-11-14 20:24:25 -06:00
Devin Buhl
d476656789 feat(ci): Push images to GitHub Container Registry (#964)
* feat(ci): Push images to GitHub Container Registry

* fix up tag

* fix typo

* use github.repository_owner
2022-11-13 08:32:50 -06:00
Fynn Petersen-Frey
8d0ff974e1 refactor(mobile): tidy-up dependencies, remove unused, replace rarely used ones (#948) 2022-11-11 11:52:02 -06:00
Alex
33ded2a174 Update README.md 2022-11-11 09:41:39 -06:00
Alex
277af33ab0 Update automatic-backup.md
Fixed incorrect sentence idea
2022-11-10 22:44:04 -06:00
Jason Rasmussen
2e4c005ad9 refactor: multistage builds (#955) 2022-11-10 22:22:17 -06:00
Alex
739bed737e Added database migration info to docs 2022-11-10 09:30:32 -06:00
bo0tzz
a1a7e6ac06 Small docs site tweaks (#954)
* Add yarn.lock to .gitignore

* Tweak announcementBar message

* Add demo link to docs homepage

* chore(docs): logo-meaning page cleanup

* chore(docs): support page cleanup

* chore(docs): tech-stack page cleanup

* chore(docs): requirements page cleanup

* Update main README warning to match docs site

* Add clearer documentation link to main README

* chore(docs): one-step-install page cleanup

* chore(docs): Security: remove example JWT_SECRET value

* chore(docs): recommended-install page cleanup

* chore(docs): portainer-install page cleanup

* chore(docs): unraid-install page cleanup
2022-11-10 08:20:23 -06:00
Alex Tran
c3348bd068 Fixed Dockerfile not working in dev 2022-11-09 23:34:35 -06:00
Jason Rasmussen
cc61729f01 build(server): use github-action cache (#949)
* build(server): prune dependencies in docker builder

* fix: e2e tests

* refactor: dockerfile step order

* fix: vips build dependency

* feat: use caching
2022-11-09 19:53:21 -06:00
Christian Paul
b457bfbd4e typo(android-feature-note): Reserve geocoding -> Reverse geocoding (#946)
* Typo: Reserve geocoding -> Reverse geocoding

https://en.wikipedia.org/wiki/Reverse_geocoding

* Update mobile/android/fastlane/metadata/android/en-US/full_description.txt
2022-11-09 10:17:43 -06:00
Jason Rasmussen
1877834fd1 fix(web): broken unit tests (#947) 2022-11-09 10:32:12 -05:00
Alex Tran
afdfd1863f Adjusting dark mode color on the web admin panel 2022-11-09 05:42:06 -06:00
Ian
f6aba0f9ec feat(deployment) Allow overriding service host and ports with env variables (#930)
* Add proxy changes

* Add web changes

* Add microservices changes

* Add examples

* Add header comment to nginx config

* Use URLs instead of host and port
2022-11-09 05:11:32 -06:00
Alex
66640ebfeb Up version for release 2022-11-08 14:34:47 -06:00
Alex
9057e4b7d0 Update documentation 2022-11-08 14:22:42 -06:00
Matthias Rupp
0deb8f4090 Add equals and hashcode to Asset 2022-11-08 19:02:02 +01:00
Fynn Petersen-Frey
1633af7af6 feat(mobile): show local assets (#905)
* introduce Asset as composition of AssetResponseDTO and AssetEntity

* filter out duplicate assets (that are both local and remote, take only remote for now)

* only allow remote images to be added to albums

* introduce ImmichImage to render Asset using local or remote data

* optimized deletion of local assets

* local video file playback

* allow multiple methods to wait on background service finished

* skip local assets when adding to album from home screen

* fix and optimize delete

* show gray box placeholder for local assets

* add comments

* fix bug: duplicate assets in state after onNewAssetUploaded
2022-11-08 11:00:24 -06:00
Jason Rasmussen
99da181cfc feat(web): favorite an asset (#939)
* feat(web): favorite an asset

* fix: test and linting

* fix: asset dto type
2022-11-08 10:20:36 -06:00
Jason Rasmussen
8a9b0347bb fix(server): increase json body payload limit (#941) 2022-11-08 09:24:49 -06:00
Zeeshan Khan
fe4b307fe6 feat(server,web): Delete and restore user from the admin portal (#935)
* delete and restore user from admin UI

* addressed review comments and fix e2e test

* added cron job to delete user, and some formatting changes

* addressed review comments

* adding missing queue registration
2022-11-07 15:53:47 -06:00
Coyote6705
948ff5530c Grammar and syntax edits for the new docs (#936)
* Update introduction.mdx

* Update logo-mearning.md

* Update support-the-project.md

Fixing more grammar/syntax :)

* Update one-step-installation.md

* Update recommended-installation.md

* Update requirements.md

* Update automatic-backup.md

* Update bulk-upload.md

* Update post-installation.md

* Update update.md

* Update contribution-guidelines.md
2022-11-06 21:27:14 -06:00
Alex Tran
2ff1a81f19 Update size 2022-11-06 21:20:48 -06:00
Alex Tran
d90527a095 Up version for release 2022-11-06 21:00:32 -06:00
Alex
f0874ff3fd feat(mobile) Enhance bottom app bar on home page (#934)
* Added bottom sheet

* Finished styling bottom app bar

* Fixed border radius
2022-11-06 20:41:10 -06:00
Alex
c8538cc62f feat(mobile): Enhanced vertical swiping motion in image viewer (#932) 2022-11-05 22:59:06 -05:00
Alex Tran
bbe820d797 Switched hero image to webp 2022-11-05 20:42:26 -05:00
Matthias Rupp
b5751a3fa8 feat(mobile): Add selected assets to album (#901)
* First implementation that uses new API

* Various UI improvements

* Create new album from home screen

* Fix padding when in multiselect mode

* Alex Suggestions

* Change to album after creation
2022-11-05 20:21:55 -05:00
Jason Rasmussen
02bc84062e feat(server): reset admin password using cli command in the server container (#928) 2022-11-05 11:28:40 -05:00
Alex Tran
dd8a4c0c56 Update screenshots readme 2022-11-04 22:33:20 -05:00
Jason Rasmussen
4274fceafe feat(web): add selected asset on main timeline to album from selection (#926) 2022-11-04 22:29:48 -05:00
Alex Tran
da06440fdc Update screenshots in readme 2022-11-04 16:00:24 -05:00
Alex Tran
c1c1d7fabb Update website url 2022-11-04 15:58:08 -05:00
Alex
8b39a1da00 chore: Update repo readme (#927) 2022-11-04 15:50:26 -05:00
Jason Rasmussen
86e50f97ba fix(web): album download progress bar (#925) 2022-11-04 11:45:17 -05:00
Alex
0d7ccc2b26 chore(web): Modified styling for add to album panel (#924) 2022-11-04 09:42:24 -05:00
Jason Rasmussen
5aa06ed3be feat(web): add current view asset to album (#923) 2022-11-04 09:32:09 -05:00
Jason Rasmussen
d696ce4e41 fix(server, web): harden auto pick album thumbnails (#918) 2022-11-04 08:41:04 -05:00
Alex Tran
2782dae518 doc: Added contribution guide line 2022-11-03 22:26:09 -05:00
Alex
0f9c2f0a38 doc: Add content for usage section (#922) 2022-11-03 21:42:24 -05:00
Jason Rasmussen
296a5e786e test(server): all the tests (#911) 2022-11-03 18:55:13 -05:00
Jason Rasmussen
db0a55cd65 fix(server): download album error handling (#917) 2022-11-03 09:12:02 -05:00
Alex
32e79ce7b3 Update portainer-installation.md 2022-11-02 09:53:39 -05:00
Alex
a898610f13 docs: add installation section (#912)
* Implemented requirements

* Added one-step installation

* Finished section
2022-11-01 20:01:03 -05:00
Fynn Petersen-Frey
dc7df5bcfa fix(mobile, Android): throttle all background backup notifications 2022-11-01 16:26:15 +01:00
Fynn Petersen-Frey
dcefd53bfe fix(mobile,Android): throttle detail progress notifications & wait on foregroundInfo (#907) 2022-10-31 21:02:06 -05:00
Fynn Petersen-Frey
cfa04fadd1 Merge pull request #906 from immich-app/dev/reduce-startup-time
reduce app startup time by loading Hive boxes in parallel
2022-10-31 17:52:39 +01:00
Fynn Petersen-Frey
4a6c337960 reduce app startup time by loading Hive boxes in parallel 2022-10-31 15:38:24 +01:00
Alex
3cf85bb837 doc/update overview section (#904)
* Update overview section

* fix typo

* logomeaning

* Update introduction content

* Update introduction content

* Update suport the project

* typo

* Added linked information

* Finished overview section
2022-10-31 06:37:36 -05:00
Fynn Petersen-Frey
dc2c92e721 feat(server/web): download entire album as zip archive (#897)
* feat(server/web): download entire album as zip archive

* fix: remove duplicate API call

* disable ZIP compression (images are already compressed)
2022-10-30 12:38:04 -05:00
Alex Tran
b7f1a1ad4b Change position of the icon 2022-10-30 11:08:55 -05:00
Anbraten
1967c1e237 feat(web): add delete button to asset viewer (#896) 2022-10-30 11:08:22 -05:00
Alex
6e638cd673 fix(web) getting asset with avaialble thumbnail when getting asset count by time bucket (#900) 2022-10-30 11:03:17 -05:00
406 changed files with 12882 additions and 3820 deletions

View File

@@ -26,6 +26,12 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Immich Mono Repo
uses: docker/build-push-action@v3.2.0
with:
@@ -33,8 +39,11 @@ jobs:
file: ./server/Dockerfile
platforms: linux/arm/v7,linux/amd64,linux/arm64
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
altran1502/immich-server:latest
ghcr.io/${{ github.repository_owner }}/immich-server:latest
build_and_push_machine_learning_latest:
runs-on: ubuntu-latest
@@ -54,6 +63,12 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Machine Learning
uses: docker/build-push-action@v3.2.0
with:
@@ -61,8 +76,11 @@ jobs:
file: ./machine-learning/Dockerfile
platforms: linux/arm/v7,linux/amd64,linux/arm64
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
altran1502/immich-machine-learning:latest
ghcr.io/${{ github.repository_owner }}/immich-machine-learning:latest
build_and_push_web_latest:
runs-on: ubuntu-latest
@@ -81,6 +99,12 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Web
uses: docker/build-push-action@v3.2.0
with:
@@ -91,6 +115,7 @@ jobs:
push: true
tags: |
altran1502/immich-web:latest
ghcr.io/${{ github.repository_owner }}/immich-web:latest
build_and_push_nginx_latest:
runs-on: ubuntu-latest
@@ -109,6 +134,12 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Proxy
uses: docker/build-push-action@v3.2.0
with:
@@ -118,3 +149,4 @@ jobs:
push: true
tags: |
altran1502/immich-proxy:latest
ghcr.io/${{ github.repository_owner }}/immich-proxy:latest

View File

@@ -27,6 +27,13 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: ${{ github.repository == 'immich-app/immich' }}
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Immich Mono Repo
uses: docker/build-push-action@v3.2.0
with:
@@ -34,9 +41,13 @@ jobs:
file: ./server/Dockerfile
platforms: linux/arm/v7,linux/amd64,linux/arm64
push: ${{ github.event_name == 'pull_request' && github.repository == 'immich-app/immich' }}
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
altran1502/immich-server:staging
altran1502/immich-server:${{ github.event.pull_request.number }}
ghcr.io/${{ github.repository_owner }}/immich-server:staging
ghcr.io/${{ github.repository_owner }}/immich-server:${{ github.event.pull_request.number }}
build_and_push_machine_learning_staging:
runs-on: ubuntu-latest
@@ -57,6 +68,13 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: ${{ github.repository == 'immich-app/immich' }}
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Machine Learning
uses: docker/build-push-action@v3.2.0
with:
@@ -64,9 +82,13 @@ jobs:
file: ./machine-learning/Dockerfile
platforms: linux/arm/v7,linux/amd64,linux/arm64
push: ${{ github.event_name == 'pull_request' && github.repository == 'immich-app/immich' }}
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
altran1502/immich-machine-learning:staging
altran1502/immich-machine-learning:${{ github.event.pull_request.number }}
ghcr.io/${{ github.repository_owner }}/immich-machine-learning:staging
ghcr.io/${{ github.repository_owner }}/immich-machine-learning:${{ github.event.pull_request.number }}
build_and_push_web_staging:
runs-on: ubuntu-latest
@@ -86,6 +108,13 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: ${{ github.repository == 'immich-app/immich' }}
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Web
uses: docker/build-push-action@v3.2.0
with:
@@ -97,6 +126,8 @@ jobs:
tags: |
altran1502/immich-web:staging
altran1502/immich-web:${{ github.event.pull_request.number }}
ghcr.io/${{ github.repository_owner }}/immich-web:staging
ghcr.io/${{ github.repository_owner }}/immich-web:${{ github.event.pull_request.number }}
build_and_push_nginx_staging:
runs-on: ubuntu-latest
@@ -116,6 +147,13 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: ${{ github.repository == 'immich-app/immich' }}
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Proxy
uses: docker/build-push-action@v3.2.0
with:
@@ -126,3 +164,5 @@ jobs:
tags: |
altran1502/immich-proxy:staging
altran1502/immich-proxy:${{ github.event.pull_request.number }}
ghcr.io/${{ github.repository_owner }}/immich-proxy:staging
ghcr.io/${{ github.repository_owner }}/immich-proxy:${{ github.event.pull_request.number }}

View File

@@ -12,12 +12,12 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
with:
ref: "main"
ref: 'main'
fetch-depth: 0
- name: "Get Previous tag"
- name: 'Get Previous tag'
id: previoustag
uses: "WyriHaximus/github-action-get-previous-tag@v1"
uses: 'WyriHaximus/github-action-get-previous-tag@v1'
with:
fallback: latest
@@ -34,6 +34,13 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push immich-server release
uses: docker/build-push-action@v3.2.0
with:
@@ -41,9 +48,13 @@ jobs:
file: ./server/Dockerfile
platforms: linux/arm/v7,linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
altran1502/immich-server:${{ steps.previoustag.outputs.tag }}
altran1502/immich-server:release
ghcr.io/${{ github.repository_owner }}/immich-server:${{ steps.previoustag.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/immich-server:release
build_and_push_machine_learning_release:
runs-on: ubuntu-latest
@@ -52,9 +63,9 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: "Get Previous tag"
- name: 'Get Previous tag'
id: previoustag
uses: "WyriHaximus/github-action-get-previous-tag@v1"
uses: 'WyriHaximus/github-action-get-previous-tag@v1'
with:
fallback: latest
- name: Set up QEMU
@@ -67,6 +78,12 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Machine Learning
uses: docker/build-push-action@v3.2.0
with:
@@ -74,9 +91,13 @@ jobs:
file: ./machine-learning/Dockerfile
platforms: linux/arm/v7,linux/amd64,linux/arm64
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
altran1502/immich-machine-learning:${{ steps.previoustag.outputs.tag }}
altran1502/immich-machine-learning:release
ghcr.io/${{ github.repository_owner }}/immich-machine-learning:${{ steps.previoustag.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/immich-machine-learning:release
build_and_push_web_release:
runs-on: ubuntu-latest
@@ -84,12 +105,12 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
with:
ref: "main"
ref: 'main'
fetch-depth: 0
- name: "Get Previous tag"
- name: 'Get Previous tag'
id: previoustag
uses: "WyriHaximus/github-action-get-previous-tag@v1"
uses: 'WyriHaximus/github-action-get-previous-tag@v1'
with:
fallback: latest
@@ -106,6 +127,13 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push immich-web release
uses: docker/build-push-action@v3.2.0
with:
@@ -117,6 +145,8 @@ jobs:
tags: |
altran1502/immich-web:${{ steps.previoustag.outputs.tag }}
altran1502/immich-web:release
ghcr.io/${{ github.repository_owner }}/immich-web:${{ steps.previoustag.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/immich-web:release
build_and_push_nginx_release:
runs-on: ubuntu-latest
@@ -124,12 +154,12 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
with:
ref: "main"
ref: 'main'
fetch-depth: 0
- name: "Get Previous tag"
- name: 'Get Previous tag'
id: previoustag
uses: "WyriHaximus/github-action-get-previous-tag@v1"
uses: 'WyriHaximus/github-action-get-previous-tag@v1'
with:
fallback: latest
@@ -146,6 +176,13 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push immich-proxy release
uses: docker/build-push-action@v3.2.0
with:
@@ -156,3 +193,5 @@ jobs:
tags: |
altran1502/immich-proxy:release
altran1502/immich-proxy:${{ steps.previoustag.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/immich-proxy:${{ steps.previoustag.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/immich-proxy:release

317
README.md
View File

@@ -1,36 +1,51 @@
<h1 align="center"> Immich </h1>
<p align="center"> <b>High performance self-hosted photo and video backup solution.</b> </p>
<p align="center">
<img src="design/feature-panel.png" title="Immich Logo">
</p>
<p align="center">
<p align="center">
<br/>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-green.svg?color=3F51B5&style=for-the-badge&label=License&logoColor=000000&labelColor=ececec" alt="License: MIT"></a>
<a href="https://github.com/alextran1502/immich"><img src="https://img.shields.io/github/stars/alextran1502/immich.svg?style=for-the-badge&logo=github&color=3F51B5&label=Stars&logoColor=000000&labelColor=ececec" alt="Star on Github"></a>
<a href="https://immichci.little-home.net/viewType.html?buildTypeId=Immich_BuildAndroidAndGetArtifact&guest=1">
<img src="https://img.shields.io/teamcity/http/immichci.little-home.net/s/Immich_BuildAndroidAndGetArtifact.svg?style=for-the-badge&label=Android&logo=teamcity&logoColor=000000&labelColor=ececec" alt="Android Build"/>
</a>
<a href="https://immichci.little-home.net/viewType.html?buildTypeId=Immich_BuildAndPublishIOSToTestFlight&guest=1">
<img src="https://img.shields.io/teamcity/http/immichci.little-home.net/s/Immich_BuildAndPublishIOSToTestFlight.svg?style=for-the-badge&label=iOS&logo=teamcity&logoColor=000000&labelColor=ececec" alt="iOS Build"/>
</a>
<a href="https://actions-badge.atrox.dev/alextran1502/immich/goto?ref=main">
<img alt="Build Status" src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Falextran1502%2Fimmich%2Fbadge%3Fref%3Dmain&style=for-the-badge&label=Github Action&logo=github&labelColor=ececec&logoColor=000000" />
</a>
<a href="https://discord.gg/D8JsnBEuKb">
<img src="https://img.shields.io/discord/979116623879368755.svg?label=Immich%20Discord&logo=Discord&style=for-the-badge&logoColor=000000&labelColor=ececec" atl="Immich Discord"/>
<img src="https://img.shields.io/discord/979116623879368755.svg?label=Discord&logo=Discord&style=for-the-badge&logoColor=000000&labelColor=ececec" atl="Discord"/>
</a>
<br/>
<br/>
</p>
<p align="center">
<img src="design/immich-logo.svg" width="150" title="Login With Custom URL">
</p>
<h3 align="center">Immich - High performance self-hosted photo and video backup solution</h3>
<br/>
<a href="https://immich.app">
<img src="design/immich-screenshots.png" title="Main Screenshot">
</a>
<br/>
## Disclaimer
- ⚠️ The project is under **very active** development.
- ⚠️ Expect bugs and breaking changes.
- ⚠️ **Do not use the app as the only way to store your photos and videos!**
## Content
- [Official Documentation](https://immich.app/docs/overview/introduction)
- [Demo](#demo)
- [Features](#features)
- [Introduction](https://immich.app/docs/overview/introduction)
- [Installation](https://immich.app/docs/installation/requirements)
- [Contribution Guidelines](https://immich.app/docs/contribution-guidelines)
- [Support The Project](#support-the-project)
- [Known Issues](#known-issues)
## Documentation
You can find the main documentation, including installation guides, at https://immich.app/.
## Demo
You can access the web demo at https://demo.immich.app
For the mobile app, you can use https://demo.immich.app/api for the `Server Endpoint URL`
For the mobile app, you can use `https://demo.immich.app/api` for the `Server Endpoint URL`
```
```bash title="Demo Credential"
The credential
email: demo@immich.app
password: demo
@@ -40,236 +55,54 @@ password: demo
Spec: Free-tier Oracle VM - Amsterdam - 2.4Ghz quad-core ARM64 CPU, 24GB RAM
```
## Content
- [Features](#features)
- [Screenshots](#screenshots)
- [Installation](#installation)
- [Update](#update)
- [Mobile App](#mobile-app)
- [App Beta Invitation links](#App-Beta-release-channel)
- [Development](#development)
- [Support](#support)
- [Known Issues](#known-issues)
# Features
> ⚠️ WARNING: **NOT READY FOR PRODUCTION! DO NOT USE TO STORE YOUR ASSETS**. This project is under heavy development. There will be continuous functions, features and api changes.
| Features | Mobile | Web |
| - | - | - |
| Upload and view videos and photos | Yes | Yes
| Auto backup when the app is opened | Yes | N/A
| Selective album(s) for backup | Yes | N/A
| Download photos and videos to local device | Yes | Yes
| Multi-user support | Yes | Yes
| Album | Yes | Yes
| Shared Albums | Yes | Yes
| Quick navigation with draggable scrollbar | Yes | Yes
| Support RAW (HEIC, HEIF, DNG, Apple ProRaw) | Yes | Yes
| Metadata view (EXIF, map) | Yes | Yes
| Search by metadata, objects and image tags | Yes | No
| Administrative functions (user management) | N/A | Yes
| Background backup | Android | N/A
| Virtual scroll | N/A | Yes
<br/>
# Screenshots
### Mobile
| | | | | |
| - | - | - | - | - |
| <img src="design/login-screen.png" width="150" title="Login With Custom URL"> <p align="center"> Login with custom URL </p> | <img src="design/backup-screen.png" width="150" title="Backup Setting Info"> <p align="center"> Backup Settings </p> | <img src="design/selective-backup-screen.png" width="150" title="Backup Setting Info"> <p align="center"> Backup selection </p> | <img src="design/home-screen.jpeg" width="150" title="Home Screen"> <p align="center"> Home Screen </p> | <img src="design/search-screen.jpeg" width="150" title="Curated Search Info"> <p align="center"> Curated search </p> |
| <img src="design/shared-albums.png" width="150" title="Shared Albums"> <p align="center"> Shared albums </p> | <img src="design/nsc6.png" width="150" title="EXIF Info"> <p align="center"> EXIF info </p> | <img src="https://media.giphy.com/media/y8ZeaAigGmNvlSoKhU/giphy.gif" width="150" title="Loading ~4000 images/videos"> <p align="center"> Loading ~4000 images/videos </p> |
### Web
| Home Dashboard | Image view |
| - | - |
|<img src="design/web-home.jpeg" width="100%" title="Home Dashboard"> | <img src="design/web-detail.jpeg" width="100%" title="Detail">|
<br/>
# Project Details
## 💾 System Requirements
- **OS**: Preferred unix-based operating system (Ubuntu, Debian, MacOS...etc).
- **RAM**: At least 2GB, preferred 4GB.
- **Core**: At least 2 cores, preferred 4 cores.
## 🔩 Technology Stack
There are several services that compose Immich:
1. **NestJs** - Backend of the application
2. **SvelteKit** - Web frontend of the application
3. **PostgreSQL** - Main database of the application
4. **Redis** - For sharing websocket instance between docker instances and background tasks message queue.
5. **Nginx** - Load balancing and optimized file uploading.
6. **TensorFlow** - Object Detection (COCO SSD) and Image Classification (ImageNet).
<br/>
# Installation
NOTE: When using a reverse proxy in front of Immich (such as NGINX), the reverse proxy might require extra configuration to allow large files to be uploaded (such as `client_max_body_size` in the case of NGINX).
## Testing one-step installation (not recommended for production)
> ⚠️ *This installation method is for evaluating Immich before further customization to meet the users' needs.*
*Applicable operating systems: Ubuntu, Debian, MacOS*
- In the shell, from the directory of your choice, run the following command:
```bash
curl -o- https://raw.githubusercontent.com/immich-app/immich/main/install.sh | bash
```
This script will download the `docker-compose.yml` file and the `.env` file, then populate the necessary information, and finally run the `docker-compose up` or `docker compose up` (based on your docker's version) command.
The web application will be available at `http://<machine-ip-address>:2283`, and the server URL for the mobile app will be `http://<machine-ip-address>:2283/api`.
The directory which is used to store the backup file is `./immich-app/immich-data`.
<br/>
## Custom installation (Recommended)
### Step 1 - Download necessary files
- Create a directory called `immich-app` and cd into it.
- Get `docker-compose.yml`
```bash
wget https://raw.githubusercontent.com/immich-app/immich/main/docker/docker-compose.yml
```
- Get `.env`
```bash
wget -O .env https://raw.githubusercontent.com/immich-app/immich/main/docker/.env.example
```
### Step 2 - Populate .env file with custom information
<a href="https://github.com/immich-app/immich/blob/main/docker/.env.example" target="_blank"><b>See the example <code>.env</code> file</b></a>
* Populate custom database information if necessary.
* Populate `UPLOAD_LOCATION` as prefered location for storing backup assets.
* Populate a secret value for `JWT_SECRET`, you can use this command: `openssl rand -base64 128`
### Step 3 - Start the containers
- Run `docker-compose up` or `docker compose up` (based on your docker's version)
### Step 4 - Register admin user
- Navigate to the web at `http://<machine-ip-address>:2283` and follow the prompts to register admin user.
<p align="center">
<img src="design/admin-registration-form.png" width="300" title="Admin Registration">
</p>
- You can add and manage users from the administration page.
<p align="center">
<img src="design/admin-interface.png" width="500" title="Admin User Management">
</p>
### Step 5 - Access the mobile app
- Login the mobile app with the server endpoint URL at `http://<machine-ip-address>:2283/api`
<p align="center">
<img src="design/login-screen.jpeg" width="250" title="Example login screen">
</p>
<br/>
## Update
If you have installed, you can update the application by navigate to the directory that contains the `docker-compose.yml` file and run the following command:
```bash
docker-compose pull && docker-compose up -d
```
# Unraid Installation
Please follow this [article](https://mfaz.dev/posts/immich-unraid/) for a tutorial on how to install Immich on Unraid
# Mobile app
| F-Droid | Google Play | iOS |
| - | - | - |
| <a href="https://f-droid.org/packages/app.alextran.immich"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80"></a> | <p align="left"> <a href="https://play.google.com/store/apps/details?id=app.alextran.immich"><img src="design/google-play-qr-code.png" width="200" title="Google Play Store"></a> <p/> | <p align="left"> <a href="https://apps.apple.com/us/app/immich/id1613945652"><img src="design/ios-qr-code.png" width="200" title="Apple App Store"></a> <p/> |
> *The Play/App Store version might be lagging behind the latest release due to their review process.*
# App Beta release channel
You can opt-in to join app beta release channel by following the links below:
* Android: Invitation link from [web](https://play.google.com/store/apps/details?id=app.alextran.immich) or from [mobile](https://play.google.com/store/apps/details?id=app.alextran.immich)
* iOS: [TestFlight invitation link](https://testflight.apple.com/join/1vYsAa8P)
<br/>
# Development
The development environment can be started from the root of the project after populating the `.env` file with the command:
```bash
make dev # required Makefile installed on the system.
```
All servers and web container are hot reload for quick feedback loop.
## Note for developers
### 1 - OpenAPI
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). When you add a new or modify an existing endpoint, you must run the generate command below to update the client SDK.
```bash
npm run api:generate # Run from server directory
```
You can find the generated client SDK in the [`web/src/api`](web/src/api) for Typescript SDK and [`mobile/openapi`](mobile/openapi) for Dart SDK.
<br/>
# Support
If you like the app, find it helpful, and want to support me to offset the cost of publishing to AppStores, you can sponsor the project with [**one time**](https://github.com/sponsors/alextran1502?frequency=one-time&sponsor=alextran1502) or monthly donation from [**Github Sponsor**](https://github.com/sponsors/alextran1502).
You can also donate using crypto currency with the following addresses:
<p align="" style="display: flex; place-items: center; gap: 15px" title="Bitcoin(BTC)"><img src="design/bitcoin.png" width="25" title="Bitcoin"> <b>Bitcoin</b>: <code>1FvEp6P6NM8EZEkpGUFAN2LqJ1gxusNxZX</code></p>
<p align="" style="display: flex; place-items: center; gap: 15px" title="Cardano(ADA)"> <img src="design/cardano.png" width="30" title="Cardano"> <b>Cardano</b>: <code>addr1qyy567vqhqrr3p7vpszr5p264gw89sqcwts2z8wqy4yek87cdmy79zazyjp7tmwhkluhk3krvslkzfvg0h43tytp3f5q49nycc</code> </p>
This is also a meaningful way to give me motivation and encouragement to continue working on the app.
Cheers! 🎉
<br/>
# Features
| Features | Mobile | Web |
| ------------------------------------------- | ------- | --- |
| Upload and view videos and photos | Yes | Yes |
| Auto backup when the app is opened | Yes | N/A |
| Selective album(s) for backup | Yes | N/A |
| Download photos and videos to local device | Yes | Yes |
| Multi-user support | Yes | Yes |
| Album | Yes | Yes |
| Shared Albums | Yes | Yes |
| Quick navigation with draggable scrollbar | Yes | Yes |
| Support RAW (HEIC, HEIF, DNG, Apple ProRaw) | Yes | Yes |
| Metadata view (EXIF, map) | Yes | Yes |
| Search by metadata, objects and image tags | Yes | No |
| Administrative functions (user management) | N/A | Yes |
| Background backup | Android | N/A |
| Virtual scroll | Yes | Yes |
| OAuth Support | Yes | Yes |
| LivePhotos Backup and Playback (iOS only) | Yes | Yes |
# Support the project
I've committed to this project, and I will not stop. I will keep updating the docs, adding new features, and fixing bugs. But I can't do it alone. So I need your help to give me additional motivation to keep going.
As our hosts in the [selfhosted.show - In the episode 'The-organization-must-not-be-name is a Hostile Actor'](https://selfhosted.show/79?t=1418) said, this is a massive undertaking of what the team and I are doing. And I would love to someday be able to do this full-time, and I am asking for your help to make that happen.
If you feel like this is the right cause and the app is something you are seeing yourself using for a long time, please consider supporting the project with the option below.
## Donation
- [Monthly donation](https://github.com/sponsors/alextran1502) via GitHub Sponsors
- [One-time donation](https://github.com/sponsors/alextran1502?frequency=one-time&sponsor=alextran1502) via Github Sponsors
# Known Issues
## TensorFlow Build Issue
*This is a known issue for incorrect Proxmox setup*
_This is a known issue for incorrect Proxmox setup_
TensorFlow doesn't run with older CPU architecture, it requires a CPU with AVX and AVX2 instruction set. If you encounter the error `illegal instruction core dump` when running the docker-compose command above, check for your CPU flags with the command and make sure you see `AVX` and `AVX2`:
```bash
more /proc/cpuinfo | grep flags
```
```
If you are running virtualization in Proxmox, the VM doesn't have the flag enabled.
You need to change the CPU type from `kvm64` to `host` under VMs hardware tab.
`Hardware > Processors > Edit > Advanced > Type (dropdown menu) > host`

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -23,7 +23,9 @@ REDIS_HOSTNAME=immich_redis
# REDIS_SOCKET=
###################################################################################
# Upload File Config
# Upload File Location
#
# This is the location where uploaded files are stored.
###################################################################################
UPLOAD_LOCATION=absolute_location_on_your_machine_where_you_want_to_store_the_backup
@@ -36,19 +38,17 @@ LOG_LEVEL=simple
###################################################################################
# JWT SECRET
###################################################################################
#
# This JWT_SECRET is used to sign the authentication keys for user login
# You should set it to a long randomly generated value
# You can use this command to generate one: openssl rand -base64 128
###################################################################################
JWT_SECRET=
###################################################################################
# Reverse Geocoding
####################################################################################
# DISABLE_REVERSE_GEOCODING=false
#
# Reverse geocoding is done locally which has a small impact on memory usage
# This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable
# This ranges from 0-3 with 3 being the most precise
@@ -56,14 +56,44 @@ JWT_SECRET=
# 2 - Cities > 1000 population: ~150MB RAM
# 1 - Cities > 5000 population: ~80MB RAM
# 0 - Cities > 15000 population: ~40MB RAM
####################################################################################
# DISABLE_REVERSE_GEOCODING=false
# REVERSE_GEOCODING_PRECISION=3
####################################################################################
# WEB - Optional
#
# Custom message on the login page, should be written in HTML form.
# For example:
# PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
####################################################################################
# Custom message on the login page, should be written in HTML form.
# For example PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
PUBLIC_LOGIN_PAGE_MESSAGE=
####################################################################################
# Alternative Service Addresses - Optional
#
# This is an advanced feature for users who may be running their immich services on different hosts.
# It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers.
# Note: immich-microservices is bound to 3002, but no references are made
####################################################################################
# IMMICH_WEB_URL=http://immich-web:3000
# IMMICH_SERVER_URL=http://immich-server:3001
# IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003
####################################################################################
# OAuth Setting - Optional
#
# These setting will enable OAuth login for your instance of Immich
# Folow the instructions in the page https://immich.app/docs/usage/oauth to set up your OAuth provider
####################################################################################
# OAUTH_ENABLED=false
# OAUTH_ISSUER_URL=
# OAUTH_CLIENT_ID=
# OAUTH_CLIENT_SECRET=
# OAUTH_BUTTON_TEXT=Login with OAuth
# OAUTH_AUTO_REGISTER=true
# OAUTH_SCOPE="openid profile email"

View File

@@ -68,6 +68,9 @@ services:
command: npm run dev --host
env_file:
- .env
environment:
# Rename these values for svelte public interface
- PUBLIC_IMMICH_SERVER_URL=${IMMICH_SERVER_URL}
ports:
- 3000:3000
- 24678:24678
@@ -100,6 +103,10 @@ services:
immich-proxy:
container_name: immich_proxy
image: immich-proxy-dev:latest
environment:
# Make sure these values get passed through from the env file
- IMMICH_SERVER_URL
- IMMICH_WEB_URL
build:
context: ../nginx
dockerfile: Dockerfile

View File

@@ -47,6 +47,9 @@ services:
entrypoint: ["/bin/sh", "./entrypoint.sh"]
env_file:
- .env
environment:
# Rename these values for svelte public interface
- PUBLIC_IMMICH_SERVER_URL=${IMMICH_SERVER_URL}
restart: always
redis:
@@ -71,6 +74,10 @@ services:
immich-proxy:
container_name: immich_proxy
image: altran1502/immich-proxy:staging
environment:
# Make sure these values get passed through from the env file
- IMMICH_SERVER_URL
- IMMICH_WEB_URL
ports:
- 2283:8080
logging:

View File

@@ -1,4 +1,4 @@
version: "3.8"
version: '3.8'
services:
immich-server-test:
@@ -9,7 +9,7 @@ services:
target: builder
command: npm run test:e2e
expose:
- "3000"
- '3000'
volumes:
- ../server:/usr/src/app
- /usr/src/app/node_modules

View File

@@ -47,6 +47,9 @@ services:
entrypoint: ["/bin/sh", "./entrypoint.sh"]
env_file:
- .env
environment:
# Rename these values for svelte public interface
- PUBLIC_IMMICH_SERVER_URL=${IMMICH_SERVER_URL}
restart: always
redis:
@@ -71,6 +74,10 @@ services:
immich-proxy:
container_name: immich_proxy
image: altran1502/immich-proxy:release
environment:
# Make sure these values get passed through from the env file
- IMMICH_SERVER_URL
- IMMICH_WEB_URL
ports:
- 2283:8080
logging:

1
docs/.gitignore vendored
View File

@@ -18,3 +18,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn.lock

View File

@@ -1,12 +0,0 @@
---
slug: first-blog-post
title: First Blog Post
authors:
name: Gao Wei
title: Docusaurus Core Team
url: https://github.com/wgao19
image_url: https://github.com/wgao19.png
tags: [hola, docusaurus]
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

View File

@@ -1,44 +0,0 @@
---
slug: long-blog-post
title: Long Blog Post
authors: endi
tags: [hello, docusaurus]
---
This is the summary of a very long blog post,
Use a `<!--` `truncate` `-->` comment to limit blog post size in the list view.
<!--truncate-->
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

View File

@@ -1,20 +0,0 @@
---
slug: mdx-blog-post
title: MDX Blog Post
authors: [slorber]
tags: [docusaurus]
---
Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
:::tip
Use the power of React to create interactive blog posts.
```js
<button onClick={() => alert('button clicked!')}>Click me!</button>
```
<button onClick={() => alert('button clicked!')}>Click me!</button>
:::

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

View File

@@ -1,25 +0,0 @@
---
slug: welcome
title: Welcome
authors: [slorber, yangshun]
tags: [facebook, hello, docusaurus]
---
[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog).
Simply add Markdown files (or folders) to the `blog` directory.
Regular blog authors can be added to `authors.yml`.
The blog post date can be extracted from filenames, such as:
- `2019-05-30-welcome.md`
- `2019-05-30-welcome/index.md`
A blog post folder can be convenient to co-locate blog post images:
![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg)
The blog supports tags as well!
**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config.

View File

@@ -1,17 +1,5 @@
endi:
name: Endilie Yacop Sucipto
title: Maintainer of Docusaurus
url: https://github.com/endiliey
image_url: https://github.com/endiliey.png
yangshun:
name: Yangshun Tay
title: Front End Engineer @ Facebook
url: https://github.com/yangshun
image_url: https://github.com/yangshun.png
slorber:
name: Sébastien Lorber
title: Docusaurus maintainer
url: https://sebastienlorber.com
image_url: https://github.com/slorber.png
alextran:
name: Alex Tran
title: Maintainer of Immich
url: https://github.com/alextran1502
image_url: https://github.com/alextran1502.png

View File

@@ -0,0 +1,114 @@
---
slug: release-1-36
title: Release v1.36.0
authors: [alextran]
tags: [release]
date: 2022-11-10
---
Hello everyone, it is my pleasure to deliver the new release of Immich to you. The team has been working hard to bring you the new features and improvements. This release includes some big features that the community has been asking since the beginning of Immich. We hope you will enjoy it.
Some notable features are:
- [OAuth integration](#livephoto-ios-support-)
- [LivePhoto support on iOS](#oauth-integration-)
- User config system
<!--truncate-->
## LivePhoto iOS Support 🎉
LivePhoto on iOS is now supported in Immich.
The motion part will now be uploaded and can be played on the mobile app and the web.
:::caution
- The server and the app has to be on version **1.36.x** for the application to work correctly.
- Previous uploaded photos will not be updated automatically, you will have to remove and reupload them if you want to keep the LivePhoto functionality.
:::
<img
src="https://media.giphy.com/media/fTrGceZd7t1ewi8ESc/giphy.gif"
width="100%"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
}}
title="LivePhoto playback on the web"
/>
## OAuth Integration 🎉
I want to borrow this chance to express my gratitude to [@EnricoBilla](https://github.com/EnricoBilla), who has been the trailblazer for this feature since the beginning days of Immich. His PR has sparked ideas, suggestions, and discussion among the team member on how to integrate this feature successfully into the app. Thank you so much for your work and your time.
OAuth is now integrated into the system. Please follow the guide [here](https://immich.app/docs/usage/oauth) to set up your OAuth integration
After setting up the correct environment variables in the `.env` file, as shown below
| Key | Type | Default | Description |
| ------------------- | ------- | -------------------- | ------------------------------------------------------------------------- |
| OAUTH_ENABLED | boolean | false | Enable/disable OAuth2 |
| OAUTH_ISSUER_URL | URL | (required) | Required. Self-discovery URL for client |
| OAUTH_CLIENT_ID | string | (required) | Required. Client ID |
| OAUTH_CLIENT_SECRET | string | (required) | Required. Client Secret |
| OAUTH_SCOPE | string | openid email profile | Full list of scopes to send with the request (space delimited) |
| OAUTH_AUTO_REGISTER | boolean | true | When true, will automatically register a user the first time they sign in |
| OAUTH_BUTTON_TEXT | string | Login with OAuth | Text for the OAuth button on the web |
```bash title="Authentik Example"
OAUTH_ENABLED=true
OAUTH_ISSUER_URL=http://10.1.15.216:9000/application/o/immich-test/
OAUTH_CLIENT_ID=30596v8f78a4b6a97d5985c3076b6b4c4d12ddc33
OAUTH_CLIENT_SECRET=50f1eafdec353b95b1c638db390db4ab67ef035a51212dbec2f56175e2eb272b5d572c099176e6fe116ecf47ffdd544bgdb9e2edc588307ee0339d25eeccd88
OAUTH_BUTTON_TEXT=Login with Authentik
```
The web will have the option to sign in with OAuth.
<img
src="https://user-images.githubusercontent.com/27055614/202923726-f43fa148-47f5-4182-8f29-b0b87e4586fa.png"
width="50%"
title="Web Sign in with OAuth"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
}}
/>
The mobile app will check if the server has OAuth enabled before displaying the OAuth
sign-in button.
<img
src="https://media.giphy.com/media/3iy3SaNkVYtlkEiw06/giphy.gif"
title="Mobile sign in with OAuth"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
}}
/>
## Support
<img
src="https://media.giphy.com/media/LStqgGESXW8XnuCv5y/giphy.gif"
width="300"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
}}
title="Support the project"
/>
If you find the project helpful and it helps you in some ways, you can support the project [one time](https://github.com/sponsors/alextran1502?frequency=one-time&sponsor=alextran1502) or [monthly](https://github.com/sponsors/alextran1502) from GitHub Sponsor
It is a great way to let me know that you want me to continue developing and working on this project for years to come.
## Details
For more details, please check out the [release note](https://github.com/immich-app/immich/releases/tag/v1.36.0_55-dev)

View File

@@ -1,5 +1,19 @@
---
sidebar_position: 4
sidebar_position: 6
---
# FAQ
# FAQ
### What is the difference between the cloud icon on the mobile app?
| Icon | Description |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| ![cloud](/img/cloud.svg) | Asset is only available in the cloud and was uploaded from some other device (like the web client) or was deleted from this device after upload |
| ![cloud-cross](/img/cloud-off.svg) | Asset is only available locally and has not yet been backed up |
| ![cloud-done](/img/cloud-done.svg) | Asset was uploaded from this device and is now backed up in the cloud/server and still available in original on the device |
### How can I sync an existing directory with Immich's server?
Immich doesn't have the mechanism to sync an existing directory with the server. There is however, a helper CLI tool to help you bulk upload the existing photos and videos to the server. You can find the guide to use the CLI tool [here](/docs/usage/bulk-upload.md).
### Why doesn't Immich watch an existing photo gallery directory?
The initial approach of Immich is to become a backup tool, primarily for mobile device usage. Thus, all the assets must be uploaded from the mobile client. The app was architectured to perform that job well.

View File

@@ -0,0 +1,103 @@
---
sidebar_position: 5
---
# Contribution guidelines
## Environment setup
### Server and web app
This environment includes the following services:
- Core server - `/server/apps/immich`
- Machine learning - `/machine-learning`
- Microservices - `/server/apps/microservicess`
- Web app - `/web`
- Redis
- PostgreSQL development database with exposed port `5432` so you can use any database client to acess it
- NGINX Proxy - `nginx/nginx.conf`
All the services are packaged to run as with single Docker Compose command.
### Instructions
1. Clone the project repo.
2. Run `cp docker/.env.example docker/.env`.
3. Edit `docker/.env` to provide values for the required variables `UPLOAD_LOCATION` and `JWT_SECRET`.
4. From the root directory, run:
```bash title="Start development server"
make dev # required Makefile installed on the system.
```
5. Access the dev instance in your browser at http://localhost:2283, or connect via the mobile app.
All the services will be started with hot-reloading enabled for a quick feedback loop.
You can access the web from `http://your-machine-ip:2283` or `http://localhost:2283` and access the server from the mobile app at `http://your-machine-ip:2283/api`
### Mobile app
The mobile app `(/mobile)` will required Flutter toolchain to be installed on your system.
Please refer to the [Flutter's official documentation](https://flutter.dev/docs/get-started/install) for more information on setting up the toolchain on your machine.
## IDE setup
### Lint / format extensions
Setting these in the IDE give a better developer experience, auto-formatting code on save, and providing instant feedback on lint issues.
### VSCode
Install `Flutter`, `Prettier`, `ESLint` and `Svelte` extensions.
in User `settings.json` (`cmd + shift + p` and search for `Open User Settings JSON`) add the following:
```json title="settings.json"
{
"editor.formatOnSave": true,
"[javascript][typescript][css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.tabSize": 2,
"editor.formatOnSave": true
},
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode",
"editor.tabSize": 2
},
"svelte.enable-ts-plugin": true,
"eslint.validate": ["javascript", "svelte"],
"[dart]": {
"editor.formatOnSave": true,
"editor.selectionHighlight": false,
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": false,
"editor.defaultFormatter": "Dart-Code.dart-code"
}
}
```
## OpenAPI generator
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). When you add a new or modify an existing endpoint, you must run the command below to update the client SDK.
```bash
npm run api:generate # Run from the `server` directory
```
You can find the generated client SDK in the `web/src/api` for Typescript SDK and `mobile/openapi` for Dart SDK.
## Database migrations
After making any changes in the `server/libs/database/src/entities`, a database migration need to run in order to register the changes in the database. Follow the steps below to create a new migration.
1. Attached to the server container shell.
2. Run
```bash
npm run typeorm -- migration:generate ./libs/database/src/<migration-name> -d libs/database/src/config/database.config.ts
```
3. Check if the migration file makes sense.
4. Move the migration file to folder `server/libs/database/src/migrations` in your code editor.

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

View File

@@ -0,0 +1,29 @@
---
sidebar_position: 2
---
# One-step installation
:::caution
This method is for evaluation purposes only. It is not recommended for production use. For production usage, please refer to the recommended installation method [here](/docs/installation/recommended-installation).
:::
In the shell, from a directory of your choice, run the following command:
```bash
curl -o- https://raw.githubusercontent.com/immich-app/immich/main/install.sh | bash
```
The script will perform the following actions:
1. Download [docker-compose.yml](https://github.com/immich-app/immich/blob/main/docker/docker-compose.yml), and the [.env](https://github.com/immich-app/immich/blob/main/docker/.env.example) file from the main branch of the [repository](https://github.com/immich-app/immich).
2. Populate the `.env` file with necessary information based on the current directory path.
3. Start the containers.
The web application will be available at `http://<machine-ip-address>:2283`, and the server URL for the mobile app will be `http://<machine-ip-address>:2283/api`
The directory which is used to store the library files is `./immich-data` relative to the current directory.
:::tip
For more information on how to use the application, please refer to the [Post Installation](/docs/usage/post-installation) guide.
:::

View File

@@ -0,0 +1,54 @@
---
sidebar_position: 4
---
# Portainer
Install Immich using Portainer's Stack feature.
1. Go to "**Stacks**" in the left sidebar.
2. Click on "**Add stack**".
3. Give the stack a name (i.e. Immich), and select "**Web Editor**" as the build method.
4. Copy the content of the `docker-compose.yml` file from the [GitHub repository](https://raw.githubusercontent.com/immich-app/immich/main/docker/docker-compose.yml).
5. Replace `.env` with `stack.env` for all containers that need to use environment variables in the web editor.
<img
src={require('./img/dot-env.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
/>
8. Click on "**Advanced Mode**" in the **Environment Variables** section.
<img
src={require('./img/env-1.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
/>
9. Copy the content of the `.env.example` file from the [GitHub repository](https://raw.githubusercontent.com/immich-app/immich/main/docker/.env.example) and paste into the editor.
10. Switch back to "**Simple Mode**".
<img
src={require('./img/env-2.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
/>
* Populate custom database information if necessary.
* Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
* Populate a secret value for `JWT_SECRET`. You can use the command below to generate a secure key:
```bash title="Generate secure JWT_SECRET key"
openssl rand -base64 128
```
11. Click on "**Deploy the stack**".
:::tip
For more information on how to use the application, please refer to the [Post Installation](/docs/usage/post-installation) guide.
:::

View File

@@ -0,0 +1,118 @@
---
sidebar_position: 3
---
# Recommended installation
This is the recommended installation method for production use.
### Step 1 - Download the required files
From a directory of your choice (e.g. `./immich-app`) run the following commands
```bash title="Get docker-compose.yml file"
wget https://raw.githubusercontent.com/immich-app/immich/main/docker/docker-compose.yml
```
```bash title="Get .env file"
wget -O .env https://raw.githubusercontent.com/immich-app/immich/main/docker/.env.example
```
### Step 2 - Populate the .env file with custom values
<details>
<summary>Example <code>.env</code> content</summary>
```bash
###################################################################################
# Database
###################################################################################
DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE_NAME=immich
# Optional Database settings:
# DB_PORT=5432
###################################################################################
# Redis
###################################################################################
REDIS_HOSTNAME=immich_redis
# Optional Redis settings:
# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_PASSWORD=
# REDIS_SOCKET=
###################################################################################
# Upload File Config
###################################################################################
UPLOAD_LOCATION=absolute_location_on_your_machine_where_you_want_to_store_the_backup
###################################################################################
# Log message level - [simple|verbose]
###################################################################################
LOG_LEVEL=simple
###################################################################################
# JWT SECRET
###################################################################################
# This JWT_SECRET is used to sign the authentication keys for user login
# You should set it to a long randomly generated value
# You can use this command to generate one: openssl rand -base64 128
JWT_SECRET=
###################################################################################
# Reverse Geocoding
####################################################################################
# DISABLE_REVERSE_GEOCODING=false
# Reverse geocoding is done locally which has a small impact on memory usage
# This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable
# This ranges from 0-3 with 3 being the most precise
# 3 - Cities > 500 population: ~200MB RAM
# 2 - Cities > 1000 population: ~150MB RAM
# 1 - Cities > 5000 population: ~80MB RAM
# 0 - Cities > 15000 population: ~40MB RAM
# REVERSE_GEOCODING_PRECISION=3
####################################################################################
# WEB - Optional
####################################################################################
# Custom message on the login page, should be written in HTML form.
# For example PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
PUBLIC_LOGIN_PAGE_MESSAGE="My Family Photos and Videos Backup Server"
```
</details>
* Populate custom database information if necessary.
* Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
* Populate a secret value for `JWT_SECRET`. You can use the command below to generate a secure key:
```bash title="Command to generate secure JWT_SECRET key"
openssl rand -base64 128
```
### Step 3 - Start the containers
```bash title="Start the containers using docker compose command"
docker-compose up -d # or `docker compose up -d` based on your docker-compose version
```
:::tip
For more information on how to use the application, please refer to the [Post Installation](/docs/usage/post-installation) guide.
:::

View File

@@ -0,0 +1,31 @@
---
sidebar_position: 1
---
# Requirements
Hardware and software requirements for Immich
## Software
- [Docker](https://docs.docker.com/get-docker/)
- [Docker Compose](https://docs.docker.com/compose/install/)
:::info Podman
You can also use Podman to run the application. However, additional configuration might be required on your end.
:::
## Hardware
- **OS**: Preferred unix-based operating system (Ubuntu, Debian, MacOS, etc). Windows works too, with [Docker Desktop on Windows](https://docs.docker.com/desktop/install/windows-install/)
- **RAM**: At least 2GB, preferred 4GB.
- **CPU**: At least 2 cores, preferred 4 cores.
## Installation methods
There are a couple installation methods that you can use to install the application. You can choose the one that suits you the best.
1. [One-step installation (Evaluation only)](/docs/installation/one-step-installation)
2. **[Docker Compose with manual configuration (Recommended)](/docs/installation/recommended-installation)**
3. [Portainer](/docs/installation/portainer-installation)
4. [Unraid (Community contribution)](/docs/installation/unraid-installation)

View File

@@ -0,0 +1,15 @@
---
sidebar_position: 5
---
# Unraid
Install Immich on Unraid.
:::info Community contribution
Please follow [this community contributed article](https://mfaz.dev/posts/immich-unraid/) to install Immich on Unraid.
:::
:::tip
For more information on how to use the application, please refer to the [Post Installation](/docs/usage/post-installation) guide.
:::

View File

@@ -1,5 +1,12 @@
---
sidebar_position: 5
sidebar_position: 4
---
# Mobile App Beta Program
# Mobile app Beta program
Join the beta release channel to test the latest update of the app
You can opt-in to join app beta release channel by following the links below:
* Android: Invitation link from [web](https://play.google.com/store/apps/details?id=app.alextran.immich) or from [mobile](https://play.google.com/store/apps/details?id=app.alextran.immich)
* iOS: [TestFlight invitation link](https://testflight.apple.com/join/1vYsAa8P)

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -1,7 +0,0 @@
---
sidebar_position: 1
---
# Introduction
This is the first

View File

@@ -0,0 +1,25 @@
---
sidebar_position: 1
---
# Introduction
Hello, I am glad you are here.
<p style={{textAlign: 'center'}}>
![Introduction Image](https://user-images.githubusercontent.com/27055614/182044984-2ee6d1ed-c4a7-4331-8a4b-64fcde77fe1f.png)
</p>
My name is Alex. I am an Electrical Engineer by schooling, then turned into a Software Engineer by trade and the pure love of problem solving.
We were lying in bed with our newborn, and my wife said, "We are starting to accumulate a lot of photos and videos of our baby, and I don't want to pay for **_App-Which-Must-Not-Be-Named_** anymore. You always want to build something for me, so why don't you build me an app which can do that?"
That was how the idea started to grow in my head. After that, I began to find existing solutions in the self-hosting space with similar backup functionality and the performance level of the **_App-Which-Must-Not-Be-Named_**. I found that the current solutions mainly focus on the gallery-type application. However, I want a simple-to-use backup tool with a native mobile app that can view photos and videos efficiently. So I set sail on this journey as a hungry engineer on the hunt.
Another motivation that pushed me to deliver my execution of the **_App-Which-Must-Not-Be-Named_** alternative or replacement is for contributing back to the open source community that I have greatly benefited from over the years.
I'm proud to share this creation with you, which values privacy, memories, and the joy of looking back at those moments in an easy-to-use and friendly interface.
If you like the application or it helps you in some way, please consider [supporting](./support-the-project.md) to the project. It will help me to continue to develop and maintain the application.

View File

@@ -0,0 +1,17 @@
---
sidebar_position: 2
---
# Logo meaning
Why the colorful flower, you ask?
I really like the Japanese culture, especially the books, history, and food. The current logo is a spin-off of [the Oda clan's symbol](https://en.wikipedia.org/wiki/Oda_clan).
![Oda_emblem](https://user-images.githubusercontent.com/27055614/182044504-a5ed33a8-5640-42de-b359-18fdbee9fb90.svg)
One of my favorite books is [Taikō](https://www.goodreads.com/book/show/336228.Taiko), it is a story about a prominent figure in the history of Japan, [Toyotomy Hideyoshi](https://www.britannica.com/biography/Toyotomi-Hideyoshi). He came from nothing, and through his resilience and wonderful mind, he has become one of the most powerful rulers in Japan's history. I enjoy his personality and the way he moved through life.
The color is an adaptation of **_App-Which-Must-Not-Be-Named_**'s color scheme, with an extra color (pink) to complete the flower's fifth petal. The petal layers are the same color scheme as the main layer rotating back and forth to "bring the flower to life."
![image](https://user-images.githubusercontent.com/27055614/182044984-2ee6d1ed-c4a7-4331-8a4b-64fcde77fe1f.png)

View File

@@ -1,5 +0,0 @@
---
sidebar_position: 2
---
# Logo meaning

View File

@@ -2,4 +2,19 @@
sidebar_position: 3
---
# Support the project
# Support the project
I've committed to this project, and I will not stop. I will keep updating the docs, adding new features, and fixing bugs. But I can't do it alone, so I need your help to give me additional motivation to keep going.
As our hosts in the [selfhosted.show - In the episode 'The-organization-which-must-not-be-named is a Hostile Actor'](https://selfhosted.show/79?t=1418) said, this is a massive undertaking that the team and I are doing. I would love to someday be able to do this full-time, and I am asking for your help to make that happen.
If you feel like this is the right cause and the app is something you see yourself using for a long time, please consider supporting the project with the options below.
## Donation
* Monthly donation via [GitHub Sponsors](https://github.com/sponsors/alextran1502)
* One-time donation via [Github Sponsors](https://github.com/sponsors/alextran1502?frequency=one-time&sponsor=alextran1502)
## Contribution
If you are a programmer/developer and the app's [technology stack](./technology-stack.md) is something you are familiar with, please consider contributing to the project. The team and I are always looking for new contributors. You can refer to the [contribution guildelines](/docs/contribution-guidelines) to start leaving your mark on the project.

View File

@@ -2,4 +2,22 @@
sidebar_position: 4
---
# Technology stack
# Technology stack
The app is built with the following technologies:
## Frontend
* [Flutter](https://flutter.dev/) for the mobile app
* [Riverpod](https://riverpod.dev/) as state management.
* [SvelteKit](https://kit.svelte.dev/) for the Web.
## Backend
* [Nest.js](https://nestjs.com/) for the server.
* [TypeORM](https://typeorm.io/) for database management.
* [PostgreSQL](https://www.postgresql.org/) for the database.
* [Redis](https://redis.io/) for communication between the core server and the microservices.
* [NGINX](https://www.nginx.com/) for internal communication between containers and load balancing when scaling.
## High level architecture
![Immich Architecture](./img/app-architecture.png)

View File

@@ -1,8 +0,0 @@
{
"label": "Tutorial - Basics",
"position": 6,
"link": {
"type": "generated-index",
"description": "5 minutes to learn the most important Docusaurus concepts."
}
}

View File

@@ -1,23 +0,0 @@
---
sidebar_position: 6
---
# Congratulations!
You have just learned the **basics of Docusaurus** and made some changes to the **initial template**.
Docusaurus has **much more to offer**!
Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**.
Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610)
## What's next?
- Read the [official documentation](https://docusaurus.io/)
- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config)
- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration)
- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout)
- Add a [search bar](https://docusaurus.io/docs/search)
- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase)
- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support)

View File

@@ -1,34 +0,0 @@
---
sidebar_position: 3
---
# Create a Blog Post
Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed...
## Create your first Post
Create a file at `blog/2021-02-28-greetings.md`:
```md title="blog/2021-02-28-greetings.md"
---
slug: greetings
title: Greetings!
authors:
- name: Joel Marcey
title: Co-creator of Docusaurus 1
url: https://github.com/JoelMarcey
image_url: https://github.com/JoelMarcey.png
- name: Sébastien Lorber
title: Docusaurus maintainer
url: https://sebastienlorber.com
image_url: https://github.com/slorber.png
tags: [greetings]
---
Congratulations, you have made your first post!
Feel free to play around and edit this post as much you like.
```
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).

View File

@@ -1,57 +0,0 @@
---
sidebar_position: 2
---
# Create a Document
Documents are **groups of pages** connected through:
- a **sidebar**
- **previous/next navigation**
- **versioning**
## Create your first Doc
Create a Markdown file at `docs/hello.md`:
```md title="docs/hello.md"
# Hello
This is my **first Docusaurus document**!
```
A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello).
## Configure the Sidebar
Docusaurus automatically **creates a sidebar** from the `docs` folder.
Add metadata to customize the sidebar label and position:
```md title="docs/hello.md" {1-4}
---
sidebar_label: 'Hi!'
sidebar_position: 3
---
# Hello
This is my **first Docusaurus document**!
```
It is also possible to create your sidebar explicitly in `sidebars.js`:
```js title="sidebars.js"
module.exports = {
tutorialSidebar: [
'intro',
// highlight-next-line
'hello',
{
type: 'category',
label: 'Tutorial',
items: ['tutorial-basics/create-a-document'],
},
],
};
```

View File

@@ -1,43 +0,0 @@
---
sidebar_position: 1
---
# Create a Page
Add **Markdown or React** files to `src/pages` to create a **standalone page**:
- `src/pages/index.js``localhost:3000/`
- `src/pages/foo.md``localhost:3000/foo`
- `src/pages/foo/bar.js``localhost:3000/foo/bar`
## Create your first React Page
Create a file at `src/pages/my-react-page.js`:
```jsx title="src/pages/my-react-page.js"
import React from 'react';
import Layout from '@theme/Layout';
export default function MyReactPage() {
return (
<Layout>
<h1>My React page</h1>
<p>This is a React page</p>
</Layout>
);
}
```
A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page).
## Create your first Markdown Page
Create a file at `src/pages/my-markdown-page.md`:
```mdx title="src/pages/my-markdown-page.md"
# My Markdown page
This is a Markdown page
```
A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page).

View File

@@ -1,31 +0,0 @@
---
sidebar_position: 5
---
# Deploy your site
Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**).
It builds your site as simple **static HTML, JavaScript and CSS files**.
## Build your site
Build your site **for production**:
```bash
npm run build
```
The static files are generated in the `build` folder.
## Deploy your site
Test your production build locally:
```bash
npm run serve
```
The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/).
You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**).

View File

@@ -1,146 +0,0 @@
---
sidebar_position: 4
---
# Markdown Features
Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**.
## Front Matter
Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/):
```text title="my-doc.md"
// highlight-start
---
id: my-doc-id
title: My document title
description: My document description
slug: /my-custom-url
---
// highlight-end
## Markdown heading
Markdown text with [links](./hello.md)
```
## Links
Regular Markdown links are supported, using url paths or relative file paths.
```md
Let's see how to [Create a page](/create-a-page).
```
```md
Let's see how to [Create a page](./create-a-page.md).
```
**Result:** Let's see how to [Create a page](./create-a-page.md).
## Images
Regular Markdown images are supported.
You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`):
```md
![Docusaurus logo](/img/docusaurus.png)
```
![Docusaurus logo](/img/docusaurus.png)
You can reference images relative to the current file as well, as shown in [the extra guides](../tutorial-extras/manage-docs-versions.md).
## Code Blocks
Markdown code blocks are supported with Syntax highlighting.
```jsx title="src/components/HelloDocusaurus.js"
function HelloDocusaurus() {
return (
<h1>Hello, Docusaurus!</h1>
)
}
```
```jsx title="src/components/HelloDocusaurus.js"
function HelloDocusaurus() {
return <h1>Hello, Docusaurus!</h1>;
}
```
## Admonitions
Docusaurus has a special syntax to create admonitions and callouts:
:::tip My tip
Use this awesome feature option
:::
:::danger Take care
This action is dangerous
:::
:::tip My tip
Use this awesome feature option
:::
:::danger Take care
This action is dangerous
:::
## MDX and React Components
[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**:
```jsx
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '20px',
color: '#fff',
padding: '10px',
cursor: 'pointer',
}}
onClick={() => {
alert(`You clicked the color ${color} with label ${children}`)
}}>
{children}
</span>
);
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
This is <Highlight color="#1877F2">Facebook blue</Highlight> !
```
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '20px',
color: '#fff',
padding: '10px',
cursor: 'pointer',
}}
onClick={() => {
alert(`You clicked the color ${color} with label ${children}`);
}}>
{children}
</span>
);
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
This is <Highlight color="#1877F2">Facebook blue</Highlight> !

View File

@@ -1,7 +0,0 @@
{
"label": "Tutorial - Extras",
"position": 6,
"link": {
"type": "generated-index"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1,55 +0,0 @@
---
sidebar_position: 1
---
# Manage Docs Versions
Docusaurus can manage multiple versions of your docs.
## Create a docs version
Release a version 1.0 of your project:
```bash
npm run docusaurus docs:version 1.0
```
The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created.
Your docs now have 2 versions:
- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs
- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs**
## Add a Version Dropdown
To navigate seamlessly across versions, add a version dropdown.
Modify the `docusaurus.config.js` file:
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
navbar: {
items: [
// highlight-start
{
type: 'docsVersionDropdown',
},
// highlight-end
],
},
},
};
```
The docs version dropdown appears in your navbar:
![Docs Version Dropdown](./img/docsVersionDropdown.png)
## Update an existing version
It is possible to edit versioned docs in their respective folder:
- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello`
- `docs/hello.md` updates `http://localhost:3000/docs/next/hello`

View File

@@ -1,88 +0,0 @@
---
sidebar_position: 2
---
# Translate your site
Let's translate `docs/intro.md` to French.
## Configure i18n
Modify `docusaurus.config.js` to add support for the `fr` locale:
```js title="docusaurus.config.js"
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
};
```
## Translate a doc
Copy the `docs/intro.md` file to the `i18n/fr` folder:
```bash
mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/
cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md
```
Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French.
## Start your localized site
Start your site on the French locale:
```bash
npm run start -- --locale fr
```
Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated.
:::caution
In development, you can only use one locale at a same time.
:::
## Add a Locale Dropdown
To navigate seamlessly across languages, add a locale dropdown.
Modify the `docusaurus.config.js` file:
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
navbar: {
items: [
// highlight-start
{
type: 'localeDropdown',
},
// highlight-end
],
},
},
};
```
The locale dropdown now appears in your navbar:
![Locale Dropdown](./img/localeDropdown.png)
## Build your localized site
Build your site for a specific locale:
```bash
npm run build -- --locale fr
```
Or build your site to include all the locales at once:
```bash
npm run build
```

View File

@@ -1,8 +1,8 @@
{
"label": "How to use the app",
"label": "How to use the application",
"position": 3,
"link": {
"type": "generated-index",
"description": "5 minutes to learn the most important Docusaurus concepts."
"description": "Quick start on how to use the app on mobile and the web"
}
}

View File

@@ -0,0 +1,35 @@
---
sidebar_position: 2
---
# Automatic Backup
A guide on how the foreground and background automatic backup works.
<img src={require('./img/background-foreground-backup.png').default} width="50%" title="Foreground&Background Backup" />
On iOS, there is only one option for automatic backup
* [**Foreground backup**](#foreground-backup)
On Android, there are two options for automatic backup
* [**Foreground backup**](#foreground-backup)
* [**Background backup**](#background-backup)
## Foreground backup
If foreground backup is enabled: whenever the app is opened or resumed, it will check if any photos or videos in the selected album(s) have yet to be uploaded to the cloud (the remainder count). If there are any, they will be uploaded.
## Background backup
Background backup is only available on Android thanks to the contribution effort of [@zoodyy](https://github.com/zoodyy).
If background backup is enabled. The app will periodically check if there are any new photos or videos in the selected album(s) to be uploaded to the cloud. If there are, it will upload them to the cloud in the background.
A native Android notification shows up when the background upload is in progress. You can further customize the notification by going to the app's settings.
:::note
* The app must be in the background for the backup worker to start running.
* It is a well-known problem that some Android models are very strict with battery optimization settings, which can cause a problem with the background worker. Please visit [Don't kill my app](https://dontkillmyapp.com/) for a guide on disabling this setting on your phone.
* If you reopen the app and the first page you see is the backup page, the counts will not reflect the background uploaded result. You have to navigate out of the page and come back to see the updated counts.
:::

View File

@@ -0,0 +1,76 @@
---
sidebar_position: 3
---
# Bulk Upload (Using the CLI)
You can use the CLI to upload an existing gallery to the Immich server
[Immich CLI Repository](https://github.com/immich-app/CLI)
## Requirements
- Node.js 16 or above
- Npm
## Installation
```bash
npm i -g immich
```
## Quick Start
Specify user's credentials, Immich's server address and port, and the directory you would like to upload videos/photos from.
```bash
immich upload --email testuser@email.com --password password --server http://192.168.1.216:2283/api -d your/target/directory
```
---
### Parameters
| Parameter | Description |
| ---------------- | ------------------------------------------------------------------- |
| --yes / -y | Assume yes on all interactive prompts |
| --delete / -da | Delete local assets after upload |
| --email / -e | User's email |
| --password / -pw | User's password |
| --server / -s | Immich's server address |
| --directory / -d | Directory to upload from |
| --threads / -t | Number of threads to use (Default 5) |
| --album/ -al | Create albums for assets based on the parent folder or a given name |
### Run via Docker
Be aware that as this runs inside a container it mounts your current directory as a volume, and for the -d flag you need to use the path inside the container.
```bash
docker run -it --rm -v $(pwd):/import ghcr.io/immich-app/immich-cli:latest upload --email testuser@email.com --password password --server http://192.168.1.216:2283/api -d /import
```
Optionally, you can create an alias:
```bash
alias immich="docker run -it --rm -v $(pwd):/import ghcr.io/immich-app/immich-cli:latest"
immich upload --email testuser@email.com --password password --server http://192.168.1.216:2283/api -d /import
```
### Run from source
```bash title="Clone Repository"
git clone https://github.com/immich-app/CLI
```
```bash title="Install dependencies"
npm install
```
```bash title="Build the project"
npm run build
```
```bash title="Run the command"
node bin/index.js upload --email testuser@email.com --password password --server http://192.168.1.216:2283/api -d your/target/directory
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

76
docs/docs/usage/oauth.md Normal file
View File

@@ -0,0 +1,76 @@
---
sidebar_position: 5
---
# OAuth Authentication
This page contains details about using OAuth 2 in Immich.
## Overview
Immich supports 3rd party authentication via [OpenID Connect][oidc] (OIDC), an identity layer built on top of OAuth2. OIDC is supported by most identity providers, including:
- [Authentik](https://goauthentik.io/integrations/sources/oauth/#openid-connect)
- [Authelia](https://www.authelia.com/configuration/identity-providers/open-id-connect/)
- [Okta](https://www.okta.com/openid-connect/)
- [Google](https://developers.google.com/identity/openid-connect/openid-connect)
## Prerequisites
Before enabling OAuth in Immich, a new client application needs to be configured in the 3rd-party authentication server. While the specifics of this setup vary from provider to provider, the general approach should be the same.
1. Create a new (Client) Application
1. The **Provider** type should be `OpenID Connect` or `OAuth2`
2. The **Client type** should be `Confidential`
3. The **Application** type should be `Web`
4. The **Grant** type should be `Authorization Code`
2. Configure Redirect URIs/Origins
The **Sign-in redirect URIs** should include:
* All URLs that will be used to access the login page of the Immich web client (eg. `http://localhost:2283/auth/login`, `http://192.168.0.200:2283/auth/login`, `https://immich.example.com/auth/login`)
* Mobile app redirect URL `app.immich:/`
:::caution
You **MUST** include `app.immich:/` as the redirect URI for iOS and Android mobile app to work properly.
**Authentik example**
<img src={require('./img/authentik-redirect.png').default} title="Authentik Redirection URL" width="80%" />
:::
## Enable OAuth
Once you have a new OAuth client application configured, Immich can be configured using the following environment variables:
| Key | Type | Default | Description |
| ------------------- | ------- | -------------------- | ------------------------------------------------------------------------- |
| OAUTH_ENABLED | boolean | false | Enable/disable OAuth2 |
| OAUTH_ISSUER_URL | URL | (required) | Required. Self-discovery URL for client (from previous step) |
| OAUTH_CLIENT_ID | string | (required) | Required. Client ID (from previous step) |
| OAUTH_CLIENT_SECRET | string | (required) | Required. Client Secret (previous step) |
| OAUTH_SCOPE | string | openid email profile | Full list of scopes to send with the request (space delimited) |
| OAUTH_AUTO_REGISTER | boolean | true | When true, will automatically register a user the first time they sign in |
| OAUTH_BUTTON_TEXT | string | Login with OAuth | Text for the OAuth button on the web |
:::info
The Issuer URL should look something like the following, and return a valid json document.
- `https://accounts.google.com/.well-known/openid-configuration`
- `http://localhost:9000/application/o/immich/.well-known/openid-configuration`
The `.well-known/openid-configuration` part of the url is optional and will be automatically added during discovery.
:::
Here is an example of a valid configuration for setting up Immich to use OAuth with Authentik:
```
OAUTH_ENABLED=true
OAUTH_ISSUER_URL=http://192.168.0.187:9000/application/o/immich
OAUTH_CLIENT_ID=f08f9c5b4f77dcfd3916b1c032336b5544a7b368
OAUTH_CLIENT_SECRET=6fe2e697644da6ff6aef73387a457d819018189086fa54b151a6067fbb884e75f7e5c90be16d3c688cf902c6974817a85eab93007d76675041eaead8c39cf5a2
OAUTH_BUTTON_TEXT=Login with Authentik
```
[oidc]: https://openid.net/connect/

View File

@@ -0,0 +1,57 @@
---
sidebar_position: 1
---
# Post Installation
This page contains information about what to do after you have installed the application.
## Step 1 - Download the mobile app
The mobile app can be downloaded from
- [Google Play Store](https://play.google.com/store/apps/details?id=app.alextran.immich)
- [Apple App Store](https://apps.apple.com/us/app/immich/id1613945652)
- [F-Droid](https://f-droid.org/packages/app.alextran.immich)
## Step 2 - Register the admin user
The first user to register will be the admin user. The admin user will be able to add other users to the application.
To register for the admin user, access the web application at `http://<machine-ip-address>:2283` and click on the **Getting Started** button.
<img src={require('./img/admin-registration-form.png').default} width="500" title="Admin Registration" />
Follow the prompts to register as the admin user and log in to the application.
## Step 3 - Create a new user (optional)
If you have a family member who wants to use the application, you can create a new account. The default password is `password`, and the user can change their password after logging in to the application for the first time.
<img src={require('./img/create-new-user.png').default} title="Admin Registration" />
## Step 4 - Access the mobile app
Login to the mobile app with the server endpoint URL at `http://<machine-ip-address>:2283/api`
<img src={require('./img/sign-in-phone.jpeg').default} width="50%" title="Mobile App Sign In" />
## Step 5 - Back up your photos and videos
Navigate to the backup screen by clicking on the cloud icon in the top right corner of the screen.
<img src={require('./img/backup-header.png').default} width="50%" title="Backup button" />
You can select which album(s) you want to back up to the Immich server from the backup screen.
<img src={require('./img/album-selection.png').default} width="50%" title="Backup button" />
Scroll down to the bottom and press "**Start Backup**" to start the backup process.
You can also enable auto foreground or background backup (only on Android). For more information about the app mechanism, please visit the next pages.
:::tip Application Mechanism
#### [Foreground and background backup](/docs/usage/automatic-backup)
#### [Bulk upload (using the CLI)](/docs/usage/bulk-upload)
:::

11
docs/docs/usage/update.md Normal file
View File

@@ -0,0 +1,11 @@
---
sidebar_position: 4
---
# Update the application
If you are using Docker Compose, update the application use the following commands in the directory where the `docker-compose.yml` file is located:
```bash title="Update Immich"
docker-compose pull && docker-compose up -d # Or `docker compose`
```

View File

@@ -6,9 +6,9 @@ const darkCodeTheme = require("prism-react-renderer/themes/dracula");
/** @type {import('@docusaurus/types').Config} */
const config = {
title: "Immich Documentation",
title: "Immich",
tagline:
"Self-hosted photo and video backup solution directly from your mobile phone",
"High performance self-hosted photo and video backup solution directly from your mobile phone",
url: "https://documentation.immich.app",
baseUrl: "/",
onBrokenLinks: "throw",
@@ -34,19 +34,18 @@ const config = {
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
showLastUpdateAuthor: true,
showLastUpdateTime: true,
sidebarPath: require.resolve("./sidebars.js"),
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/",
},
blog: {
showReadingTime: true,
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/",
editUrl: "https://github.com/immich-app/immich/tree/main/docs/",
},
// blog: {
// showReadingTime: true,
// editUrl: "https://github.com/immich-app/immich/tree/main/docs/",
// },
theme: {
customCss: require.resolve("./src/css/custom.css"),
},
@@ -57,16 +56,23 @@ const config = {
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
announcementBar: {
id: "site_announcement_immich",
content: `⚠️ The project is under <strong>very active</strong> development. Expect bugs and changes. Do not use it as <strong>the only way</strong> to store your photos and videos!`,
backgroundColor: "#593f00",
textColor: "#ffefc9",
isCloseable: false,
},
docs: {
sidebar: {
autoCollapseCategories: false,
},
},
navbar: {
title: "Immich",
logo: {
alt: "Immich University Logo",
src: "img/logo.png",
src: "img/color-logo.png",
srcDark: "img/logo.png",
},
items: [
{
@@ -83,7 +89,7 @@ const config = {
],
},
footer: {
style: "dark",
style: "light",
links: [
{
title: "Overview",
@@ -121,7 +127,7 @@ const config = {
],
},
],
copyright: `Alex Tran - For my family`,
copyright: `Immich is available as open source under the terms of the MIT License.`,
},
prism: {
theme: lightCodeTheme,

35
docs/package-lock.json generated
View File

@@ -10356,31 +10356,20 @@
}
},
"node_modules/serve-handler": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz",
"integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==",
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz",
"integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==",
"dependencies": {
"bytes": "3.0.0",
"content-disposition": "0.5.2",
"fast-url-parser": "1.1.3",
"mime-types": "2.1.18",
"minimatch": "3.0.4",
"minimatch": "3.1.2",
"path-is-inside": "1.0.2",
"path-to-regexp": "2.2.1",
"range-parser": "1.2.0"
}
},
"node_modules/serve-handler/node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/serve-handler/node_modules/path-to-regexp": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
@@ -19878,28 +19867,20 @@
}
},
"serve-handler": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz",
"integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==",
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz",
"integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==",
"requires": {
"bytes": "3.0.0",
"content-disposition": "0.5.2",
"fast-url-parser": "1.1.3",
"mime-types": "2.1.18",
"minimatch": "3.0.4",
"minimatch": "3.1.2",
"path-is-inside": "1.0.2",
"path-to-regexp": "2.2.1",
"range-parser": "1.2.0"
},
"dependencies": {
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"path-to-regexp": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",

View File

@@ -4,10 +4,11 @@
* work well for content-centric websites.
*/
@import url("https://fonts.googleapis.com/css2?family=Work+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Snowburst+One&display=swap");
html {
font-family: "Work Sans", sans-serif;
font-family: "Overpass", sans-serif;
}
/* You can override the default Infima variables here. */

View File

@@ -5,10 +5,13 @@
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
height: 40rem;
text-align: center;
background: #606c88;
background: -webkit-linear-gradient(to top, #4e5362, #606c88);
background: linear-gradient(to top, #4e5362, #606c88);
color: whitesmoke;
}
@media screen and (max-width: 996px) {
@@ -22,3 +25,42 @@
align-items: center;
justify-content: center;
}
.buttonsRow {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
margin-bottom: 4rem;
gap: 1rem;
}
.installButton {
background-color: #adcbfa;
color: #000000;
border-radius: 50px;
}
.installButton:hover {
color: #000000;
}
.introButton {
background-color: #e6ebf5;
color: #000000;
border-radius: 50px;
}
.introButton:hover {
color: #000000;
}
.demoButton {
background-color: aquamarine;
color: #000000;
border-radius: 50px;
}
.demoButton:hover {
color: #000000;
}

View File

@@ -12,16 +12,46 @@ function HomepageHeader() {
return (
<header className={clsx("hero hero--primary", styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<h1
className="hero__title"
style={{
fontFamily: "Snowburst One",
color: "#adcbfa",
}}
>
IMMICH
</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="docs/installation/requirements"
>
Getting Started
</Link>
<div className={styles.buttonsRow}>
<div className={styles.buttons}>
<Link
className={clsx("button button--lg", styles.introButton)}
to="docs/overview/introduction"
>
Introduction
</Link>
</div>
<div className={styles.buttons}>
<Link
className={clsx("button button--lg", styles.installButton)}
to="docs/installation/requirements"
>
Installation
</Link>
</div>
<div className={styles.buttons}>
<Link
className={clsx("button button--lg", styles.demoButton)}
to="https://demo.immich.app/"
>
Demo
</Link>
</div>
</div>
<img src="/img/immich-screenshots.webp" alt="logo" />
</div>
</header>
);
@@ -31,13 +61,11 @@ export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={`${siteConfig.title}`}
description="Description will go into a meta tag in <head />"
title={`Home`}
description="immich Self-hosted photo and video backup solution directly from your mobile phone "
>
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
<main>{/* <HomepageFeatures /> */}</main>
</Layout>
);
}

1
docs/static/img/cloud-done.svg vendored Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" fill="#4250af"><path d="M12.65 39q-4 0-6.825-2.825T3 29.3q0-3.7 2.5-6.475Q8 20.05 11.6 19.7q.75-4.65 4.275-7.65 3.525-3 8.225-3 5.2 0 8.825 3.775Q36.55 16.6 36.55 21.9v1.9h.6q3.3-.1 5.575 2.075Q45 28.05 45 31.4q0 3.1-2.25 5.35Q40.5 39 37.4 39Zm7.95-6.2q.3 0 .55-.125.25-.125.5-.325l8.95-9q.3-.3.325-.75.025-.45-.325-.75-.3-.35-.75-.35t-.75.35l-8.45 8.4-4.05-4.05q-.3-.25-.75-.275-.45-.025-.75.275-.35.35-.35.8 0 .45.35.75l4.55 4.6q.2.2.45.325t.5.125Zm-7.95 3.95H37.4q2.2 0 3.775-1.575Q42.75 33.6 42.75 31.4t-1.575-3.75Q39.6 26.1 37.4 26.1h-3.1v-4.2q0-4.4-3.025-7.5-3.025-3.1-7.375-3.1-4.3 0-7.35 3.1t-3.05 7.5h-1q-2.95 0-5.1 2.15-2.15 2.15-2.15 5.3 0 3.1 2.175 5.25t5.225 2.15ZM24 24Z"/></svg>

After

Width:  |  Height:  |  Size: 756 B

1
docs/static/img/cloud-off.svg vendored Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" fill="#4250af"><path d="m42.15 37.1-1.8-1.8q1.15-.8 1.775-1.8t.625-2.4q0-2.1-1.525-3.625T37.55 25.95H34.3V21.9q0-4.3-3.025-7.275-3.025-2.975-7.325-2.975-1.4 0-2.925.425T18.2 13.45l-1.6-1.65q1.8-1.3 3.6-1.85t3.7-.55q5.25 0 8.95 3.7 3.7 3.7 3.7 8.9v1.75h.6q3.3-.05 5.575 2.05Q45 27.9 45 31.1q0 1.55-.675 3.2-.675 1.65-2.175 2.8Zm-1.75 6.55-5-5.05H12.55q-4.05 0-6.8-2.725T3 29.1q0-3.85 2.525-6.4 2.525-2.55 6.075-2.9.05-.75.375-1.875T12.8 16L5.55 8.75q-.3-.3-.325-.775Q5.2 7.5 5.55 7.15q.35-.35.8-.35.45 0 .8.35l34.9 34.9q.3.3.325.775.025.475-.325.825-.35.35-.825.35t-.825-.35Zm-27.85-7.3h20.6L14.6 17.8q-.55.85-.825 1.975Q13.5 20.9 13.5 22h-.95q-3.05 0-5.175 2T5.25 29q0 3.05 2.125 5.2 2.125 2.15 5.175 2.15ZM29.3 24.4ZM23.85 27Z"/></svg>

After

Width:  |  Height:  |  Size: 799 B

1
docs/static/img/cloud.svg vendored Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" fill="#4250af"><path d="M12.65 39q-4 0-6.825-2.825T3 29.3q0-3.65 2.45-6.45 2.45-2.8 6.15-3.15.75-4.65 4.275-7.65 3.525-3 8.225-3 5.2 0 8.825 3.775Q36.55 16.6 36.55 21.9v1.9h.6q3.3-.1 5.575 2.075Q45 28.05 45 31.4q0 3.1-2.25 5.35Q40.5 39 37.4 39Zm0-2.25H37.4q2.2 0 3.775-1.575Q42.75 33.6 42.75 31.4t-1.575-3.75Q39.6 26.1 37.4 26.1h-3.1v-4.2q0-4.4-3.025-7.5-3.025-3.1-7.375-3.1-4.3 0-7.35 3.1t-3.05 7.5h-.95q-3.05 0-5.175 2.15t-2.125 5.3q0 3.05 2.175 5.225t5.225 2.175ZM24 24Z"/></svg>

After

Width:  |  Height:  |  Size: 545 B

BIN
docs/static/img/color-logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/static/img/immich-screenshots.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

View File

@@ -1,43 +1,42 @@
# Build stage
FROM node:16-bullseye-slim as builder
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN apt-get update
RUN apt-get install gcc g++ make cmake python3 python3-pip ffmpeg -y
COPY package.json package-lock.json ./
RUN npm ci
RUN npm rebuild @tensorflow/tfjs-node --build-from-source
COPY . .
FROM builder as prod
RUN npm run build
RUN npm prune --omit=dev
# Prod stage
FROM node:16-bullseye-slim
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
COPY entrypoint.sh ./
RUN mkdir -p /usr/src/app/dist \
&& mkdir -p /usr/src/app/node_modules \
&& apt-get update \
RUN apt-get update \
&& apt-get install -y ffmpeg \
&& rm -rf /var/cache/apt/lists
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/dist ./dist
COPY --from=prod /usr/src/app/node_modules ./node_modules
COPY --from=prod /usr/src/app/dist ./dist
RUN npm prune --production
COPY package.json package-lock.json ./
COPY entrypoint.sh ./
# CMD [ "node", "dist/main" ]
# CMD [ "node", "dist/main" ]

View File

@@ -33,7 +33,7 @@ if (keystorePropertiesFile.exists()) {
android {
compileSdkVersion flutter.compileSdkVersion
compileSdkVersion 33
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -52,7 +52,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "app.alextran.immich"
minSdkVersion 23
targetSdkVersion flutter.targetSdkVersion
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

View File

@@ -12,21 +12,35 @@
</intent-filter>
</activity>
<activity
android:name="com.linusu.flutter_web_auth.CallbackActivity"
android:exported="true">
<intent-filter android:label="flutter_web_auth">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="app.immich" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data android:name="flutterEmbedding" android:value="2" />
<!-- Disables default WorkManager initialization to use our custom initialization -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove">
</provider>
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove"></provider>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- If you want to read images-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- If you want to read videos-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- If you want to read audio-->
<queries>
<intent>

View File

@@ -50,6 +50,7 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
private var timeBackupStarted: Long = 0L
private var notificationBuilder: NotificationCompat.Builder? = null
private var notificationDetailBuilder: NotificationCompat.Builder? = null
private var fgFuture: ListenableFuture<Void>? = null
override fun startWork(): ListenableFuture<ListenableWorker.Result> {
@@ -112,6 +113,7 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
Handler(Looper.getMainLooper()).postAtFrontOfQueue {
backgroundChannel.invokeMethod("systemStop", null)
}
waitOnSetForegroundAsync()
// cannot await/get(block) on resolvableFuture as its already cancelled (would throw CancellationException)
// instead, wait for 5 seconds until forcefully stopping backup work
Handler(Looper.getMainLooper()).postDelayed({
@@ -119,15 +121,27 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
}, 5000)
}
private fun waitOnSetForegroundAsync() {
val fgFuture = this.fgFuture
if (fgFuture != null && !fgFuture.isCancelled() && !fgFuture.isDone()) {
try {
fgFuture.get(500, TimeUnit.MILLISECONDS)
}
catch (e: Exception) {
// ignored, there is nothing to be done
}
}
}
private fun stopEngine(result: Result?) {
clearBackgroundNotification()
engine?.destroy()
engine = null
if (result != null) {
Log.d(TAG, "stopEngine result=${result}")
resolvableFuture.set(result)
}
engine?.destroy()
engine = null
clearBackgroundNotification()
waitOnSetForegroundAsync()
}
override fun onMethodCall(call: MethodCall, r: MethodChannel.Result) {
@@ -207,8 +221,8 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
private fun showInfo(notification: Notification, isDetail: Boolean = false) {
val id = if(isDetail) NOTIFICATION_DETAIL_ID else NOTIFICATION_ID
if (isIgnoringBatteryOptimizations) {
setForegroundAsync(ForegroundInfo(id, notification))
if (isIgnoringBatteryOptimizations && !isDetail) {
fgFuture = setForegroundAsync(ForegroundInfo(id, notification))
} else {
notificationManager.notify(id, notification)
}

View File

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

View File

@@ -0,0 +1,6 @@
* Reduce app startup time by loading Hive boxes in parallel
* Throttle detail progress notifications & wait on foregroundInfo
* Throttle all background backup progress notifications
* Add selected assets to album
* Enhanced vertical swiping motion in image viewer
* Enhance the bottom app bar on the home page

View File

@@ -0,0 +1 @@
* Local assets are now shown in the app

View File

@@ -0,0 +1,3 @@
* Added OAuth login option
* Tidy-up dependencies, remove unused, replace rarely used ones
* Added view LivePhotos feature

View File

@@ -0,0 +1,2 @@
* Fixed freezed splash screen
* Fixed OIDC redirect but not logging in

View File

@@ -0,0 +1,2 @@
* Show human readable file size in detail view
* Fix permission issue on Android 33

View File

@@ -0,0 +1,6 @@
* Use binary prefixes for data sizes
* Fix not able to show device asset on Android 13
* Use cached asset info if unchanged instead of downloading all assets
* Add in-app logging
* Add search mechanism to album selection page
* Improve UI

View File

@@ -15,7 +15,7 @@ Once set up, this app can be used as photo and video backup solution directly fr
* Object detection based on COCO SSD.
* Search assets based on tags and exif data (lens, make, model, orientation)
* Upload assets from your local computer/server using <a href='https://www.npmjs.com/package/immich' target='_blank' rel='nofollow'>immich cli tools</a>
* [Optional] Reserve geocoding using Mapbox (Generous free-tier of 100,000 search/month)
* Reverse geocoding from image exif data
* Show asset's location information on map (OpenStreetMap).
* Show curated places on the search page
* Show curated objects on the search page

View File

@@ -5,17 +5,17 @@
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000233">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000345">
</testcase>
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="61.699536">
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="123.14891">
</testcase>
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="46.210553">
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="39.270764">
</testcase>

View File

@@ -1,3 +1,3 @@
This is a client app for Immich Server and you will need to run/manage the server on your own in order to use the app.
Github URL: https://github.com/alextran1502/immich
Github URL: https://github.com/immich-app/immich

View File

@@ -17,7 +17,7 @@
"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_select_albums": "Select albums",
"backup_album_selection_page_selection_info": "Selection Info",
"backup_album_selection_page_total_assets": "Total unique assets",
"backup_all": "All",
@@ -109,7 +109,9 @@
"login_form_err_invalid_email": "Invalid Email",
"login_form_err_leading_whitespace": "Leading whitespace",
"login_form_err_trailing_whitespace": "Trailing whitespace",
"login_form_failed_login": "Error logging you in, check server url, email and password",
"login_form_failed_login": "Error logging you in, check server URL, email and password",
"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_label_email": "Email",
"login_form_label_password": "Password",
"login_form_password_hint": "password",
@@ -118,6 +120,7 @@
"profile_drawer_client_server_up_to_date": "Client and Server are up-to-date",
"profile_drawer_settings": "Settings",
"profile_drawer_sign_out": "Sign Out",
"profile_drawer_app_logs": "Logs",
"search_bar_hint": "Search your photos",
"search_page_no_objects": "No Objects Info Available",
"search_page_no_places": "No Places Info Available",
@@ -171,5 +174,11 @@
"version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89",
"experimental_settings_title": "Experimental",
"experimental_settings_subtitle": "Use at your own risk!"
"experimental_settings_subtitle": "Use at your own risk!",
"control_bottom_app_bar_add_to_album": "Add to album",
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the 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"
}

View File

@@ -1,6 +1,9 @@
{
"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": "앨범에서 나가지 못했습니다",
@@ -9,6 +12,8 @@
"album_viewer_appbar_share_leave": "앨범 나가기",
"album_viewer_appbar_share_remove": "앨범에서 제거",
"album_viewer_page_share_add_users": "사용자 추가",
"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": "미디어파일은 여러 앨범에 분산될 수 있습니다. 따라서 백업 프로세스 중에 앨범에서 포함하거나 제외할 수 있습니다.",
@@ -16,25 +21,29 @@
"backup_album_selection_page_selection_info": "선택 정보",
"backup_album_selection_page_total_assets": "총 미디어파일 수",
"backup_all": "모두",
"backup_background_service_default_notification": "새 미디어파일 확인중...",
"backup_background_service_upload_failure_notification": "{} 업로드 실패",
"backup_background_service_in_progress_notification": "미디어파일 백업 중...",
"backup_background_service_current_upload_notification": "{} 업로드 중",
"backup_background_service_error_title": "백업 오류",
"backup_background_service_connection_failed_message": "서버에 연결하지 못했습니다. 다시 시도하는 중...",
"backup_background_service_backup_failed_message": "미디어파일을 백업하지 못했습니다. 다시 시도하는 중...",
"backup_background_service_connection_failed_message": "서버에 연결하지 못했습니다. 다시 시도하는 중...",
"backup_background_service_current_upload_notification": "{} 업로드 중",
"backup_background_service_default_notification": "새 미디어파일 확인중...",
"backup_background_service_error_title": "백업 오류",
"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": "배터리 최적화",
"backup_controller_page_background_charging": "충전 중일 때만",
"backup_controller_page_background_configure_error": "백그라운드 서비스를 구성하지 못했습니다",
"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_background_description": "백그라운드 서비스를 켜서 앱을 열지 않고도 새 미디어파일을 자동으로 백업합니다.",
"backup_controller_page_background_wifi": "WiFi에서만",
"backup_controller_page_background_charging": "충전 중일 때만",
"backup_controller_page_background_is_on": "자동 백그라운드 백업이 켜져 있습니다",
"backup_controller_page_background_is_off": "자동 백그라운드 백업이 꺼져 있습니다",
"backup_controller_page_background_turn_on": "백그라운드 서비스 켜기",
"backup_controller_page_background_turn_off": "백그라운드 서비스 끄기",
"backup_controller_page_background_configure_error": "백그라운드 서비스를 구성하지 못했습니다",
"backup_controller_page_cancel": "취소",
"backup_controller_page_created": "생성일: {}",
"backup_controller_page_desc_backup": "새 미디어파일을 서버에 자동으로 업로드하려면 백업을 켜주세요.",
@@ -60,9 +69,28 @@
"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": "앨범 생성",
"control_bottom_app_bar_delete": "삭제",
"create_shared_album_page_share": "공유",
"control_bottom_app_bar_share": "공유",
"create_album_page_untitled": "제목없음",
"create_shared_album_page_create": "만들기",
"create_shared_album_page_share": "공유",
"create_shared_album_page_share_add_assets": "사진 추가",
"create_shared_album_page_share_select_photos": "사진 선택",
"daily_title_text_date": "E, M월 d일",
@@ -75,6 +103,12 @@
"exif_bottom_sheet_description": "설명 추가...",
"exif_bottom_sheet_details": "상세정보",
"exif_bottom_sheet_location": "위치",
"experimental_settings_subtitle": "문제시 책임지지 않습니다!",
"experimental_settings_title": "실험적기능",
"home_page_add_to_album_conflicts": "{album} 앨범에 {added} 미디어를 추가했습니다. {failed} 이미 앨범에 있는 항목입니다.",
"home_page_add_to_album_success": "{album} 앨범에 {added} 미디어를 추가했습니다. ",
"library_page_albums": "앨범",
"library_page_new_album": "새 앨범",
"login_form_button_text": "로그인",
"login_form_email_hint": "youremail@email.com",
"login_form_endpoint_hint": "https://your-server-ip:port/api",
@@ -90,8 +124,8 @@
"login_form_save_login": "로그인상태 유지",
"monthly_title_text_date_format": "y년 M월",
"profile_drawer_client_server_up_to_date": "클라이언트와 서버가 최신 상태입니다",
"profile_drawer_sign_out": "로그아웃",
"profile_drawer_settings": "설정",
"profile_drawer_sign_out": "로그아웃",
"search_bar_hint": "사진 검색",
"search_page_no_objects": "발견된 사물이\n없습니다",
"search_page_no_places": "발견된 장소가\n없습니다",
@@ -101,52 +135,47 @@
"select_additional_user_for_sharing_page_suggestions": "초대 가능한 사용자 제안",
"select_user_for_sharing_page_err_album": "앨범 생성 실패",
"select_user_for_sharing_page_share_suggestions": "초대 가능한 사용자 제안",
"setting_notifications_notify_failures_grace_period": "백그라운드 백업 실패 알림: {}",
"setting_notifications_notify_hours": "{}시간 뒤",
"setting_notifications_notify_immediately": "즉시",
"setting_notifications_notify_minutes": "{}분 뒤",
"setting_notifications_notify_never": "알리지 않음",
"setting_notifications_single_progress_subtitle": "미디어별 상세 진행률 표시",
"setting_notifications_single_progress_title": "백그라운드 작업 세부 진행률 표시",
"setting_notifications_subtitle": "알림 기본 설정 조정",
"setting_notifications_title": "알림",
"setting_notifications_total_progress_subtitle": "전체 업로드 진행률(완료/전체)",
"setting_notifications_total_progress_title": "백그라운드 작업 전체 진행률 표시",
"setting_pages_app_bar_settings": "설정",
"share_add": "추가",
"share_add_photos": "사진 추가",
"share_add_title": "새 앨범제목",
"share_create_album": "앨범 만들기",
"share_dialog_preparing": "준비중...",
"share_invite": "앨범에 초대",
"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": "공유",
"tab_controller_nav_library": "라이브러리",
"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": "디테일 이미지 뷰어 품질 조정",
"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": "이 기능은 로딩 성능을 향상시킬 수 있지만 훨씬 더 많은 데이터를 사용합니다.",
"theme_setting_three_stage_loading_title": "3단계 로딩 활성화",
"version_announcement_overlay_ack": "승인",
"version_announcement_overlay_release_notes": "릴리스 정보",
"version_announcement_overlay_text_1": "안녕하세요!",
"version_announcement_overlay_text_2": "앱에 새로운 업데이트가 있습니다!",
"version_announcement_overlay_text_3": "특히 WatchTower 또는 서버 응용 프로그램 자동 업데이트를 처리하는 메커니즘을 사용하는 경우 잘못된 구성을 방지하기 위해 docker-compose 및 .env 설정이 최신 상태인지 확인하세요.",
"version_announcement_overlay_title": "새 서버 버전 사용 가능 \uD83C\uDF89",
"album_thumbnail_card_item": "1개 항목",
"album_thumbnail_card_items": "{}개 항목",
"album_thumbnail_card_shared": " · 공유",
"library_page_albums": "앨범",
"library_page_new_album": "새 앨범",
"create_album_page_untitled": "제목없음",
"share_dialog_preparing": "준비중...",
"control_bottom_app_bar_share": "공유",
"setting_pages_app_bar_settings": "설정",
"theme_setting_theme_title": "테마",
"theme_setting_theme_subtitle": "앱테마 선택",
"theme_setting_system_theme_switch": "자동(시스템 설정에 따름)",
"theme_setting_dark_mode_switch": "다크모드",
"theme_setting_image_viewer_quality_title": "이미지 뷰어 품질",
"theme_setting_image_viewer_quality_subtitle": "디테일 이미지 뷰어 품질 조정",
"theme_setting_three_stage_loading_title": "3단계 로딩 활성화",
"theme_setting_three_stage_loading_subtitle": "이 기능은 로딩 성능을 향상시킬 수 있지만 훨씬 더 많은 데이터를 사용합니다.",
"asset_list_settings_title": "사진 배열",
"asset_list_settings_subtitle": "사진 배열 레이아웃 설정",
"theme_setting_asset_list_storage_indicator_title": "미디어 타일에 스토리지 싱크여부 표시",
"theme_setting_asset_list_tiles_per_row_title": "한 줄에 표시할 미디어 수 ({})",
"setting_notifications_title": "알림",
"setting_notifications_subtitle": "알림 기본 설정 조정",
"setting_notifications_notify_failures_grace_period": "백그라운드 백업 실패 알림: {}",
"setting_notifications_notify_immediately": "즉시",
"setting_notifications_notify_minutes": "{}분 뒤",
"setting_notifications_notify_hours": "{}시간 뒤",
"setting_notifications_notify_never": "알리지 않음"
"version_announcement_overlay_title": "새 서버 버전 사용 가능 🎉"
}

Binary file not shown.

View File

@@ -3,6 +3,8 @@ PODS:
- flutter_udid (0.0.1):
- Flutter
- SAMKeychain
- flutter_web_auth (0.5.0):
- Flutter
- fluttertoast (0.0.2):
- Flutter
- Toast
@@ -37,6 +39,7 @@ PODS:
DEPENDENCIES:
- Flutter (from `Flutter`)
- 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`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
@@ -60,6 +63,8 @@ EXTERNAL SOURCES:
:path: Flutter
flutter_udid:
:path: ".symlinks/plugins/flutter_udid/ios"
flutter_web_auth:
:path: ".symlinks/plugins/flutter_web_auth/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
image_picker_ios:
@@ -86,6 +91,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_udid: 0848809dbed4c055175747ae6a45a8b4f6771e1c
flutter_web_auth: c25208760459cec375a3c39f6a8759165ca0fa4d
fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb

View File

@@ -360,7 +360,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 62;
CURRENT_PROJECT_VERSION = 72;
DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -495,7 +495,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 62;
CURRENT_PROJECT_VERSION = 72;
DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -522,7 +522,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 62;
CURRENT_PROJECT_VERSION = 72;
DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;

View File

@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.30.1</string>
<string>1.36.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>62</string>
<string>72</string>
<key>LSRequiresIPhoneOS</key>
<true />
<key>MGLMapboxMetricsEnabledSettingShownInApp</key>

View File

@@ -0,0 +1,23 @@
#!/bin/sh
# The default execution directory of this script is the ci_scripts directory.
cd $CI_WORKSPACE/mobile
# Install Flutter using git.
git clone https://github.com/flutter/flutter.git --depth 1 -b stable $HOME/flutter
export PATH="$PATH:$HOME/flutter/bin"
# Install Flutter artifacts for iOS (--ios), or macOS (--macos) platforms.
flutter precache --ios
# Install Flutter dependencies.
flutter pub get
# Install CocoaPods using Homebrew.
HOMEBREW_NO_AUTO_UPDATE=1 # disable homebrew's automatic updates.
brew install cocoapods
# Install CocoaPods dependencies.
cd ios && pod install # run `pod install` in the `ios` directory.
exit 0

View File

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

View File

@@ -5,32 +5,32 @@
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000209">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000358">
</testcase>
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="0.78333">
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="0.721922">
</testcase>
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="3.947588">
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="6.015111">
</testcase>
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="0.505399">
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="0.656945">
</testcase>
<testcase classname="fastlane.lanes" name="4: build_app" time="80.954627">
<testcase classname="fastlane.lanes" name="4: build_app" time="75.686541">
</testcase>
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="58.295965">
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="68.644406">
</testcase>

Some files were not shown because too many files have changed in this diff Show More