mirror of
https://github.com/immich-app/immich.git
synced 2026-03-23 10:59:52 +03:00
refactor(web): routes (#25313)
This commit is contained in:
@@ -3,12 +3,13 @@
|
||||
import { shortcuts, type ShortcutOptions } from '$lib/actions/shortcut';
|
||||
import type { Action } from '$lib/components/asset-viewer/actions/action';
|
||||
import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
|
||||
import { AppRoute, AssetAction } from '$lib/constants';
|
||||
import { AssetAction } from '$lib/constants';
|
||||
import Portal from '$lib/elements/Portal.svelte';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import type { TimelineAsset, Viewport } from '$lib/managers/timeline-manager/types';
|
||||
import AssetDeleteConfirmModal from '$lib/modals/AssetDeleteConfirmModal.svelte';
|
||||
import ShortcutsModal from '$lib/modals/ShortcutsModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { showDeleteModal } from '$lib/stores/preferences.store';
|
||||
@@ -256,7 +257,7 @@
|
||||
|
||||
const shortcuts: ShortcutOptions[] = [
|
||||
{ shortcut: { key: '?', shift: true }, onShortcut: handleOpenShortcutModal },
|
||||
{ shortcut: { key: '/' }, onShortcut: () => goto(AppRoute.EXPLORE) },
|
||||
{ shortcut: { key: '/' }, onShortcut: () => goto(Route.explore()) },
|
||||
{ shortcut: { key: 'A', ctrl: true }, onShortcut: () => selectAllAssets() },
|
||||
...(arrowNavigation
|
||||
? [
|
||||
@@ -306,7 +307,7 @@
|
||||
1,
|
||||
);
|
||||
if (assets.length === 0) {
|
||||
return await goto(AppRoute.PHOTOS);
|
||||
return await goto(Route.photos());
|
||||
}
|
||||
if (assetCursor.nextAsset) {
|
||||
await navigateToAsset(assetCursor.nextAsset);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { focusTrap } from '$lib/actions/focus-trap';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import AvatarEditModal from '$lib/modals/AvatarEditModal.svelte';
|
||||
import HelpAndFeedbackModal from '$lib/modals/HelpAndFeedbackModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
import { getAboutInfo, type ServerAboutResponseDto } from '@immich/sdk';
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<Button
|
||||
href={AppRoute.USER_SETTINGS}
|
||||
href={Route.userSettings()}
|
||||
onclick={onClose}
|
||||
size="small"
|
||||
color="secondary"
|
||||
@@ -78,7 +78,7 @@
|
||||
</Button>
|
||||
{#if $user.isAdmin}
|
||||
<Button
|
||||
href={AppRoute.ADMIN_SETTINGS}
|
||||
href={Route.systemSettings()}
|
||||
onclick={onClose}
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
import ActionButton from '$lib/components/ActionButton.svelte';
|
||||
import NotificationPanel from '$lib/components/shared-components/navigation-bar/notification-panel.svelte';
|
||||
import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import SkipLink from '$lib/elements/SkipLink.svelte';
|
||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { getGlobalActions } from '$lib/services/app.service';
|
||||
import { mobileDevice } from '$lib/stores/mobile-device.svelte';
|
||||
import { notificationManager } from '$lib/stores/notification-manager.svelte';
|
||||
@@ -78,7 +78,7 @@
|
||||
}}
|
||||
class="sidebar:hidden"
|
||||
/>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.PHOTOS}>
|
||||
<a data-sveltekit-preload-data="hover" href={Route.photos()}>
|
||||
<Logo variant={mobileDevice.isFullSidebar ? 'inline' : 'icon'} class="max-md:h-12" />
|
||||
</a>
|
||||
</div>
|
||||
@@ -97,7 +97,7 @@
|
||||
variant="ghost"
|
||||
size="medium"
|
||||
icon={mdiMagnify}
|
||||
href={AppRoute.SEARCH}
|
||||
href={Route.search()}
|
||||
id="search-button"
|
||||
class="sm:hidden"
|
||||
aria-label={$t('go_to_search')}
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { focusOutside } from '$lib/actions/focus-outside';
|
||||
import { shortcuts } from '$lib/actions/shortcut';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import SearchFilterModal from '$lib/modals/SearchFilterModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { searchStore } from '$lib/stores/search.svelte';
|
||||
import { handlePromiseError } from '$lib/utils';
|
||||
import { generateId } from '$lib/utils/generate-id';
|
||||
import { getMetadataSearchQuery } from '$lib/utils/metadata-search';
|
||||
import type { MetadataSearchDto, SmartSearchDto } from '@immich/sdk';
|
||||
import { Button, IconButton, modalManager } from '@immich/ui';
|
||||
import { mdiClose, mdiMagnify, mdiTune } from '@mdi/js';
|
||||
@@ -42,11 +41,9 @@
|
||||
});
|
||||
|
||||
const handleSearch = async (payload: SmartSearchDto | MetadataSearchDto) => {
|
||||
const params = getMetadataSearchQuery(payload);
|
||||
|
||||
closeDropdown();
|
||||
searchStore.isSearchEnabled = false;
|
||||
await goto(`${AppRoute.SEARCH}?${params}`);
|
||||
await goto(Route.search(payload));
|
||||
};
|
||||
|
||||
const clearSearchTerm = (searchTerm: string) => {
|
||||
@@ -256,7 +253,7 @@
|
||||
draggable="false"
|
||||
autocomplete="off"
|
||||
class="select-text text-sm"
|
||||
action={AppRoute.SEARCH}
|
||||
action={Route.search()}
|
||||
onreset={() => (value = '')}
|
||||
{onsubmit}
|
||||
onfocusin={onFocusIn}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { OpenQueryParam } from '$lib/constants';
|
||||
import Portal from '$lib/elements/Portal.svelte';
|
||||
import PurchaseModal from '$lib/modals/PurchaseModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { purchaseStore } from '$lib/stores/purchase.store';
|
||||
import { preferences } from '$lib/stores/user.store';
|
||||
import { getAccountAge } from '$lib/utils/auth';
|
||||
@@ -73,7 +74,7 @@
|
||||
<div class="license-status ps-4 text-sm">
|
||||
{#if $isPurchased && $preferences.purchase.showSupportBadge}
|
||||
<button
|
||||
onclick={() => goto(`${AppRoute.USER_SETTINGS}?isOpen=user-purchase-settings`)}
|
||||
onclick={() => goto(Route.userSettings({ isOpen: OpenQueryParam.PURCHASE_SETTINGS }))}
|
||||
class="w-full mt-2"
|
||||
type="button"
|
||||
>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { Route } from '$lib/route';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
import { getAssetThumbnailUrl } from '$lib/utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
@@ -25,7 +26,7 @@
|
||||
|
||||
{#each albums as album (album.id)}
|
||||
<a
|
||||
href={'/albums/' + album.id}
|
||||
href={Route.viewAlbum(album)}
|
||||
title={album.albumName}
|
||||
class="flex w-full place-items-center justify-between gap-4 rounded-e-full py-3 transition-[padding] delay-100 duration-100 hover:cursor-pointer hover:bg-subtle hover:text-immich-primary dark:text-immich-dark-fg dark:hover:bg-immich-dark-gray dark:hover:text-immich-dark-primary ps-10 group-hover:sm:px-10 md:px-10"
|
||||
>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import Sidebar from '$lib/components/sidebar/sidebar.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { recentAlbumsDropdown } from '$lib/stores/preferences.store';
|
||||
import { preferences } from '$lib/stores/user.store';
|
||||
import { NavbarGroup, NavbarItem } from '@immich/ui';
|
||||
@@ -37,15 +38,10 @@
|
||||
</script>
|
||||
|
||||
<Sidebar ariaLabel={$t('primary')}>
|
||||
<NavbarItem
|
||||
title={$t('photos')}
|
||||
href={AppRoute.PHOTOS}
|
||||
icon={mdiImageMultipleOutline}
|
||||
activeIcon={mdiImageMultiple}
|
||||
/>
|
||||
<NavbarItem title={$t('photos')} href={Route.photos()} icon={mdiImageMultipleOutline} activeIcon={mdiImageMultiple} />
|
||||
|
||||
{#if featureFlagsManager.value.search}
|
||||
<NavbarItem title={$t('explore')} href={AppRoute.EXPLORE} icon={mdiMagnify} />
|
||||
<NavbarItem title={$t('explore')} href={Route.explore()} icon={mdiMagnify} />
|
||||
{/if}
|
||||
|
||||
{#if featureFlagsManager.value.map}
|
||||
@@ -57,23 +53,23 @@
|
||||
{/if}
|
||||
|
||||
{#if $preferences.sharedLinks.enabled && $preferences.sharedLinks.sidebarWeb}
|
||||
<NavbarItem title={$t('shared_links')} href={AppRoute.SHARED_LINKS} icon={mdiLink} />
|
||||
<NavbarItem title={$t('shared_links')} href={Route.sharedLinks()} icon={mdiLink} />
|
||||
{/if}
|
||||
|
||||
<NavbarItem
|
||||
title={$t('sharing')}
|
||||
href={AppRoute.SHARING}
|
||||
href={Route.sharing()}
|
||||
icon={mdiAccountMultipleOutline}
|
||||
activeIcon={mdiAccountMultiple}
|
||||
/>
|
||||
|
||||
<NavbarGroup title={$t('library')} size="tiny" />
|
||||
|
||||
<NavbarItem title={$t('favorites')} href={AppRoute.FAVORITES} icon={mdiHeartOutline} activeIcon={mdiHeart} />
|
||||
<NavbarItem title={$t('favorites')} href={Route.favorites()} icon={mdiHeartOutline} activeIcon={mdiHeart} />
|
||||
|
||||
<NavbarItem
|
||||
title={$t('albums')}
|
||||
href={AppRoute.ALBUMS}
|
||||
href={Route.albums()}
|
||||
icon={{ icon: mdiImageAlbum, flipped: true }}
|
||||
bind:expanded={$recentAlbumsDropdown}
|
||||
>
|
||||
@@ -92,19 +88,19 @@
|
||||
<NavbarItem title={$t('folders')} href={AppRoute.FOLDERS} icon={{ icon: mdiFolderOutline, flipped: true }} />
|
||||
{/if}
|
||||
|
||||
<NavbarItem title={$t('utilities')} href={AppRoute.UTILITIES} icon={mdiToolboxOutline} activeIcon={mdiToolbox} />
|
||||
<NavbarItem title={$t('utilities')} href={Route.utilities()} icon={mdiToolboxOutline} activeIcon={mdiToolbox} />
|
||||
|
||||
<NavbarItem
|
||||
title={$t('archive')}
|
||||
href={AppRoute.ARCHIVE}
|
||||
href={Route.archive()}
|
||||
icon={mdiArchiveArrowDownOutline}
|
||||
activeIcon={mdiArchiveArrowDown}
|
||||
/>
|
||||
|
||||
<NavbarItem title={$t('locked_folder')} href={AppRoute.LOCKED} icon={mdiLockOutline} activeIcon={mdiLock} />
|
||||
<NavbarItem title={$t('locked_folder')} href={Route.locked()} icon={mdiLockOutline} activeIcon={mdiLock} />
|
||||
|
||||
{#if featureFlagsManager.value.trash}
|
||||
<NavbarItem title={$t('trash')} href={AppRoute.TRASH} icon={mdiTrashCanOutline} activeIcon={mdiTrashCan} />
|
||||
<NavbarItem title={$t('trash')} href={Route.trash()} icon={mdiTrashCanOutline} activeIcon={mdiTrashCan} />
|
||||
{/if}
|
||||
|
||||
<BottomInfo />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { uploadAssetsStore } from '$lib/stores/upload';
|
||||
import type { UploadAsset } from '$lib/types';
|
||||
@@ -34,10 +34,6 @@
|
||||
uploadAssetsStore.removeItem(uploadAsset.id);
|
||||
await fileUploadHandler({ files: [uploadAsset.file], albumId: uploadAsset.albumId });
|
||||
};
|
||||
|
||||
const asLink = (asset: UploadAsset) => {
|
||||
return asset.isTrashed ? `${AppRoute.TRASH}/${asset.assetId}` : `${AppRoute.PHOTOS}/${uploadAsset.assetId}`;
|
||||
};
|
||||
</script>
|
||||
|
||||
<div
|
||||
@@ -69,7 +65,9 @@
|
||||
{#if uploadAsset.state === UploadState.DUPLICATED && uploadAsset.assetId}
|
||||
<div class="flex items-center justify-between gap-1">
|
||||
<a
|
||||
href={asLink(uploadAsset)}
|
||||
href={uploadAsset.isTrashed
|
||||
? Route.viewTrashedAsset({ id: uploadAsset.assetId })
|
||||
: Route.viewAsset({ id: uploadAsset.assetId })}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class=""
|
||||
|
||||
Reference in New Issue
Block a user