diff --git a/docs/docs/partials/_mobile-app-download.md b/docs/docs/partials/_mobile-app-download.md index 72a3053440..31cf62bf81 100644 --- a/docs/docs/partials/_mobile-app-download.md +++ b/docs/docs/partials/_mobile-app-download.md @@ -1,5 +1,6 @@ The mobile app can be downloaded from the following places: +- Obtainium: You can get your Obtainium config link from the [Utilities page of your Immich server](https://my.immich.app/utilities). - [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) diff --git a/e2e/src/web/specs/auth.e2e-spec.ts b/e2e/src/web/specs/auth.e2e-spec.ts index 173131ec5e..a14a177917 100644 --- a/e2e/src/web/specs/auth.e2e-spec.ts +++ b/e2e/src/web/specs/auth.e2e-spec.ts @@ -38,6 +38,7 @@ test.describe('Registration', () => { await page.getByRole('button', { name: 'User Privacy' }).click(); await page.getByRole('button', { name: 'Storage Template' }).click(); await page.getByRole('button', { name: 'Backups' }).click(); + await page.getByRole('button', { name: 'Mobile App' }).click(); await page.getByRole('button', { name: 'Done' }).click(); // success @@ -85,6 +86,7 @@ test.describe('Registration', () => { await page.getByRole('button', { name: 'Theme' }).click(); await page.getByRole('button', { name: 'Language' }).click(); await page.getByRole('button', { name: 'User Privacy' }).click(); + await page.getByRole('button', { name: 'Mobile App' }).click(); await page.getByRole('button', { name: 'Done' }).click(); // success diff --git a/i18n/en.json b/i18n/en.json index fede3f8a40..d265c9b9d8 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -468,9 +468,11 @@ "api_key_description": "This value will only be shown once. Please be sure to copy it before closing the window.", "api_key_empty": "Your API Key name shouldn't be empty", "api_keys": "API Keys", + "app_architecture_variant": "Variant (Architecture)", "app_bar_signout_dialog_content": "Are you sure you want to sign out?", "app_bar_signout_dialog_ok": "Yes", "app_bar_signout_dialog_title": "Sign out", + "app_download_links": "App Download Links", "app_settings": "App Settings", "appears_in": "Appears in", "apply_count": "Apply ({count, number})", @@ -1348,6 +1350,8 @@ "minute": "Minute", "minutes": "Minutes", "missing": "Missing", + "mobile_app": "Mobile App", + "mobile_app_download_onboarding_note": "You can access these options again from the Utilities page.", "model": "Model", "month": "Month", "monthly_title_text_date_format": "MMMM y", @@ -1428,6 +1432,8 @@ "notifications": "Notifications", "notifications_setting_description": "Manage notifications", "oauth": "OAuth", + "obtainium_configurator": "Obtainium Configurator", + "obtainium_configurator_instructions": "Please create an API key and select a variant to create your Obtainium configuration link.", "official_immich_resources": "Official Immich Resources", "offline": "Offline", "offset": "Offset", diff --git a/web/src/lib/components/onboarding-page/onboarding-mobile-app.svelte b/web/src/lib/components/onboarding-page/onboarding-mobile-app.svelte new file mode 100644 index 0000000000..4c46ad76d1 --- /dev/null +++ b/web/src/lib/components/onboarding-page/onboarding-mobile-app.svelte @@ -0,0 +1,27 @@ + + + + + + +

{$t('mobile_app_download_onboarding_note')}

diff --git a/web/src/lib/components/utilities-page/utilities-menu.svelte b/web/src/lib/components/utilities-page/utilities-menu.svelte index fc747dc6af..bf7090e310 100644 --- a/web/src/lib/components/utilities-page/utilities-menu.svelte +++ b/web/src/lib/components/utilities-page/utilities-menu.svelte @@ -1,7 +1,15 @@ + + + +
+
+ + + Get it on F-Droid + +
+ +
+ + + Get it on Google Play + +
+ +
+ + + Download on the App Store + +
+
+
+
diff --git a/web/src/lib/modals/ObtainiumConfigModal.svelte b/web/src/lib/modals/ObtainiumConfigModal.svelte new file mode 100644 index 0000000000..d7132f2f85 --- /dev/null +++ b/web/src/lib/modals/ObtainiumConfigModal.svelte @@ -0,0 +1,94 @@ + + + + +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ {#if inputUrl && inputApiKey && archVariant} + + Get it on Obtainium + + {:else} + + {/if} +
+
+
+
diff --git a/web/src/routes/auth/onboarding/+page.svelte b/web/src/routes/auth/onboarding/+page.svelte index 44f3792a5b..c046c5fadf 100644 --- a/web/src/routes/auth/onboarding/+page.svelte +++ b/web/src/routes/auth/onboarding/+page.svelte @@ -5,6 +5,7 @@ import OnboardingCard from '$lib/components/onboarding-page/onboarding-card.svelte'; import OnboardingHello from '$lib/components/onboarding-page/onboarding-hello.svelte'; import OnboardingLocale from '$lib/components/onboarding-page/onboarding-language.svelte'; + import OnboardingMobileApp from '$lib/components/onboarding-page/onboarding-mobile-app.svelte'; import OnboardingServerPrivacy from '$lib/components/onboarding-page/onboarding-server-privacy.svelte'; import OnboardingStorageTemplate from '$lib/components/onboarding-page/onboarding-storage-template.svelte'; import OnboardingTheme from '$lib/components/onboarding-page/onboarding-theme.svelte'; @@ -14,7 +15,14 @@ import { retrieveServerConfig, retrieveSystemConfig, serverConfig } from '$lib/stores/server-config.store'; import { user } from '$lib/stores/user.store'; import { setUserOnboarding, updateAdminOnboarding } from '@immich/sdk'; - import { mdiCloudCheckOutline, mdiHarddisk, mdiIncognito, mdiThemeLightDark, mdiTranslate } from '@mdi/js'; + import { + mdiCellphoneArrowDownVariant, + mdiCloudCheckOutline, + mdiHarddisk, + mdiIncognito, + mdiThemeLightDark, + mdiTranslate, + } from '@mdi/js'; import { onMount } from 'svelte'; import { t } from 'svelte-i18n'; @@ -26,6 +34,7 @@ | typeof OnboardingStorageTemplate | typeof OnboardingServerPrivacy | typeof OnboardingUserPrivacy + | typeof OnboardingMobileApp | typeof OnboardingLocale; role: OnboardingRole; title?: string; @@ -76,6 +85,13 @@ title: $t('admin.backup_onboarding_title'), icon: mdiCloudCheckOutline, }, + { + name: 'mobile_app', + component: OnboardingMobileApp, + role: OnboardingRole.USER, + title: $t('mobile_app'), + icon: mdiCellphoneArrowDownVariant, // or you can use mdiCellphone + }, ]); let index = $state(0);