diff --git a/apps/next.immich.app/routes/features/+page.svelte b/apps/next.immich.app/routes/features/+page.svelte
deleted file mode 100644
index b229b24..0000000
--- a/apps/next.immich.app/routes/features/+page.svelte
+++ /dev/null
@@ -1,285 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Features
- Immich is packed with features!
-
-
-
-
- {#each features as feature}
-
-
- {feature.title}
- {feature.description}
-
-
-
-
-
- {/each}
-
-
-
-
-
diff --git a/apps/next.immich.app/routes/features/[[feature]]/+page.svelte b/apps/next.immich.app/routes/features/[[feature]]/+page.svelte
new file mode 100644
index 0000000..7770f9d
--- /dev/null
+++ b/apps/next.immich.app/routes/features/[[feature]]/+page.svelte
@@ -0,0 +1,71 @@
+
+
+{#if feature}
+ goto('/features')}>
+
+
+
+
+{/if}
+
+
+
+
+
+
+
+
+
+ Features
+ Immich is packed with features!
+
+
+
+
+
+
+
+
diff --git a/apps/next.immich.app/routes/features/[[feature]]/+page.ts b/apps/next.immich.app/routes/features/[[feature]]/+page.ts
new file mode 100644
index 0000000..bdf4053
--- /dev/null
+++ b/apps/next.immich.app/routes/features/[[feature]]/+page.ts
@@ -0,0 +1,10 @@
+import { features } from '$lib/utilities';
+import type { PageLoad } from './$types';
+
+export const load = (async ({ url }) => {
+ const feature = features.find((feature) => feature.href === url.pathname);
+
+ return {
+ feature,
+ };
+}) satisfies PageLoad;
diff --git a/package-lock.json b/package-lock.json
index cb6feda..1cc2b3b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
"@mdi/js": "^7.4.47"
},
"devDependencies": {
- "@immich/ui": "^0.14.1",
+ "@immich/ui": "^0.15.0",
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.12.1",
"@sveltejs/vite-plugin-svelte": "^5.0.2",
@@ -700,9 +700,9 @@
}
},
"node_modules/@immich/ui": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/@immich/ui/-/ui-0.14.1.tgz",
- "integrity": "sha512-s5HGT35Odu6PrjO49xJ1Kpe7v1K53iMV03tv6MePVIdIM9sZHA04+o0tJgMm2KqLPZrkU+jhKPSfSy0PqkoEyQ==",
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/@immich/ui/-/ui-0.15.0.tgz",
+ "integrity": "sha512-vGDNEOGj5Ma/BAIgj31M1roAVoEOVWws5lkgt1xPlIxSHk4pMhGRFMQaJaCsfXeX/nTRsQCd3gOk7Yo0XNrVfg==",
"dev": true,
"license": "GNU Affero General Public License version 3",
"dependencies": {
diff --git a/package.json b/package.json
index f2207ec..c230ee3 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"format:fix": "prettier --write ."
},
"devDependencies": {
- "@immich/ui": "^0.14.1",
+ "@immich/ui": "^0.15.0",
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.12.1",
"@sveltejs/vite-plugin-svelte": "^5.0.2",
diff --git a/src/lib/components/features/MobileAppFeature.svelte b/src/lib/components/features/MobileAppFeature.svelte
new file mode 100644
index 0000000..f25eb82
--- /dev/null
+++ b/src/lib/components/features/MobileAppFeature.svelte
@@ -0,0 +1,9 @@
+
+
+Immich has a mobile app, published on the Apple Store, Google PlayStore, and F-Droid. To download the app, view the download page.
diff --git a/src/lib/types.ts b/src/lib/types.ts
index 25eff56..0352c39 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -1,4 +1,5 @@
import type { Color } from '@immich/ui';
+import type { Component } from 'svelte';
export type HeaderItem = {
title: string;
@@ -16,3 +17,11 @@ export type TimelineItem = {
done?: false;
getDateLabel: (language: string) => string;
};
+
+export type Feature = {
+ icon: string;
+ title: string;
+ description: string;
+ href: string;
+ content: Component;
+};
diff --git a/src/lib/utilities.ts b/src/lib/utilities.ts
new file mode 100644
index 0000000..eb8b61c
--- /dev/null
+++ b/src/lib/utilities.ts
@@ -0,0 +1,300 @@
+import MobileAppFeature from '$lib/components/features/MobileAppFeature.svelte';
+import type { Feature } from '$lib/types';
+import {
+ mdiAccountCog,
+ mdiAccountMultiple,
+ mdiAccountMultipleOutline,
+ mdiAccountPlusOutline,
+ mdiArchiveOutline,
+ mdiCalendarTodayOutline,
+ mdiChartLine,
+ mdiCloudUpload,
+ mdiDatabaseOutline,
+ mdiEmailOutline,
+ mdiFaceRecognition,
+ mdiFileOutline,
+ mdiFileUploadOutline,
+ mdiFolderMultiple,
+ mdiForumOutline,
+ mdiHeartOutline,
+ mdiImageAlbum,
+ mdiImageMultiple,
+ mdiImageMultipleOutline,
+ mdiKeyOutline,
+ mdiMagnify,
+ mdiMapMarkerOutline,
+ mdiMapOutline,
+ mdiMotionPlayOutline,
+ mdiPanoramaOutline,
+ mdiPlayBoxOutline,
+ mdiRaw,
+ mdiRotate360,
+ mdiSecurity,
+ mdiShareVariant,
+ mdiTagMultiple,
+ mdiThemeLightDark,
+ mdiTimelineOutline,
+ mdiWeb,
+} from '@mdi/js';
+
+export const features: Feature[] = [
+ {
+ title: 'Timeline',
+ description: 'View your photos and videos in a timeline',
+ icon: mdiTimelineOutline,
+ href: 'timeline',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Albums',
+ description: 'Organize your photos and videos into albums and share them with other users',
+ icon: mdiImageAlbum,
+ href: 'albums',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Multi-User',
+ description: 'Add friends and family to your instance, each with their own private set of photos and videos',
+ icon: mdiAccountPlusOutline,
+ href: 'multi-user',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Shared Links',
+ description: 'Share your photos and videos with private, secure, and optionally password protected links',
+ icon: mdiShareVariant,
+ href: 'shared-links',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Partner Sharing',
+ description: 'Share your photos and videos with one or more partners',
+ icon: mdiAccountMultipleOutline,
+ href: 'partner-sharing',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Dark Theme',
+ description: 'View Immich using a dark theme',
+ icon: mdiThemeLightDark,
+ href: 'dark-theme',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Facial Recognition',
+ description: 'Detect faces in your photos and videos',
+ icon: mdiFaceRecognition,
+ href: 'facial-recognition',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Map',
+ description: 'View your photos and videos on a map',
+ icon: mdiMapOutline,
+ href: 'map',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Archive',
+ description: 'Hide non-essential photos and videos from the main timeline',
+ icon: mdiArchiveOutline,
+ href: 'archive',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Memories',
+ description: 'View photos and videos taken on this day in past years',
+ icon: mdiCalendarTodayOutline,
+ href: 'memories',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Favorites',
+ description: 'Keep track of your favorite photos and videos',
+ icon: mdiHeartOutline,
+ href: 'favorites',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Smart Search',
+ description: 'Search your photos and videos with natural language',
+ icon: mdiMagnify,
+ href: 'mobile-app',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Slideshow',
+ description: 'View your photos and videos as a slideshow',
+ icon: mdiPlayBoxOutline,
+ href: 'slideshow',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Live Photos',
+ description: 'View Live Photos from Apple devices',
+ icon: mdiMotionPlayOutline,
+ href: 'live-photos',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Motion Photos',
+ description: 'View Motion PHotos from Android devices',
+ icon: mdiMotionPlayOutline,
+ href: 'motion-photos',
+ content: MobileAppFeature,
+ },
+ {
+ title: '360° Photos',
+ description: 'View your 360° photos in Immich',
+ icon: mdiRotate360,
+ href: '360-photos',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Panoramas',
+ description: 'View your panoramas in Immich',
+ icon: mdiPanoramaOutline,
+ href: 'panoramas',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'RAW',
+ description: 'View your raw, uncompressed photo and scans in Immich',
+ icon: mdiRaw,
+ href: 'raw',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Stacks',
+ description: 'Combine similar or related photos and videos into a stack',
+ icon: mdiImageMultipleOutline,
+ href: 'stacks',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Tags',
+ description: 'Organize your photos and videos with hierarchal tags',
+ icon: mdiTagMultiple,
+ href: 'tags',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Drag and Drop',
+ description: 'Drag and drop photos, videos, and screenshots into Immich',
+ icon: mdiFileUploadOutline,
+ href: 'drag-and-drop',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Internationalization',
+ description: 'View Immich in your preferred language and locale',
+ icon: mdiWeb,
+ href: 'internationalization',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Email Notifications',
+ description: 'Receive email notifications when new photos or videos are added to an album',
+ icon: mdiEmailOutline,
+ href: 'email-notifications',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Trash',
+ description: 'Automatically delete photos and videos from the trash after a period of time',
+ icon: mdiTagMultiple,
+ href: 'trash',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Reverse Geocoding',
+ description: 'View and search your photos and videos by city, state, and country names',
+ icon: mdiMapMarkerOutline,
+ href: 'reverse-geocoding',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Activity & Comments',
+ description: 'View activity and comments on your photos and videos',
+ icon: mdiForumOutline,
+ href: 'activity-and-comments',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'External Libraries',
+ description: 'Mount your photos and videos as read-only, external folder',
+ icon: mdiImageMultiple,
+ href: 'external-libraries',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Folder View',
+ description: 'View your photos and videos in a folder structure',
+ icon: mdiFolderMultiple,
+ href: 'folder-view',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Storage Template',
+ description: 'Customize how your photos and videos are stored on disk',
+ icon: mdiTagMultiple,
+ href: 'storage-template',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'OIDC',
+ description: 'Login to Immich using OpenID Connect',
+ icon: mdiSecurity,
+ href: 'openid-connect',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Hardware Transcoding',
+ description: 'Use hardware acceleration to transcode your videos',
+ icon: mdiAccountMultiple,
+ href: 'hardware-transcoding',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Database Backups',
+ description: 'Automatically backup your Immich database',
+ icon: mdiDatabaseOutline,
+ href: 'database-backujps',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'CLI Upload',
+ description: 'Import photos and videos into Immich using the CLI',
+ icon: mdiCloudUpload,
+ href: 'command-line-upload',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Api Keys',
+ description: 'Programmatically access your data or integrate Immich with third party services',
+ icon: mdiKeyOutline,
+ href: 'api-keys',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'Monitoring',
+ description: 'Monitor the health of your Immich instance via Prometheus',
+ icon: mdiChartLine,
+ href: 'monitoring',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'User Settings',
+ description: 'Customize your Immich experience',
+ icon: mdiAccountCog,
+ href: 'user-settings',
+ content: MobileAppFeature,
+ },
+ {
+ title: 'XML Sidecars',
+ description: 'Sync metadata to and from XMP sidecar files',
+ icon: mdiFileOutline,
+ href: 'xml-sidecars',
+ content: MobileAppFeature,
+ },
+].map((feature) => ({ ...feature, href: `/features/${feature.href}` }));