refactor(web): material icons (#4636)
This commit is contained in:
parent
d5e19e45cd
commit
2ad389f64e
89 changed files with 557 additions and 534 deletions
|
@ -186,7 +186,7 @@ export default {
|
|||
},
|
||||
|
||||
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
|
||||
transformIgnorePatterns: ['/node_modules/(?!svelte-material-icons).*/', '\\.pnp\\.[^\\/]+$'],
|
||||
transformIgnorePatterns: ['\\.pnp\\.[^\\/]+$'],
|
||||
|
||||
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
|
||||
// unmockedModulePathPatterns: undefined,
|
||||
|
|
26
web/package-lock.json
generated
26
web/package-lock.json
generated
|
@ -9,6 +9,7 @@
|
|||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@egjs/svelte-view360": "^4.0.0-beta.7",
|
||||
"@mdi/js": "^7.3.67",
|
||||
"@zoom-image/svelte": "^0.1.8",
|
||||
"axios": "^0.27.2",
|
||||
"buffer": "^6.0.3",
|
||||
|
@ -23,7 +24,6 @@
|
|||
"socket.io-client": "^4.6.1",
|
||||
"svelte-loading-spinners": "^0.3.4",
|
||||
"svelte-local-storage-store": "^0.5.0",
|
||||
"svelte-material-icons": "^3.0.5",
|
||||
"thumbhash": "^0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -3197,6 +3197,11 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@mdi/js": {
|
||||
"version": "7.3.67",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.3.67.tgz",
|
||||
"integrity": "sha512-MnRjknFqpTC6FifhGHjZ0+QYq2bAkZFQqIj8JA2AdPZbBxUvr8QSgB2yPAJ8/ob/XkR41xlg5majDR3c1JP1hw=="
|
||||
},
|
||||
"node_modules/@namnode/store": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@namnode/store/-/store-0.1.0.tgz",
|
||||
|
@ -11418,14 +11423,6 @@
|
|||
"svelte": "^3.48.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-material-icons": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-3.0.5.tgz",
|
||||
"integrity": "sha512-UbhAa+Btd5y6e6DMljVccP+cbJ8lvesltMippiCOvfIUtYe2TsQqM+P6osfrVsZHV47b1tY6AmqCuSpMKnwMOQ==",
|
||||
"peerDependencies": {
|
||||
"svelte": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-preprocess": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz",
|
||||
|
@ -14495,6 +14492,11 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"@mdi/js": {
|
||||
"version": "7.3.67",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.3.67.tgz",
|
||||
"integrity": "sha512-MnRjknFqpTC6FifhGHjZ0+QYq2bAkZFQqIj8JA2AdPZbBxUvr8QSgB2yPAJ8/ob/XkR41xlg5majDR3c1JP1hw=="
|
||||
},
|
||||
"@namnode/store": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@namnode/store/-/store-0.1.0.tgz",
|
||||
|
@ -20512,12 +20514,6 @@
|
|||
"integrity": "sha512-SEDrpapeia6fUqta+r1NvSLlJYPkZ4pBcl15EYIOSPNzy6vhpoXu8cnzUDmZxsWl7fZGAHxrVH9UyZCbyO4W+g==",
|
||||
"requires": {}
|
||||
},
|
||||
"svelte-material-icons": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-3.0.5.tgz",
|
||||
"integrity": "sha512-UbhAa+Btd5y6e6DMljVccP+cbJ8lvesltMippiCOvfIUtYe2TsQqM+P6osfrVsZHV47b1tY6AmqCuSpMKnwMOQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"svelte-preprocess": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz",
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
"type": "module",
|
||||
"dependencies": {
|
||||
"@egjs/svelte-view360": "^4.0.0-beta.7",
|
||||
"@mdi/js": "^7.3.67",
|
||||
"@zoom-image/svelte": "^0.1.8",
|
||||
"axios": "^0.27.2",
|
||||
"buffer": "^6.0.3",
|
||||
|
@ -76,7 +77,6 @@
|
|||
"socket.io-client": "^4.6.1",
|
||||
"svelte-loading-spinners": "^0.3.4",
|
||||
"svelte-local-storage-store": "^0.5.0",
|
||||
"svelte-material-icons": "^3.0.5",
|
||||
"thumbhash": "^0.1.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
<script lang="ts">
|
||||
import type Icon from 'svelte-material-icons/AbTesting.svelte';
|
||||
import SelectionSearch from 'svelte-material-icons/SelectionSearch.svelte';
|
||||
import Play from 'svelte-material-icons/Play.svelte';
|
||||
import Pause from 'svelte-material-icons/Pause.svelte';
|
||||
import FastForward from 'svelte-material-icons/FastForward.svelte';
|
||||
import AllInclusive from 'svelte-material-icons/AllInclusive.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import AlertCircle from 'svelte-material-icons/AlertCircle.svelte';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { JobCommand, JobCommandDto, JobCountsDto, QueueStatusDto } from '@api';
|
||||
import Badge from '$lib/components/elements/badge.svelte';
|
||||
import JobTileButton from './job-tile-button.svelte';
|
||||
import JobTileStatus from './job-tile-status.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import {
|
||||
mdiAlertCircle,
|
||||
mdiAllInclusive,
|
||||
mdiClose,
|
||||
mdiFastForward,
|
||||
mdiPause,
|
||||
mdiPlay,
|
||||
mdiSelectionSearch,
|
||||
} from '@mdi/js';
|
||||
|
||||
export let title: string;
|
||||
export let subtitle: string | undefined = undefined;
|
||||
export let jobCounts: JobCountsDto;
|
||||
export let queueStatus: QueueStatusDto;
|
||||
export let allowForceCommand = true;
|
||||
export let icon: typeof Icon;
|
||||
export let icon: string;
|
||||
export let disabled = false;
|
||||
|
||||
export let allText: string;
|
||||
|
@ -47,7 +49,7 @@
|
|||
<div class="flex flex-col gap-2 p-5 sm:p-7 md:p-9">
|
||||
<div class="flex items-center gap-4 text-xl font-semibold text-immich-primary dark:text-immich-dark-primary">
|
||||
<span class="flex items-center gap-2">
|
||||
<svelte:component this={icon} size="1.25em" class="hidden shrink-0 sm:block" />
|
||||
<Icon path={icon} size="1.25em" class="hidden shrink-0 sm:block" />
|
||||
{title.toUpperCase()}
|
||||
</span>
|
||||
<div class="flex gap-2">
|
||||
|
@ -102,12 +104,12 @@
|
|||
color="light-gray"
|
||||
on:click={() => dispatch('command', { command: JobCommand.Start, force: false })}
|
||||
>
|
||||
<AlertCircle size="36" /> DISABLED
|
||||
<Icon path={mdiAlertCircle} size="36" /> DISABLED
|
||||
</JobTileButton>
|
||||
{:else if !isIdle}
|
||||
{#if waitingCount > 0}
|
||||
<JobTileButton color="gray" on:click={() => dispatch('command', { command: JobCommand.Empty, force: false })}>
|
||||
<Close size="24" /> CLEAR
|
||||
<Icon path={mdiClose} size="24" /> CLEAR
|
||||
</JobTileButton>
|
||||
{/if}
|
||||
{#if queueStatus.isPaused}
|
||||
|
@ -117,26 +119,26 @@
|
|||
on:click={() => dispatch('command', { command: JobCommand.Resume, force: false })}
|
||||
>
|
||||
<!-- size property is not reactive, so have to use width and height -->
|
||||
<FastForward width={size} height={size} /> RESUME
|
||||
<Icon path={mdiFastForward} {size} /> RESUME
|
||||
</JobTileButton>
|
||||
{:else}
|
||||
<JobTileButton
|
||||
color="light-gray"
|
||||
on:click={() => dispatch('command', { command: JobCommand.Pause, force: false })}
|
||||
>
|
||||
<Pause size="24" /> PAUSE
|
||||
<Icon path={mdiPause} size="24" /> PAUSE
|
||||
</JobTileButton>
|
||||
{/if}
|
||||
{:else if allowForceCommand}
|
||||
<JobTileButton color="gray" on:click={() => dispatch('command', { command: JobCommand.Start, force: true })}>
|
||||
<AllInclusive size="24" />
|
||||
<Icon path={mdiAllInclusive} size="24" />
|
||||
{allText}
|
||||
</JobTileButton>
|
||||
<JobTileButton
|
||||
color="light-gray"
|
||||
on:click={() => dispatch('command', { command: JobCommand.Start, force: false })}
|
||||
>
|
||||
<SelectionSearch size="24" />
|
||||
<Icon path={mdiSelectionSearch} size="24" />
|
||||
{missingText}
|
||||
</JobTileButton>
|
||||
{:else}
|
||||
|
@ -144,7 +146,7 @@
|
|||
color="light-gray"
|
||||
on:click={() => dispatch('command', { command: JobCommand.Start, force: false })}
|
||||
>
|
||||
<Play size="48" /> START
|
||||
<Icon path={mdiPlay} size="48" /> START
|
||||
</JobTileButton>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -7,16 +7,17 @@
|
|||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { AllJobStatusResponseDto, api, JobCommand, JobCommandDto, JobName } from '@api';
|
||||
import type { ComponentType } from 'svelte';
|
||||
import type Icon from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import FaceRecognition from 'svelte-material-icons/FaceRecognition.svelte';
|
||||
import FileJpgBox from 'svelte-material-icons/FileJpgBox.svelte';
|
||||
import FileXmlBox from 'svelte-material-icons/FileXmlBox.svelte';
|
||||
import LibraryShelves from 'svelte-material-icons/LibraryShelves.svelte';
|
||||
import FolderMove from 'svelte-material-icons/FolderMove.svelte';
|
||||
import Table from 'svelte-material-icons/Table.svelte';
|
||||
import TagMultiple from 'svelte-material-icons/TagMultiple.svelte';
|
||||
import VectorCircle from 'svelte-material-icons/VectorCircle.svelte';
|
||||
import Video from 'svelte-material-icons/Video.svelte';
|
||||
import {
|
||||
mdiFaceRecognition,
|
||||
mdiFileJpgBox,
|
||||
mdiFileXmlBox,
|
||||
mdiFolderMove,
|
||||
mdiLibraryShelves,
|
||||
mdiTable,
|
||||
mdiTagMultiple,
|
||||
mdiVectorCircle,
|
||||
mdiVideo,
|
||||
} from '@mdi/js';
|
||||
import ConfirmDialogue from '../../shared-components/confirm-dialogue.svelte';
|
||||
import JobTile from './job-tile.svelte';
|
||||
import StorageMigrationDescription from './storage-migration-description.svelte';
|
||||
|
@ -29,7 +30,7 @@
|
|||
allText?: string;
|
||||
missingText?: string;
|
||||
disabled?: boolean;
|
||||
icon: typeof Icon;
|
||||
icon: string;
|
||||
allowForceCommand?: boolean;
|
||||
component?: ComponentType;
|
||||
handleCommand?: (jobId: JobName, jobCommand: JobCommandDto) => Promise<void>;
|
||||
|
@ -53,17 +54,17 @@
|
|||
|
||||
$: jobDetails = <Partial<Record<JobName, JobDetails>>>{
|
||||
[JobName.ThumbnailGeneration]: {
|
||||
icon: FileJpgBox,
|
||||
icon: mdiFileJpgBox,
|
||||
title: api.getJobName(JobName.ThumbnailGeneration),
|
||||
subtitle: 'Regenerate JPEG and WebP thumbnails',
|
||||
},
|
||||
[JobName.MetadataExtraction]: {
|
||||
icon: Table,
|
||||
icon: mdiTable,
|
||||
title: api.getJobName(JobName.MetadataExtraction),
|
||||
subtitle: 'Extract metadata information i.e. GPS, resolution...etc',
|
||||
},
|
||||
[JobName.Library]: {
|
||||
icon: LibraryShelves,
|
||||
icon: mdiLibraryShelves,
|
||||
title: api.getJobName(JobName.Library),
|
||||
subtitle: 'Perform library tasks',
|
||||
allText: 'ALL',
|
||||
|
@ -71,44 +72,44 @@
|
|||
},
|
||||
[JobName.Sidecar]: {
|
||||
title: api.getJobName(JobName.Sidecar),
|
||||
icon: FileXmlBox,
|
||||
icon: mdiFileXmlBox,
|
||||
subtitle: 'Discover or synchronize sidecar metadata from the filesystem',
|
||||
allText: 'SYNC',
|
||||
missingText: 'DISCOVER',
|
||||
disabled: !$featureFlags.sidecar,
|
||||
},
|
||||
[JobName.ObjectTagging]: {
|
||||
icon: TagMultiple,
|
||||
icon: mdiTagMultiple,
|
||||
title: api.getJobName(JobName.ObjectTagging),
|
||||
subtitle: 'Run machine learning to tag objects\nNote that some assets may not have any objects detected',
|
||||
disabled: !$featureFlags.tagImage,
|
||||
},
|
||||
[JobName.ClipEncoding]: {
|
||||
icon: VectorCircle,
|
||||
icon: mdiVectorCircle,
|
||||
title: api.getJobName(JobName.ClipEncoding),
|
||||
subtitle: 'Run machine learning to generate clip embeddings',
|
||||
disabled: !$featureFlags.clipEncode,
|
||||
},
|
||||
[JobName.RecognizeFaces]: {
|
||||
icon: FaceRecognition,
|
||||
icon: mdiFaceRecognition,
|
||||
title: api.getJobName(JobName.RecognizeFaces),
|
||||
subtitle: 'Run machine learning to recognize faces',
|
||||
handleCommand: handleFaceCommand,
|
||||
disabled: !$featureFlags.facialRecognition,
|
||||
},
|
||||
[JobName.VideoConversion]: {
|
||||
icon: Video,
|
||||
icon: mdiVideo,
|
||||
title: api.getJobName(JobName.VideoConversion),
|
||||
subtitle: 'Transcode videos not in the desired format',
|
||||
},
|
||||
[JobName.StorageTemplateMigration]: {
|
||||
icon: FolderMove,
|
||||
icon: mdiFolderMove,
|
||||
title: api.getJobName(JobName.StorageTemplateMigration),
|
||||
allowForceCommand: false,
|
||||
component: StorageMigrationDescription,
|
||||
},
|
||||
[JobName.Migration]: {
|
||||
icon: FolderMove,
|
||||
icon: mdiFolderMove,
|
||||
title: api.getJobName(JobName.Migration),
|
||||
subtitle: 'Migrate thumbnails for assets and faces to the latest folder structure',
|
||||
allowForceCommand: false,
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import type { ServerStatsResponseDto } from '@api';
|
||||
import CameraIris from 'svelte-material-icons/CameraIris.svelte';
|
||||
import Memory from 'svelte-material-icons/Memory.svelte';
|
||||
import PlayCircle from 'svelte-material-icons/PlayCircle.svelte';
|
||||
import { asByteUnitString, getBytesWithUnit } from '../../../utils/byte-units';
|
||||
import { asByteUnitString, getBytesWithUnit } from '$lib/utils/byte-units';
|
||||
import StatsCard from './stats-card.svelte';
|
||||
import { mdiCameraIris, mdiMemory, mdiPlayCircle } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let stats: ServerStatsResponseDto = {
|
||||
photos: 0,
|
||||
|
@ -30,15 +29,15 @@
|
|||
<p class="text-sm dark:text-immich-dark-fg">TOTAL USAGE</p>
|
||||
|
||||
<div class="mt-5 hidden justify-between lg:flex">
|
||||
<StatsCard logo={CameraIris} title="PHOTOS" value={stats.photos} />
|
||||
<StatsCard logo={PlayCircle} title="VIDEOS" value={stats.videos} />
|
||||
<StatsCard logo={Memory} title="STORAGE" value={statsUsage} unit={statsUsageUnit} />
|
||||
<StatsCard icon={mdiCameraIris} title="PHOTOS" value={stats.photos} />
|
||||
<StatsCard icon={mdiPlayCircle} title="VIDEOS" value={stats.videos} />
|
||||
<StatsCard icon={mdiMemory} title="STORAGE" value={statsUsage} unit={statsUsageUnit} />
|
||||
</div>
|
||||
<div class="mt-5 flex lg:hidden">
|
||||
<div class="flex flex-col justify-between rounded-3xl bg-immich-gray p-5 dark:bg-immich-dark-gray">
|
||||
<div class="flex flex-wrap gap-x-12">
|
||||
<div class="flex place-items-center gap-4 text-immich-primary dark:text-immich-dark-primary">
|
||||
<CameraIris size="25" />
|
||||
<Icon path={mdiCameraIris} size="25" />
|
||||
<p>PHOTOS</p>
|
||||
</div>
|
||||
|
||||
|
@ -50,7 +49,7 @@
|
|||
</div>
|
||||
<div class="flex flex-wrap gap-x-12">
|
||||
<div class="flex place-items-center gap-4 text-immich-primary dark:text-immich-dark-primary">
|
||||
<PlayCircle size="25" />
|
||||
<Icon path={mdiPlayCircle} size="25" />
|
||||
<p>VIDEOS</p>
|
||||
</div>
|
||||
|
||||
|
@ -62,7 +61,7 @@
|
|||
</div>
|
||||
<div class="flex flex-wrap gap-x-7">
|
||||
<div class="flex place-items-center gap-4 text-immich-primary dark:text-immich-dark-primary">
|
||||
<Memory size="25" />
|
||||
<Icon path={mdiMemory} size="25" />
|
||||
<p>STORAGE</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import type Icon from 'svelte-material-icons/AbTesting.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let logo: typeof Icon;
|
||||
export let icon: string;
|
||||
export let title: string;
|
||||
export let value: number;
|
||||
export let unit: string | undefined = undefined;
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
<div class="flex h-[140px] w-[250px] flex-col justify-between rounded-3xl bg-immich-gray p-5 dark:bg-immich-dark-gray">
|
||||
<div class="flex place-items-center gap-4 text-immich-primary dark:text-immich-dark-primary">
|
||||
<svelte:component this={logo} size="40" />
|
||||
<Icon path={icon} size="40" />
|
||||
<p>{title}</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSelect from '../setting-select.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import HelpCircleOutline from 'svelte-material-icons/HelpCircleOutline.svelte';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { fade } from 'svelte/transition';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
import { mdiHelpCircleOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let ffmpegConfig: SystemConfigFFmpegDto; // this is the config that is being edited
|
||||
export let disabled = false;
|
||||
|
@ -93,7 +94,7 @@
|
|||
<form autocomplete="off" on:submit|preventDefault>
|
||||
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||
<p class="text-sm dark:text-immich-dark-fg">
|
||||
<HelpCircleOutline class="inline" size="15" />
|
||||
<Icon path={mdiHelpCircleOutline} class="inline" size="15" />
|
||||
To learn more about the terminology used here, refer to FFmpeg documentation for
|
||||
<a href="https://trac.ffmpeg.org/wiki/Encode/H.264" class="underline" target="_blank" rel="noreferrer"
|
||||
>H.264 codec</a
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { AlbumResponseDto, api, ThumbnailFormat, UserResponseDto } from '@api';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import IconButton from '../elements/buttons/icon-button.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { OnClick, OnShowContextMenu } from './album-card';
|
||||
import { getContextMenuPosition } from '../../utils/context-menu';
|
||||
import { mdiDotsVertical } from '@mdi/js';
|
||||
|
||||
export let album: AlbumResponseDto;
|
||||
export let isSharingView = false;
|
||||
|
@ -75,7 +76,7 @@
|
|||
data-testid="context-button-parent"
|
||||
>
|
||||
<IconButton color="transparent-primary">
|
||||
<DotsVertical size="20" class="icon-white-drop-shadow" color="white" />
|
||||
<Icon path={mdiDotsVertical} size="20" class="icon-white-drop-shadow text-white" />
|
||||
</IconButton>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
import { TimeBucketSize, type AlbumResponseDto, type SharedLinkResponseDto } from '@api';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import FileImagePlusOutline from 'svelte-material-icons/FileImagePlusOutline.svelte';
|
||||
import FolderDownloadOutline from 'svelte-material-icons/FolderDownloadOutline.svelte';
|
||||
import { dateFormats } from '../../constants';
|
||||
import { createAssetInteractionStore } from '../../stores/asset-interaction.store';
|
||||
import { AssetStore } from '../../stores/assets.store';
|
||||
|
@ -21,6 +19,7 @@
|
|||
import ImmichLogo from '../shared-components/immich-logo.svelte';
|
||||
import ThemeButton from '../shared-components/theme-button.svelte';
|
||||
import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
|
||||
import { mdiFileImagePlusOutline, mdiFolderDownloadOutline } from '@mdi/js';
|
||||
|
||||
export let sharedLink: SharedLinkResponseDto;
|
||||
|
||||
|
@ -122,12 +121,12 @@
|
|||
<CircleIconButton
|
||||
title="Add Photos"
|
||||
on:click={() => openFileUploadDialog(album.id)}
|
||||
logo={FileImagePlusOutline}
|
||||
icon={mdiFileImagePlusOutline}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if album.assetCount > 0 && sharedLink.allowDownload}
|
||||
<CircleIconButton title="Download" on:click={() => downloadAlbum()} logo={FolderDownloadOutline} />
|
||||
<CircleIconButton title="Download" on:click={() => downloadAlbum()} icon={mdiFolderDownloadOutline} />
|
||||
{/if}
|
||||
|
||||
<ThemeButton />
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import { AlbumResponseDto, api, UserResponseDto } from '@api';
|
||||
import BaseModal from '../shared-components/base-modal.svelte';
|
||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
|
||||
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
|
||||
|
@ -11,6 +10,7 @@
|
|||
import { handleError } from '../../utils/handle-error';
|
||||
import ConfirmDialogue from '../shared-components/confirm-dialogue.svelte';
|
||||
import { getContextMenuPosition } from '../../utils/context-menu';
|
||||
import { mdiDotsVertical } from '@mdi/js';
|
||||
|
||||
export let album: AlbumResponseDto;
|
||||
|
||||
|
@ -99,7 +99,7 @@
|
|||
<div>
|
||||
<CircleIconButton
|
||||
on:click={(event) => showContextMenu(event, user)}
|
||||
logo={DotsVertical}
|
||||
icon={mdiDotsVertical}
|
||||
backgroundColor="transparent"
|
||||
hoverColor="#e2e7e9"
|
||||
size="20"
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
import { AlbumResponseDto, api, SharedLinkResponseDto, UserResponseDto } from '@api';
|
||||
import BaseModal from '../shared-components/base-modal.svelte';
|
||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||
import Link from 'svelte-material-icons/Link.svelte';
|
||||
import ShareCircle from 'svelte-material-icons/ShareCircle.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import ImmichLogo from '../shared-components/immich-logo.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { mdiLink, mdiShareCircle } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let album: AlbumResponseDto;
|
||||
let users: UserResponseDto[] = [];
|
||||
|
@ -128,7 +128,7 @@
|
|||
class="flex flex-col place-content-center place-items-center gap-2 hover:cursor-pointer"
|
||||
on:click={() => dispatch('share')}
|
||||
>
|
||||
<Link size={24} />
|
||||
<Icon path={mdiLink} size={24} />
|
||||
<p class="text-sm">Create link</p>
|
||||
</button>
|
||||
|
||||
|
@ -137,7 +137,7 @@
|
|||
class="flex flex-col place-content-center place-items-center gap-2 hover:cursor-pointer"
|
||||
on:click={() => goto(AppRoute.SHARED_LINKS)}
|
||||
>
|
||||
<ShareCircle size={24} />
|
||||
<Icon path={mdiShareCircle} size={24} />
|
||||
<p class="text-sm">View links</p>
|
||||
</button>
|
||||
{/if}
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { photoZoomState } from '$lib/stores/zoom-image.store';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { getContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import { AssetJobName, AssetResponseDto, AssetTypeEnum, api } from '@api';
|
||||
import {
|
||||
mdiAlertOutline,
|
||||
mdiArrowLeft,
|
||||
mdiCloudDownloadOutline,
|
||||
mdiContentCopy,
|
||||
mdiDeleteOutline,
|
||||
mdiDotsVertical,
|
||||
mdiHeart,
|
||||
mdiHeartOutline,
|
||||
mdiInformationOutline,
|
||||
mdiMagnifyMinusOutline,
|
||||
mdiMagnifyPlusOutline,
|
||||
mdiMotionPauseOutline,
|
||||
mdiMoviePlayOutline,
|
||||
} from '@mdi/js';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import CloudDownloadOutline from 'svelte-material-icons/CloudDownloadOutline.svelte';
|
||||
import AlertOutline from 'svelte-material-icons/AlertOutline.svelte';
|
||||
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Heart from 'svelte-material-icons/Heart.svelte';
|
||||
import HeartOutline from 'svelte-material-icons/HeartOutline.svelte';
|
||||
import InformationOutline from 'svelte-material-icons/InformationOutline.svelte';
|
||||
import MagnifyMinusOutline from 'svelte-material-icons/MagnifyMinusOutline.svelte';
|
||||
import MagnifyPlusOutline from 'svelte-material-icons/MagnifyPlusOutline.svelte';
|
||||
import MotionPauseOutline from 'svelte-material-icons/MotionPauseOutline.svelte';
|
||||
import MotionPlayOutline from 'svelte-material-icons/MotionPlayOutline.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
|
||||
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
|
||||
import { getContextMenuPosition } from '$lib/utils/context-menu';
|
||||
|
||||
export let asset: AssetResponseDto;
|
||||
export let showCopyButton: boolean;
|
||||
|
@ -74,13 +76,13 @@
|
|||
class="z-[1001] flex h-16 place-items-center justify-between bg-gradient-to-b from-black/40 px-3 transition-transform duration-200"
|
||||
>
|
||||
<div class="text-white">
|
||||
<CircleIconButton isOpacity={true} logo={ArrowLeft} on:click={() => dispatch('goBack')} />
|
||||
<CircleIconButton isOpacity={true} icon={mdiArrowLeft} on:click={() => dispatch('goBack')} />
|
||||
</div>
|
||||
<div class="flex w-[calc(100%-3rem)] justify-end gap-2 overflow-hidden text-white">
|
||||
{#if asset.isOffline}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
logo={AlertOutline}
|
||||
icon={mdiAlertOutline}
|
||||
on:click={() => dispatch('showDetail')}
|
||||
title="Asset Offline"
|
||||
/>
|
||||
|
@ -89,14 +91,14 @@
|
|||
{#if isMotionPhotoPlaying}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
logo={MotionPauseOutline}
|
||||
icon={mdiMotionPauseOutline}
|
||||
title="Stop Motion Photo"
|
||||
on:click={() => dispatch('stopMotionPhoto')}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
logo={MotionPlayOutline}
|
||||
icon={mdiMoviePlayOutline}
|
||||
title="Play Motion Photo"
|
||||
on:click={() => dispatch('playMotionPhoto')}
|
||||
/>
|
||||
|
@ -106,7 +108,7 @@
|
|||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
hideMobile={true}
|
||||
logo={$photoZoomState && $photoZoomState.currentZoom > 1 ? MagnifyMinusOutline : MagnifyPlusOutline}
|
||||
icon={$photoZoomState && $photoZoomState.currentZoom > 1 ? mdiMagnifyMinusOutline : mdiMagnifyPlusOutline}
|
||||
title="Zoom Image"
|
||||
on:click={() => {
|
||||
const zoomImage = new CustomEvent('zoomImage');
|
||||
|
@ -117,7 +119,7 @@
|
|||
{#if showCopyButton}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
logo={ContentCopy}
|
||||
icon={mdiContentCopy}
|
||||
title="Copy Image"
|
||||
on:click={() => {
|
||||
const copyEvent = new CustomEvent('copyImage');
|
||||
|
@ -129,7 +131,7 @@
|
|||
{#if showDownloadButton}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
logo={CloudDownloadOutline}
|
||||
icon={mdiCloudDownloadOutline}
|
||||
on:click={() => dispatch('download')}
|
||||
title="Download"
|
||||
/>
|
||||
|
@ -137,7 +139,7 @@
|
|||
{#if showDetailButton}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
logo={InformationOutline}
|
||||
icon={mdiInformationOutline}
|
||||
on:click={() => dispatch('showDetail')}
|
||||
title="Info"
|
||||
/>
|
||||
|
@ -145,7 +147,7 @@
|
|||
{#if isOwner}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
logo={asset.isFavorite ? Heart : HeartOutline}
|
||||
icon={asset.isFavorite ? mdiHeart : mdiHeartOutline}
|
||||
on:click={() => dispatch('favorite')}
|
||||
title="Favorite"
|
||||
/>
|
||||
|
@ -153,10 +155,10 @@
|
|||
|
||||
{#if isOwner}
|
||||
{#if !asset.isReadOnly || !asset.isExternal}
|
||||
<CircleIconButton isOpacity={true} logo={DeleteOutline} on:click={() => dispatch('delete')} title="Delete" />
|
||||
<CircleIconButton isOpacity={true} icon={mdiDeleteOutline} on:click={() => dispatch('delete')} title="Delete" />
|
||||
{/if}
|
||||
<div use:clickOutside on:outclick={() => (isShowAssetOptions = false)}>
|
||||
<CircleIconButton isOpacity={true} logo={DotsVertical} on:click={showOptionsMenu} title="More" />
|
||||
<CircleIconButton isOpacity={true} icon={mdiDotsVertical} on:click={showOptionsMenu} title="More" />
|
||||
{#if isShowAssetOptions}
|
||||
<ContextMenu {...contextMenuPosition} direction="left">
|
||||
{#if showSlideshow}
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import { AlbumResponseDto, api, AssetJobName, AssetResponseDto, AssetTypeEnum, SharedLinkResponseDto } from '@api';
|
||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
|
||||
import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
|
||||
import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
|
||||
import ImageBrokenVariant from 'svelte-material-icons/ImageBrokenVariant.svelte';
|
||||
import { fly } from 'svelte/transition';
|
||||
import AlbumSelectionModal from '../shared-components/album-selection-modal.svelte';
|
||||
import { notificationController, NotificationType } from '../shared-components/notification/notification';
|
||||
|
@ -16,8 +13,6 @@
|
|||
import { ProjectionType } from '$lib/constants';
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import ProfileImageCropper from '../shared-components/profile-image-cropper.svelte';
|
||||
import Pause from 'svelte-material-icons/Pause.svelte';
|
||||
import Play from 'svelte-material-icons/Play.svelte';
|
||||
import { isShowDetail } from '$lib/stores/preferences.store';
|
||||
import { addAssetsToAlbum, downloadFile } from '$lib/utils/asset-utils';
|
||||
import NavigationArea from './navigation-area.svelte';
|
||||
|
@ -25,11 +20,11 @@
|
|||
import { handleError } from '$lib/utils/handle-error';
|
||||
import type { AssetStore } from '$lib/stores/assets.store';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
|
||||
import ProgressBar, { ProgressBarStatus } from '../shared-components/progress-bar/progress-bar.svelte';
|
||||
import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiImageBrokenVariant, mdiPause, mdiPlay } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let assetStore: AssetStore | null = null;
|
||||
export let asset: AssetResponseDto;
|
||||
|
@ -368,14 +363,14 @@
|
|||
<!-- SlideShowController -->
|
||||
<div class="flex">
|
||||
<div class="m-4 flex gap-2">
|
||||
<CircleIconButton logo={Close} on:click={handleStopSlideshow} title="Exit Slideshow" />
|
||||
<CircleIconButton icon={mdiClose} on:click={handleStopSlideshow} title="Exit Slideshow" />
|
||||
<CircleIconButton
|
||||
logo={progressBarStatus === ProgressBarStatus.Paused ? Play : Pause}
|
||||
icon={progressBarStatus === ProgressBarStatus.Paused ? mdiPlay : mdiPause}
|
||||
on:click={() => (progressBarStatus === ProgressBarStatus.Paused ? progressBar.play() : progressBar.pause())}
|
||||
title={progressBarStatus === ProgressBarStatus.Paused ? 'Play' : 'Pause'}
|
||||
/>
|
||||
<CircleIconButton logo={ChevronLeft} on:click={navigateAssetBackward} title="Previous" />
|
||||
<CircleIconButton logo={ChevronRight} on:click={navigateAssetForward} title="Next" />
|
||||
<CircleIconButton icon={mdiChevronLeft} on:click={navigateAssetBackward} title="Previous" />
|
||||
<CircleIconButton icon={mdiChevronRight} on:click={navigateAssetForward} title="Next" />
|
||||
</div>
|
||||
<ProgressBar
|
||||
autoplay
|
||||
|
@ -414,7 +409,7 @@
|
|||
|
||||
{#if !isSlideshowMode && showNavigation}
|
||||
<div class="column-span-1 z-[999] col-start-1 row-span-1 row-start-2 mb-[60px] justify-self-start">
|
||||
<NavigationArea on:click={navigateAssetBackward}><ChevronLeft size="36" /></NavigationArea>
|
||||
<NavigationArea on:click={navigateAssetBackward}><Icon path={mdiChevronLeft} size="36" /></NavigationArea>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
@ -425,7 +420,7 @@
|
|||
<div
|
||||
class="px-auto flex aspect-square h-full items-center justify-center bg-gray-100 dark:bg-immich-dark-gray"
|
||||
>
|
||||
<ImageBrokenVariant size="25%" />
|
||||
<Icon path={mdiImageBrokenVariant} size="25%" />
|
||||
</div>
|
||||
</div>
|
||||
{:else if asset.type === AssetTypeEnum.Image}
|
||||
|
@ -455,7 +450,7 @@
|
|||
|
||||
{#if !isSlideshowMode && showNavigation}
|
||||
<div class="z-[999] col-span-1 col-start-4 row-span-1 row-start-2 mb-[60px] justify-self-end">
|
||||
<NavigationArea on:click={navigateAssetForward}><ChevronRight size="36" /></NavigationArea>
|
||||
<NavigationArea on:click={navigateAssetForward}><Icon path={mdiChevronRight} size="36" /></NavigationArea>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -7,14 +7,11 @@
|
|||
import type { LatLngTuple } from 'leaflet';
|
||||
import { DateTime } from 'luxon';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import Calendar from 'svelte-material-icons/Calendar.svelte';
|
||||
import CameraIris from 'svelte-material-icons/CameraIris.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import ImageOutline from 'svelte-material-icons/ImageOutline.svelte';
|
||||
import MapMarkerOutline from 'svelte-material-icons/MapMarkerOutline.svelte';
|
||||
import { asByteUnitString } from '../../utils/byte-units';
|
||||
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||
import { mdiCalendar, mdiCameraIris, mdiClose, mdiImageOutline, mdiMapMarkerOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let asset: AssetResponseDto;
|
||||
export let albums: AlbumResponseDto[] = [];
|
||||
|
@ -91,7 +88,7 @@
|
|||
class="flex place-content-center place-items-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900"
|
||||
on:click={() => dispatch('close')}
|
||||
>
|
||||
<Close size="24" />
|
||||
<Icon path={mdiClose} size="24" />
|
||||
</button>
|
||||
|
||||
<p class="text-lg text-immich-fg dark:text-immich-dark-fg">Info</p>
|
||||
|
@ -186,7 +183,7 @@
|
|||
})}
|
||||
<div class="flex gap-4 py-4">
|
||||
<div>
|
||||
<Calendar size="24" />
|
||||
<Icon path={mdiCalendar} size="24" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
@ -218,7 +215,7 @@
|
|||
|
||||
{#if asset.exifInfo?.fileSizeInByte}
|
||||
<div class="flex gap-4 py-4">
|
||||
<div><ImageOutline size="24" /></div>
|
||||
<div><Icon path={mdiImageOutline} size="24" /></div>
|
||||
|
||||
<div>
|
||||
<p class="break-all">
|
||||
|
@ -242,7 +239,7 @@
|
|||
|
||||
{#if asset.exifInfo?.make || asset.exifInfo?.model || asset.exifInfo?.fNumber}
|
||||
<div class="flex gap-4 py-4">
|
||||
<div><CameraIris size="24" /></div>
|
||||
<div><Icon path={mdiCameraIris} size="24" /></div>
|
||||
|
||||
<div>
|
||||
<p>{asset.exifInfo.make || ''} {asset.exifInfo.model || ''}</p>
|
||||
|
@ -271,7 +268,7 @@
|
|||
|
||||
{#if asset.exifInfo?.city}
|
||||
<div class="flex gap-4 py-4">
|
||||
<div><MapMarkerOutline size="24" /></div>
|
||||
<div><Icon path={mdiMapMarkerOutline} size="24" /></div>
|
||||
|
||||
<div>
|
||||
<p>{asset.exifInfo.city}</p>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { DownloadProgress, downloadAssets, downloadManager, isDownloading } from '$lib/stores/download';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import { fly, slide } from 'svelte/transition';
|
||||
import { asByteUnitString } from '../../utils/byte-units';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
|
||||
const abort = (downloadKey: string, download: DownloadProgress) => {
|
||||
download.abort?.abort();
|
||||
|
@ -39,7 +39,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="absolute right-2">
|
||||
<CircleIconButton on:click={() => abort(downloadKey, download)} size="20" logo={Close} forceDark />
|
||||
<CircleIconButton on:click={() => abort(downloadKey, download)} size="20" icon={mdiClose} forceDark />
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
import { fade } from 'svelte/transition';
|
||||
import { thumbHashToDataURL } from 'thumbhash';
|
||||
import { Buffer } from 'buffer';
|
||||
import EyeOffOutline from 'svelte-material-icons/EyeOffOutline.svelte';
|
||||
import { mdiEyeOffOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let url: string;
|
||||
export let altText: string;
|
||||
|
@ -18,7 +19,7 @@
|
|||
export let border = false;
|
||||
let complete = false;
|
||||
|
||||
export let eyeColor = 'white';
|
||||
export let eyeColor: 'black' | 'white' = 'white';
|
||||
</script>
|
||||
|
||||
<img
|
||||
|
@ -43,7 +44,7 @@
|
|||
|
||||
{#if hidden}
|
||||
<div class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform">
|
||||
<EyeOffOutline size="2em" color={eyeColor} />
|
||||
<Icon path={mdiEyeOffOutline} size="2em" class="text-{eyeColor}" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -4,16 +4,19 @@
|
|||
import { timeToSeconds } from '$lib/utils/time-to-seconds';
|
||||
import { api, AssetResponseDto, AssetTypeEnum, ThumbnailFormat } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import ArchiveArrowDownOutline from 'svelte-material-icons/ArchiveArrowDownOutline.svelte';
|
||||
import CheckCircle from 'svelte-material-icons/CheckCircle.svelte';
|
||||
import Heart from 'svelte-material-icons/Heart.svelte';
|
||||
import ImageBrokenVariant from 'svelte-material-icons/ImageBrokenVariant.svelte';
|
||||
import MotionPauseOutline from 'svelte-material-icons/MotionPauseOutline.svelte';
|
||||
import MotionPlayOutline from 'svelte-material-icons/MotionPlayOutline.svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import ImageThumbnail from './image-thumbnail.svelte';
|
||||
import VideoThumbnail from './video-thumbnail.svelte';
|
||||
import Rotate360Icon from 'svelte-material-icons/Rotate360.svelte';
|
||||
import {
|
||||
mdiArchiveArrowDownOutline,
|
||||
mdiCheckCircle,
|
||||
mdiHeart,
|
||||
mdiImageBrokenVariant,
|
||||
mdiMotionPauseOutline,
|
||||
mdiMotionPlayOutline,
|
||||
mdiRotate360,
|
||||
} from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
|
@ -93,13 +96,13 @@
|
|||
{disabled}
|
||||
>
|
||||
{#if disabled}
|
||||
<CheckCircle size="24" class="text-zinc-800" />
|
||||
<Icon path={mdiCheckCircle} size="24" class="text-zinc-800" />
|
||||
{:else if selected}
|
||||
<div class="rounded-full bg-[#D9DCEF] dark:bg-[#232932]">
|
||||
<CheckCircle size="24" class="text-immich-primary" />
|
||||
<Icon path={mdiCheckCircle} size="24" class="text-immich-primary" />
|
||||
</div>
|
||||
{:else}
|
||||
<CheckCircle size="24" class="text-white/80 hover:text-white" />
|
||||
<Icon path={mdiCheckCircle} size="24" class="text-white/80 hover:text-white" />
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
|
@ -119,20 +122,20 @@
|
|||
<!-- Favorite asset star -->
|
||||
{#if !api.isSharedLink && asset.isFavorite}
|
||||
<div class="absolute bottom-2 left-2 z-10">
|
||||
<Heart size="24" class="text-white" />
|
||||
<Icon path={mdiHeart} size="24" class="text-white" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !api.isSharedLink && showArchiveIcon && asset.isArchived}
|
||||
<div class="absolute {asset.isFavorite ? 'bottom-10' : 'bottom-2'} left-2 z-10">
|
||||
<ArchiveArrowDownOutline size="24" class="text-white" />
|
||||
<Icon path={mdiArchiveArrowDownOutline} size="24" class="text-white" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if asset.type === AssetTypeEnum.Image && asset.exifInfo?.projectionType === ProjectionType.EQUIRECTANGULAR}
|
||||
<div class="absolute right-0 top-0 z-20 flex place-items-center gap-1 text-xs font-medium text-white">
|
||||
<span class="pr-2 pt-2">
|
||||
<Rotate360Icon size="24" />
|
||||
<Icon path={mdiRotate360} size="24" />
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -148,7 +151,7 @@
|
|||
/>
|
||||
{:else}
|
||||
<div class="flex h-full w-full items-center justify-center p-4">
|
||||
<ImageBrokenVariant size="48" />
|
||||
<Icon path={mdiImageBrokenVariant} size="48" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
@ -167,8 +170,8 @@
|
|||
<div class="absolute top-0 h-full w-full">
|
||||
<VideoThumbnail
|
||||
url={api.getAssetFileUrl(asset.livePhotoVideoId, false, true)}
|
||||
pauseIcon={MotionPauseOutline}
|
||||
playIcon={MotionPlayOutline}
|
||||
pauseIcon={mdiMotionPauseOutline}
|
||||
playIcon={mdiMotionPlayOutline}
|
||||
showTime={false}
|
||||
curve={selected}
|
||||
playbackOnIconHover
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { Duration } from 'luxon';
|
||||
import PauseCircleOutline from 'svelte-material-icons/PauseCircleOutline.svelte';
|
||||
import PlayCircleOutline from 'svelte-material-icons/PlayCircleOutline.svelte';
|
||||
import AlertCircleOutline from 'svelte-material-icons/AlertCircleOutline.svelte';
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import { mdiAlertCircleOutline, mdiPauseCircleOutline, mdiPlayCircleOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let url: string;
|
||||
export let durationInSeconds = 0;
|
||||
|
@ -11,8 +10,8 @@
|
|||
export let playbackOnIconHover = false;
|
||||
export let showTime = true;
|
||||
export let curve = false;
|
||||
export let playIcon = PlayCircleOutline;
|
||||
export let pauseIcon = PauseCircleOutline;
|
||||
export let playIcon = mdiPlayCircleOutline;
|
||||
export let pauseIcon = mdiPauseCircleOutline;
|
||||
|
||||
let remainingSeconds = durationInSeconds;
|
||||
let loading = true;
|
||||
|
@ -55,12 +54,12 @@
|
|||
{#if loading}
|
||||
<LoadingSpinner />
|
||||
{:else if error}
|
||||
<AlertCircleOutline size="24" class="text-red-600" />
|
||||
<Icon path={mdiAlertCircleOutline} size="24" class="text-red-600" />
|
||||
{:else}
|
||||
<svelte:component this={pauseIcon} size="24" />
|
||||
<Icon path={pauseIcon} size="24" />
|
||||
{/if}
|
||||
{:else}
|
||||
<svelte:component this={playIcon} size="24" />
|
||||
<Icon path={playIcon} size="24" />
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import type Icon from 'svelte-material-icons/AbTesting.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let logo: typeof Icon;
|
||||
export let icon: string;
|
||||
export let backgroundColor = '';
|
||||
export let hoverColor = '#e2e7e9';
|
||||
export let padding = '3';
|
||||
|
@ -23,7 +23,7 @@
|
|||
{hideMobile && 'hidden sm:flex'}"
|
||||
on:click
|
||||
>
|
||||
<svelte:component this={logo} {size} />
|
||||
<Icon path={icon} {size} />
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
</script>
|
||||
|
||||
<script lang="ts" generics="T">
|
||||
import Icon from './icon.svelte';
|
||||
|
||||
import { mdiCheck } from '@mdi/js';
|
||||
|
||||
import _ from 'lodash';
|
||||
import LinkButton from './buttons/link-button.svelte';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { fly } from 'svelte/transition';
|
||||
import type Icon from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Check from 'svelte-material-icons/Check.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
|
@ -24,7 +26,7 @@
|
|||
|
||||
type RenderedOption = {
|
||||
title: string;
|
||||
icon?: typeof Icon;
|
||||
icon?: string;
|
||||
};
|
||||
|
||||
let showMenu = false;
|
||||
|
@ -61,7 +63,7 @@
|
|||
<LinkButton on:click={() => (showMenu = true)}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
{#if renderedSelectedOption?.icon}
|
||||
<svelte:component this={renderedSelectedOption.icon} size="18" />
|
||||
<Icon path={renderedSelectedOption.icon} size="18" />
|
||||
{/if}
|
||||
<p class="hidden sm:block">{renderedSelectedOption.title}</p>
|
||||
</div>
|
||||
|
@ -81,7 +83,7 @@
|
|||
>
|
||||
{#if _.isEqual(selectedOption, option)}
|
||||
<div class="text-immich-primary dark:text-immich-dark-primary">
|
||||
<Check size="18" />
|
||||
<Icon path={mdiCheck} size="18" />
|
||||
</div>
|
||||
<p class="justify-self-start text-immich-primary dark:text-immich-dark-primary">
|
||||
{renderedOption.title}
|
||||
|
|
36
web/src/lib/components/elements/icon.svelte
Normal file
36
web/src/lib/components/elements/icon.svelte
Normal file
|
@ -0,0 +1,36 @@
|
|||
<script lang="ts">
|
||||
import type { AriaRole } from 'svelte/elements';
|
||||
|
||||
export let size: string | number = '1em';
|
||||
export let color = 'currentColor';
|
||||
export let path: string;
|
||||
export let title = '';
|
||||
export let desc = '';
|
||||
export let flipped = false;
|
||||
let className = '';
|
||||
export { className as class };
|
||||
export let viewBox = '0 0 24 24';
|
||||
export let role: AriaRole = 'img';
|
||||
export let ariaHidden: boolean | undefined = undefined;
|
||||
export let ariaLabel: string | undefined = undefined;
|
||||
export let ariaLabelledby: string | undefined = undefined;
|
||||
</script>
|
||||
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
{viewBox}
|
||||
class="{className} {flipped && '-scale-x-100'}"
|
||||
{role}
|
||||
aria-label={ariaLabel}
|
||||
aria-hidden={ariaHidden}
|
||||
aria-labelledby={ariaLabelledby}
|
||||
>
|
||||
{#if title}
|
||||
<title>{title}</title>
|
||||
{/if}
|
||||
{#if desc}
|
||||
<desc>{desc}</desc>
|
||||
{/if}
|
||||
<path d={path} fill={color} />
|
||||
</svg>
|
|
@ -6,15 +6,14 @@
|
|||
import { fly } from 'svelte/transition';
|
||||
import ControlAppBar from '../shared-components/control-app-bar.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import Merge from 'svelte-material-icons/Merge.svelte';
|
||||
import CallMerge from 'svelte-material-icons/CallMerge.svelte';
|
||||
import { flip } from 'svelte/animate';
|
||||
import { NotificationType, notificationController } from '../shared-components/notification/notification';
|
||||
import ConfirmDialogue from '../shared-components/confirm-dialogue.svelte';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { goto, invalidateAll } from '$app/navigation';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import SwapHorizontal from 'svelte-material-icons/SwapHorizontal.svelte';
|
||||
import { mdiCallMerge, mdiMerge, mdiSwapHorizontal } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let person: PersonResponseDto;
|
||||
let people: PersonResponseDto[] = [];
|
||||
|
@ -104,7 +103,7 @@
|
|||
isShowConfirmation = true;
|
||||
}}
|
||||
>
|
||||
<Merge size={18} />
|
||||
<Icon path={mdiMerge} size={18} />
|
||||
<span class="ml-2"> Merge</span></Button
|
||||
>
|
||||
</svelte:fragment>
|
||||
|
@ -123,10 +122,10 @@
|
|||
|
||||
{#if hasSelection}
|
||||
<span class="grid grid-cols-1"
|
||||
><CallMerge size={48} class="rotate-90 dark:text-white" />
|
||||
><Icon path={mdiCallMerge} size={48} class="rotate-90 dark:text-white" />
|
||||
{#if selectedPeople.length === 1}
|
||||
<button class="flex justify-center" on:click={handleSwapPeople}
|
||||
><SwapHorizontal size={24} class="dark:text-white" />
|
||||
><Icon path={mdiSwapHorizontal} size={24} class="dark:text-white" />
|
||||
</button>
|
||||
{/if}
|
||||
</span>
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
import { api, type PersonResponseDto } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import Merge from 'svelte-material-icons/Merge.svelte';
|
||||
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { mdiArrowLeft, mdiClose, mdiMerge } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
reject: void;
|
||||
|
@ -40,7 +39,7 @@
|
|||
Merge faces - {title}
|
||||
</h1>
|
||||
<div class="p-2">
|
||||
<CircleIconButton logo={Close} on:click={() => dispatch('close')} />
|
||||
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -57,7 +56,7 @@
|
|||
</div>
|
||||
<div class="mx-0.5 flex md:mx-2">
|
||||
<CircleIconButton
|
||||
logo={Merge}
|
||||
icon={mdiMerge}
|
||||
on:click={() => ([personMerge1, personMerge2] = [personMerge2, personMerge1])}
|
||||
/>
|
||||
</div>
|
||||
|
@ -83,7 +82,7 @@
|
|||
{:else}
|
||||
<div class="grid w-full grid-cols-1 gap-2">
|
||||
<div class="px-2">
|
||||
<button on:click={() => (choosePersonToMerge = false)}> <ArrowLeft /></button>
|
||||
<button on:click={() => (choosePersonToMerge = false)}> <Icon path={mdiArrowLeft} /></button>
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
<div class="flex flex-wrap justify-center md:grid md:grid-cols-{potentialMergePeople.length}">
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
import { getContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
||||
import IconButton from '../elements/buttons/icon-button.svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
|
||||
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
|
||||
import Portal from '../shared-components/portal/portal.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { mdiDotsVertical } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let person: PersonResponseDto;
|
||||
|
||||
|
@ -71,7 +72,7 @@
|
|||
id={`icon-${person.id}`}
|
||||
>
|
||||
<IconButton color="transparent-primary">
|
||||
<DotsVertical size="20" class="icon-white-drop-shadow" color="white" />
|
||||
<Icon path={mdiDotsVertical} size="20" class="icon-white-drop-shadow text-white" />
|
||||
</IconButton>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import Cake from 'svelte-material-icons/Cake.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
|
||||
import { mdiCake } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let birthDate: string;
|
||||
|
||||
|
@ -22,7 +23,7 @@
|
|||
<div
|
||||
class="flex flex-col place-content-center place-items-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||
>
|
||||
<Cake size="4em" />
|
||||
<Icon path={mdiCake} size="4em" />
|
||||
<h1 class="text-2xl font-medium text-immich-primary dark:text-immich-dark-primary">Set date of birth</h1>
|
||||
|
||||
<p class="text-sm dark:text-immich-dark-fg">
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
import { fly } from 'svelte/transition';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import IconButton from '../elements/buttons/icon-button.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import Restart from 'svelte-material-icons/Restart.svelte';
|
||||
import Eye from 'svelte-material-icons/Eye.svelte';
|
||||
import EyeOff from 'svelte-material-icons/EyeOff.svelte';
|
||||
import { mdiClose, mdiEye, mdiEyeOff, mdiRestart } from '@mdi/js';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
|
@ -24,15 +21,19 @@
|
|||
class="sticky top-0 z-10 flex h-16 w-full items-center justify-between border-b bg-white p-1 dark:border-immich-dark-gray dark:bg-black dark:text-immich-dark-fg md:p-8"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<CircleIconButton logo={Close} on:click={() => dispatch('closeClick')} />
|
||||
<CircleIconButton icon={mdiClose} on:click={() => dispatch('closeClick')} />
|
||||
<p class="ml-4 hidden sm:block">Show & hide faces</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-end">
|
||||
<div class="flex items-center md:mr-8">
|
||||
<CircleIconButton title="Reset faces visibility" logo={Restart} on:click={() => dispatch('reset-visibility')} />
|
||||
<CircleIconButton
|
||||
title="Reset faces visibility"
|
||||
icon={mdiRestart}
|
||||
on:click={() => dispatch('reset-visibility')}
|
||||
/>
|
||||
<CircleIconButton
|
||||
title="Toggle visibility"
|
||||
logo={toggleVisibility ? Eye : EyeOff}
|
||||
icon={toggleVisibility ? mdiEye : mdiEyeOff}
|
||||
on:click={() => dispatch('toggle-visibility')}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<script lang="ts">
|
||||
import type { APIKeyResponseDto } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import KeyVariant from 'svelte-material-icons/KeyVariant.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiKeyVariant } from '@mdi/js';
|
||||
|
||||
export let apiKey: Partial<APIKeyResponseDto>;
|
||||
export let title = 'API Key';
|
||||
|
@ -22,7 +23,7 @@
|
|||
<div
|
||||
class="flex flex-col place-content-center place-items-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||
>
|
||||
<KeyVariant size="4em" />
|
||||
<Icon path={mdiKeyVariant} size="4em" />
|
||||
<h1 class="text-2xl font-medium text-immich-primary dark:text-immich-dark-primary">
|
||||
{title}
|
||||
</h1>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import KeyVariant from 'svelte-material-icons/KeyVariant.svelte';
|
||||
import { copyToClipboard } from '@api';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
|
||||
import { mdiKeyVariant } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let secret = '';
|
||||
|
||||
|
@ -24,7 +25,7 @@
|
|||
<div
|
||||
class="flex flex-col place-content-center place-items-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||
>
|
||||
<KeyVariant size="4em" />
|
||||
<Icon path={mdiKeyVariant} size="4em" />
|
||||
<h1 class="text-2xl font-medium text-immich-primary dark:text-immich-dark-primary">API Key</h1>
|
||||
|
||||
<p class="text-sm dark:text-immich-dark-fg">
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { AlbumResponseDto, api } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import ImageAlbum from 'svelte-material-icons/ImageAlbum.svelte';
|
||||
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
|
||||
import { handleError } from '../../utils/handle-error';
|
||||
import { mdiImageAlbum } from '@mdi/js';
|
||||
|
||||
export let album: AlbumResponseDto;
|
||||
|
||||
|
@ -36,7 +35,7 @@
|
|||
<div
|
||||
class="flex flex-col place-content-center place-items-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||
>
|
||||
<ImageAlbum size="4em" />
|
||||
<Icon path={mdiImageAlbum} size="4em" />
|
||||
<h1 class="text-2xl font-medium text-immich-primary dark:text-immich-dark-primary">Edit album</h1>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { api, UserResponseDto } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import AccountEditOutline from 'svelte-material-icons/AccountEditOutline.svelte';
|
||||
import { notificationController, NotificationType } from '../shared-components/notification/notification';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import { handleError } from '../../utils/handle-error';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiAccountEditOutline } from '@mdi/js';
|
||||
|
||||
export let user: UserResponseDto;
|
||||
export let canResetPassword = true;
|
||||
|
@ -72,7 +73,7 @@
|
|||
<div
|
||||
class="flex flex-col place-content-center place-items-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||
>
|
||||
<AccountEditOutline size="4em" />
|
||||
<Icon path={mdiAccountEditOutline} size="4em" />
|
||||
<h1 class="text-2xl font-medium text-immich-primary dark:text-immich-dark-primary">Edit user</h1>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import FolderRemove from 'svelte-material-icons/FolderRemove.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiFolderRemove } from '@mdi/js';
|
||||
|
||||
export let exclusionPattern: string;
|
||||
export let canDelete = false;
|
||||
|
@ -20,7 +21,7 @@
|
|||
<div
|
||||
class="flex flex-col place-content-center place-items-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||
>
|
||||
<FolderRemove size="4em" />
|
||||
<Icon path={mdiFolderRemove} size="4em" />
|
||||
<h1 class="text-2xl font-medium text-immich-primary dark:text-immich-dark-primary">Add Exclusion pattern</h1>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import FolderSync from 'svelte-material-icons/FolderSync.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
|
||||
import { mdiFolderSync } from '@mdi/js';
|
||||
|
||||
export let importPath: string;
|
||||
export let title = 'Import path';
|
||||
|
@ -22,7 +23,7 @@
|
|||
<div
|
||||
class="flex flex-col place-content-center place-items-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||
>
|
||||
<FolderSync size="4em" />
|
||||
<Icon path={mdiFolderSync} size="4em" />
|
||||
<h1 class="text-2xl font-medium text-immich-primary dark:text-immich-dark-primary">
|
||||
{title}
|
||||
</h1>
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
import { handleError } from '../../utils/handle-error';
|
||||
import LibraryImportPathForm from './library-import-path-form.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import PencilOutline from 'svelte-material-icons/PencilOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { LibraryResponseDto } from '@api';
|
||||
import { mdiPencilOutline } from '@mdi/js';
|
||||
|
||||
export let library: Partial<LibraryResponseDto>;
|
||||
|
||||
|
@ -141,7 +142,7 @@
|
|||
}}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<PencilOutline size="16" />
|
||||
<Icon path={mdiPencilOutline} size="16" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
import { LibraryType, type LibraryResponseDto } from '@api';
|
||||
import { handleError } from '../../utils/handle-error';
|
||||
import { onMount } from 'svelte';
|
||||
import PencilOutline from 'svelte-material-icons/PencilOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import LibraryExclusionPatternForm from './library-exclusion-pattern-form.svelte';
|
||||
import { mdiPencilOutline } from '@mdi/js';
|
||||
|
||||
export let library: Partial<LibraryResponseDto>;
|
||||
|
||||
|
@ -139,7 +140,7 @@
|
|||
}}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<PencilOutline size="16" />
|
||||
<Icon path={mdiPencilOutline} size="16" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -6,12 +6,6 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
|
||||
import { fromLocalDateTime } from '$lib/utils/timeline-util';
|
||||
import Play from 'svelte-material-icons/Play.svelte';
|
||||
import Pause from 'svelte-material-icons/Pause.svelte';
|
||||
import ChevronDown from 'svelte-material-icons/ChevronDown.svelte';
|
||||
import ChevronUp from 'svelte-material-icons/ChevronUp.svelte';
|
||||
import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
|
||||
import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { page } from '$app/stores';
|
||||
import noThumbnailUrl from '$lib/assets/no-thumbnail.png';
|
||||
|
@ -20,6 +14,7 @@
|
|||
import IntersectionObserver from '$lib/components/asset-viewer/intersection-observer.svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { tweened } from 'svelte/motion';
|
||||
import { mdiChevronDown, mdiChevronLeft, mdiChevronRight, mdiChevronUp, mdiPause, mdiPlay } from '@mdi/js';
|
||||
|
||||
const parseIndex = (s: string | null, max: number | null) => Math.max(Math.min(parseInt(s ?? '') || 0, max ?? 0), 0);
|
||||
|
||||
|
@ -115,7 +110,7 @@
|
|||
|
||||
{#if !galleryInView}
|
||||
<div class="flex place-content-center place-items-center gap-2 overflow-hidden">
|
||||
<CircleIconButton logo={paused ? Play : Pause} forceDark on:click={() => (paused = !paused)} />
|
||||
<CircleIconButton icon={paused ? mdiPlay : mdiPause} forceDark on:click={() => (paused = !paused)} />
|
||||
|
||||
{#each currentMemory.assets as _, i}
|
||||
<button class="relative w-full py-2" on:click={() => goto(`?memory=${memoryIndex}&asset=${i}`)}>
|
||||
|
@ -147,7 +142,7 @@
|
|||
class:opacity-100={galleryInView}
|
||||
>
|
||||
<button on:click={() => memoryWrapper.scrollIntoView({ behavior: 'smooth' })} disabled={!galleryInView}>
|
||||
<CircleIconButton logo={ChevronUp} backgroundColor="white" forceDark />
|
||||
<CircleIconButton icon={mdiChevronUp} backgroundColor="white" forceDark />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -190,14 +185,14 @@
|
|||
<div class="ml-4 flex h-full flex-col place-content-center place-items-center">
|
||||
<div class="inline-block">
|
||||
{#if canGoBack}
|
||||
<CircleIconButton logo={ChevronLeft} backgroundColor="#202123" on:click={toPrevious} />
|
||||
<CircleIconButton icon={mdiChevronLeft} backgroundColor="#202123" on:click={toPrevious} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mr-4 flex h-full flex-col place-content-center place-items-center">
|
||||
<div class="inline-block">
|
||||
{#if canGoForward}
|
||||
<CircleIconButton logo={ChevronRight} backgroundColor="#202123" on:click={toNext} />
|
||||
<CircleIconButton icon={mdiChevronRight} backgroundColor="#202123" on:click={toNext} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -260,7 +255,7 @@
|
|||
class:opacity-100={!galleryInView}
|
||||
>
|
||||
<button on:click={() => memoryGallery.scrollIntoView({ behavior: 'smooth' })}>
|
||||
<CircleIconButton logo={ChevronDown} backgroundColor="white" forceDark />
|
||||
<CircleIconButton icon={mdiChevronDown} backgroundColor="white" forceDark />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api } from '@api';
|
||||
import ArchiveArrowDownOutline from 'svelte-material-icons/ArchiveArrowDownOutline.svelte';
|
||||
import ArchiveArrowUpOutline from 'svelte-material-icons/ArchiveArrowUpOutline.svelte';
|
||||
import TimerSand from 'svelte-material-icons/TimerSand.svelte';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { OnArchive, getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { mdiArchiveArrowUpOutline, mdiArchiveArrowDownOutline, mdiTimerSand } from '@mdi/js';
|
||||
|
||||
export let onArchive: OnArchive | undefined = undefined;
|
||||
|
||||
|
@ -18,7 +16,7 @@
|
|||
export let unarchive = false;
|
||||
|
||||
$: text = unarchive ? 'Unarchive' : 'Archive';
|
||||
$: logo = unarchive ? ArchiveArrowUpOutline : ArchiveArrowDownOutline;
|
||||
$: icon = unarchive ? mdiArchiveArrowUpOutline : mdiArchiveArrowDownOutline;
|
||||
|
||||
let loading = false;
|
||||
|
||||
|
@ -62,8 +60,8 @@
|
|||
|
||||
{#if !menuItem}
|
||||
{#if loading}
|
||||
<CircleIconButton title="Loading" logo={TimerSand} />
|
||||
<CircleIconButton title="Loading" icon={mdiTimerSand} />
|
||||
{:else}
|
||||
<CircleIconButton title={text} {logo} on:click={handleArchive} />
|
||||
<CircleIconButton title={text} {icon} on:click={handleArchive} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts">
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import CreateSharedLinkModal from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte';
|
||||
import ShareVariantOutline from 'svelte-material-icons/ShareVariantOutline.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { mdiShareVariantOutline } from '@mdi/js';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
|
||||
let showModal = false;
|
||||
const dispatch = createEventDispatcher();
|
||||
|
@ -14,7 +14,7 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<CircleIconButton title="Share" logo={ShareVariantOutline} on:click={() => (showModal = true)} />
|
||||
<CircleIconButton title="Share" icon={mdiShareVariantOutline} on:click={() => (showModal = true)} />
|
||||
|
||||
{#if showModal}
|
||||
<CreateSharedLinkModal
|
||||
|
|
|
@ -7,13 +7,11 @@
|
|||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api } from '@api';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import TimerSand from 'svelte-material-icons/TimerSand.svelte';
|
||||
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { OnAssetDelete, getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { mdiTimerSand, mdiDeleteOutline } from '@mdi/js';
|
||||
|
||||
export let onAssetDelete: OnAssetDelete;
|
||||
export let menuItem = false;
|
||||
|
@ -70,9 +68,9 @@
|
|||
{#if menuItem}
|
||||
<MenuOption text={force ? 'Permanently Delete' : 'Delete'} on:click={handleTrash} />
|
||||
{:else if loading}
|
||||
<CircleIconButton title="Loading" logo={TimerSand} />
|
||||
<CircleIconButton title="Loading" icon={mdiTimerSand} />
|
||||
{:else}
|
||||
<CircleIconButton title="Delete" logo={DeleteOutline} on:click={handleTrash} />
|
||||
<CircleIconButton title="Delete" icon={mdiDeleteOutline} on:click={handleTrash} />
|
||||
{/if}
|
||||
|
||||
{#if isShowConfirmation}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts">
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { downloadArchive, downloadFile } from '$lib/utils/asset-utils';
|
||||
import CloudDownloadOutline from 'svelte-material-icons/CloudDownloadOutline.svelte';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { mdiCloudDownloadOutline } from '@mdi/js';
|
||||
|
||||
export let filename = 'immich.zip';
|
||||
export let menuItem = false;
|
||||
|
@ -26,5 +26,5 @@
|
|||
{#if menuItem}
|
||||
<MenuOption text="Download" on:click={handleDownloadFiles} />
|
||||
{:else}
|
||||
<CircleIconButton title="Download" logo={CloudDownloadOutline} on:click={handleDownloadFiles} />
|
||||
<CircleIconButton title="Download" icon={mdiCloudDownloadOutline} on:click={handleDownloadFiles} />
|
||||
{/if}
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api } from '@api';
|
||||
import HeartMinusOutline from 'svelte-material-icons/HeartMinusOutline.svelte';
|
||||
import HeartOutline from 'svelte-material-icons/HeartOutline.svelte';
|
||||
import TimerSand from 'svelte-material-icons/TimerSand.svelte';
|
||||
import { OnFavorite, getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { mdiHeartMinusOutline, mdiHeartOutline, mdiTimerSand } from '@mdi/js';
|
||||
|
||||
export let onFavorite: OnFavorite | undefined = undefined;
|
||||
|
||||
|
@ -18,7 +16,7 @@
|
|||
export let removeFavorite: boolean;
|
||||
|
||||
$: text = removeFavorite ? 'Remove from Favorites' : 'Favorite';
|
||||
$: logo = removeFavorite ? HeartMinusOutline : HeartOutline;
|
||||
$: icon = removeFavorite ? mdiHeartMinusOutline : mdiHeartOutline;
|
||||
|
||||
let loading = false;
|
||||
|
||||
|
@ -62,8 +60,8 @@
|
|||
|
||||
{#if !menuItem}
|
||||
{#if loading}
|
||||
<CircleIconButton title="Loading" logo={TimerSand} />
|
||||
<CircleIconButton title="Loading" icon={mdiTimerSand} />
|
||||
{:else}
|
||||
<CircleIconButton title={text} {logo} on:click={handleFavorite} />
|
||||
<CircleIconButton title={text} {icon} on:click={handleFavorite} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
notificationController,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { AlbumResponseDto, api } from '@api';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { mdiDeleteOutline } from '@mdi/js';
|
||||
|
||||
export let album: AlbumResponseDto;
|
||||
export let onRemove: ((assetIds: string[]) => void) | undefined = undefined;
|
||||
|
@ -53,7 +53,7 @@
|
|||
{#if menuItem}
|
||||
<MenuOption text="Remove from album" on:click={() => (isShowConfirmation = true)} />
|
||||
{:else}
|
||||
<CircleIconButton title="Remove from album" logo={DeleteOutline} on:click={() => (isShowConfirmation = true)} />
|
||||
<CircleIconButton title="Remove from album" icon={mdiDeleteOutline} on:click={() => (isShowConfirmation = true)} />
|
||||
{/if}
|
||||
|
||||
{#if isShowConfirmation}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts">
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { SharedLinkResponseDto, api } from '@api';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import ConfirmDialogue from '../../shared-components/confirm-dialogue.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { NotificationType, notificationController } from '../../shared-components/notification/notification';
|
||||
import { handleError } from '../../../utils/handle-error';
|
||||
import { mdiDeleteOutline } from '@mdi/js';
|
||||
|
||||
export let sharedLink: SharedLinkResponseDto;
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<CircleIconButton title="Remove from shared link" on:click={() => (removing = true)} logo={DeleteOutline} />
|
||||
<CircleIconButton title="Remove from shared link" on:click={() => (removing = true)} icon={mdiDeleteOutline} />
|
||||
|
||||
{#if removing}
|
||||
<ConfirmDialogue
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api } from '@api';
|
||||
import History from 'svelte-material-icons/History.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import Button from '../../elements/buttons/button.svelte';
|
||||
import { OnRestore, getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { mdiHistory } from '@mdi/js';
|
||||
|
||||
export let onRestore: OnRestore | undefined = undefined;
|
||||
|
||||
|
@ -38,6 +39,6 @@
|
|||
</script>
|
||||
|
||||
<Button disabled={loading} size="sm" color="transparent-gray" shadow={false} rounded="lg" on:click={handleRestore}>
|
||||
<History size="24" />
|
||||
<Icon path={mdiHistory} size="24" />
|
||||
<span class="ml-2">Restore</span>
|
||||
</Button>
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
import type { AssetInteractionStore } from '$lib/stores/asset-interaction.store';
|
||||
import { BucketPosition, type AssetStore } from '$lib/stores/assets.store';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import SelectAll from 'svelte-material-icons/SelectAll.svelte';
|
||||
import TimerSand from 'svelte-material-icons/TimerSand.svelte';
|
||||
import { get } from 'svelte/store';
|
||||
import { mdiTimerSand, mdiSelectAll } from '@mdi/js';
|
||||
|
||||
export let assetStore: AssetStore;
|
||||
export let assetInteractionStore: AssetInteractionStore;
|
||||
|
@ -32,8 +31,8 @@
|
|||
</script>
|
||||
|
||||
{#if selecting}
|
||||
<CircleIconButton title="Delete" logo={TimerSand} />
|
||||
<CircleIconButton title="Delete" icon={mdiTimerSand} />
|
||||
{/if}
|
||||
{#if !selecting}
|
||||
<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
|
||||
<CircleIconButton title="Select all" icon={mdiSelectAll} on:click={handleSelectAll} />
|
||||
{/if}
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
import type { AssetResponseDto } from '@api';
|
||||
import justifiedLayout from 'justified-layout';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import CheckCircle from 'svelte-material-icons/CheckCircle.svelte';
|
||||
import CircleOutline from 'svelte-material-icons/CircleOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { fly } from 'svelte/transition';
|
||||
import Thumbnail from '../assets/thumbnail/thumbnail.svelte';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import type { AssetStore } from '$lib/stores/assets.store';
|
||||
import type { AssetInteractionStore } from '$lib/stores/asset-interaction.store';
|
||||
import type { Viewport } from '$lib/stores/assets.store';
|
||||
import { mdiCheckCircle, mdiCircleOutline } from '@mdi/js';
|
||||
|
||||
export let assets: AssetResponseDto[];
|
||||
export let bucketDate: string;
|
||||
|
@ -154,9 +154,9 @@
|
|||
on:keydown={() => handleSelectGroup(groupTitle, groupAssets)}
|
||||
>
|
||||
{#if $selectedGroup.has(groupTitle)}
|
||||
<CheckCircle size="24" color="#4250af" />
|
||||
<Icon path={mdiCheckCircle} size="24" color="#4250af" />
|
||||
{:else}
|
||||
<CircleOutline size="24" color="#757575" />
|
||||
<Icon path={mdiCircleOutline} size="24" color="#757575" />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -9,10 +9,9 @@
|
|||
<script lang="ts">
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
|
||||
import type Icon from 'svelte-material-icons/AbTesting.svelte';
|
||||
import { getContextMenuPosition } from '$lib/utils/context-menu';
|
||||
|
||||
export let icon: typeof Icon;
|
||||
export let icon: string;
|
||||
export let title: string;
|
||||
|
||||
let showContextMenu = false;
|
||||
|
@ -27,7 +26,7 @@
|
|||
</script>
|
||||
|
||||
<div use:clickOutside on:outclick={() => (showContextMenu = false)}>
|
||||
<CircleIconButton {title} logo={icon} on:click={handleShowMenu} />
|
||||
<CircleIconButton {title} {icon} on:click={handleShowMenu} />
|
||||
{#if showContextMenu}
|
||||
<ContextMenu {...contextMenuPosition}>
|
||||
<div class="flex flex-col rounded-lg">
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
<script lang="ts">
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import type { AssetResponseDto } from '@api';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import ControlAppBar from '../shared-components/control-app-bar.svelte';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
|
||||
export let assets: Set<AssetResponseDto>;
|
||||
export let clearSelect: () => void;
|
||||
|
@ -28,7 +28,7 @@
|
|||
setContext({ getAssets: () => assets, clearSelect });
|
||||
</script>
|
||||
|
||||
<ControlAppBar on:close-button-click={clearSelect} backIcon={Close} tailwindClasses="bg-white shadow-md">
|
||||
<ControlAppBar on:close-button-click={clearSelect} backIcon={mdiClose} tailwindClasses="bg-white shadow-md">
|
||||
<p class="font-medium text-immich-primary dark:text-immich-dark-primary" slot="leading">
|
||||
Selected {assets.size.toLocaleString($locale)}
|
||||
</p>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { api } from '@api';
|
||||
import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
|
||||
import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { memoryStore } from '$lib/stores/memory.store';
|
||||
import { goto } from '$app/navigation';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { mdiChevronLeft, mdiChevronRight } from '@mdi/js';
|
||||
|
||||
$: shouldRender = $memoryStore?.length > 0;
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
|||
class="rounded-full border border-gray-500 bg-gray-100 p-2 text-gray-500 opacity-50 hover:opacity-100"
|
||||
on:click={scrollLeft}
|
||||
>
|
||||
<ChevronLeft size="36" /></button
|
||||
<Icon path={mdiChevronLeft} size="36" /></button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -60,7 +60,7 @@
|
|||
class="rounded-full border border-gray-500 bg-gray-100 p-2 text-gray-500 opacity-50 hover:opacity-100"
|
||||
on:click={scrollRight}
|
||||
>
|
||||
<ChevronRight size="36" /></button
|
||||
<Icon path={mdiChevronRight} size="36" /></button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -4,19 +4,16 @@
|
|||
import { downloadArchive } from '$lib/utils/asset-utils';
|
||||
import { api, AssetResponseDto, SharedLinkResponseDto } from '@api';
|
||||
import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import FileImagePlusOutline from 'svelte-material-icons/FileImagePlusOutline.svelte';
|
||||
import FolderDownloadOutline from 'svelte-material-icons/FolderDownloadOutline.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import DownloadAction from '../photos-page/actions/download-action.svelte';
|
||||
import RemoveFromSharedLink from '../photos-page/actions/remove-from-shared-link.svelte';
|
||||
import AssetSelectControlBar from '../photos-page/asset-select-control-bar.svelte';
|
||||
import ControlAppBar from '../shared-components/control-app-bar.svelte';
|
||||
import GalleryViewer from '../shared-components/gallery-viewer/gallery-viewer.svelte';
|
||||
import SelectAll from 'svelte-material-icons/SelectAll.svelte';
|
||||
import ImmichLogo from '../shared-components/immich-logo.svelte';
|
||||
import { notificationController, NotificationType } from '../shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { mdiArrowLeft, mdiFileImagePlusOutline, mdiFolderDownloadOutline, mdiSelectAll } from '@mdi/js';
|
||||
|
||||
export let sharedLink: SharedLinkResponseDto;
|
||||
export let isOwned: boolean;
|
||||
|
@ -72,7 +69,7 @@
|
|||
<section class="bg-immich-bg dark:bg-immich-dark-bg">
|
||||
{#if isMultiSelectionMode}
|
||||
<AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new Set())}>
|
||||
<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
|
||||
<CircleIconButton title="Select all" icon={mdiSelectAll} on:click={handleSelectAll} />
|
||||
{#if sharedLink?.allowDownload}
|
||||
<DownloadAction filename="immich-shared.zip" />
|
||||
{/if}
|
||||
|
@ -81,7 +78,7 @@
|
|||
{/if}
|
||||
</AssetSelectControlBar>
|
||||
{:else}
|
||||
<ControlAppBar on:close-button-click={() => goto('/photos')} backIcon={ArrowLeft} showBackButton={false}>
|
||||
<ControlAppBar on:close-button-click={() => goto('/photos')} backIcon={mdiArrowLeft} showBackButton={false}>
|
||||
<svelte:fragment slot="leading">
|
||||
<a
|
||||
data-sveltekit-preload-data="hover"
|
||||
|
@ -95,11 +92,11 @@
|
|||
|
||||
<svelte:fragment slot="trailing">
|
||||
{#if sharedLink?.allowUpload}
|
||||
<CircleIconButton title="Add Photos" on:click={() => handleUploadAssets()} logo={FileImagePlusOutline} />
|
||||
<CircleIconButton title="Add Photos" on:click={() => handleUploadAssets()} icon={mdiFileImagePlusOutline} />
|
||||
{/if}
|
||||
|
||||
{#if sharedLink?.allowDownload}
|
||||
<CircleIconButton title="Download" on:click={downloadAssets} logo={FolderDownloadOutline} />
|
||||
<CircleIconButton title="Download" on:click={downloadAssets} icon={mdiFolderDownloadOutline} />
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</ControlAppBar>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { AlbumResponseDto, api } from '@api';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import BaseModal from './base-modal.svelte';
|
||||
import AlbumListItem from '../asset-viewer/album-list-item.svelte';
|
||||
import { mdiPlus } from '@mdi/js';
|
||||
|
||||
let albums: AlbumResponseDto[] = [];
|
||||
let recentAlbums: AlbumResponseDto[] = [];
|
||||
|
@ -84,7 +85,7 @@
|
|||
class="flex w-full items-center gap-4 px-6 py-2 transition-colors hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
>
|
||||
<div class="flex h-12 w-12 items-center justify-center">
|
||||
<Plus size="30" />
|
||||
<Icon path={mdiPlus} size="30" />
|
||||
</div>
|
||||
<p class="">
|
||||
New {#if shared}Shared {/if}Album {#if search.length > 0}<b>{search}</b>{/if}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { fade } from 'svelte/transition';
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import { createEventDispatcher, onMount, onDestroy } from 'svelte';
|
||||
import { browser } from '$app/environment';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
export let zIndex = 9999;
|
||||
|
@ -46,7 +46,7 @@
|
|||
</slot>
|
||||
</div>
|
||||
|
||||
<CircleIconButton on:click={() => dispatch('close')} logo={Close} size={'20'} />
|
||||
<CircleIconButton on:click={() => dispatch('close')} icon={mdiClose} size={'20'} />
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
import { browser } from '$app/environment';
|
||||
|
||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
|
||||
export let showBackButton = true;
|
||||
export let backIcon = Close;
|
||||
export let backIcon = mdiClose;
|
||||
export let tailwindClasses = '';
|
||||
export let forceDark = false;
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
|||
{#if showBackButton}
|
||||
<CircleIconButton
|
||||
on:click={() => dispatch('close-button-click')}
|
||||
logo={backIcon}
|
||||
icon={backIcon}
|
||||
backgroundColor={'transparent'}
|
||||
hoverColor={'#e2e7e9'}
|
||||
size={'24'}
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api, copyToClipboard, SharedLinkResponseDto, SharedLinkType } from '@api';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import Link from 'svelte-material-icons/Link.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import BaseModal from '../base-modal.svelte';
|
||||
import type { ImmichDropDownOption } from '../dropdown-button.svelte';
|
||||
import DropdownButton from '../dropdown-button.svelte';
|
||||
import { notificationController, NotificationType } from '../notification/notification';
|
||||
import { mdiLink } from '@mdi/js';
|
||||
|
||||
export let albumId: string | undefined = undefined;
|
||||
export let assetIds: string[] = [];
|
||||
|
@ -140,7 +141,7 @@
|
|||
<BaseModal on:close={() => dispatch('close')} on:escape={() => dispatch('escape')}>
|
||||
<svelte:fragment slot="title">
|
||||
<span class="flex place-items-center gap-2">
|
||||
<Link size={24} />
|
||||
<Icon path={mdiLink} size={24} />
|
||||
{#if editingLink}
|
||||
<p class="font-medium text-immich-fg dark:text-immich-dark-fg">Edit link</p>
|
||||
{:else}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
import { AppRoute } from '$lib/constants';
|
||||
import type { UserResponseDto } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import Cog from 'svelte-material-icons/Cog.svelte';
|
||||
import Logout from 'svelte-material-icons/Logout.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import UserAvatar from '../user-avatar.svelte';
|
||||
import { mdiCog, mdiLogout } from '@mdi/js';
|
||||
|
||||
export let user: UserResponseDto;
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
<a href={AppRoute.USER_SETTINGS} on:click={() => dispatch('close')}>
|
||||
<Button color="dark-gray" size="sm" shadow={false} border>
|
||||
<div class="flex place-content-center place-items-center gap-2 px-2">
|
||||
<Cog size="18" />
|
||||
<Icon path={mdiCog} size="18" />
|
||||
Account Settings
|
||||
</div>
|
||||
</Button>
|
||||
|
@ -47,7 +47,7 @@
|
|||
class="flex w-full place-content-center place-items-center gap-2 py-3 font-medium text-gray-500 hover:bg-immich-primary/10 dark:text-gray-300"
|
||||
on:click={() => dispatch('logout')}
|
||||
>
|
||||
<Logout size={24} />
|
||||
<Icon path={mdiLogout} size={24} />
|
||||
Sign Out</button
|
||||
>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade, fly } from 'svelte/transition';
|
||||
import TrayArrowUp from 'svelte-material-icons/TrayArrowUp.svelte';
|
||||
import { api, UserResponseDto } from '@api';
|
||||
import ThemeButton from '../theme-button.svelte';
|
||||
import { AppRoute } from '../../../constants';
|
||||
|
@ -12,11 +11,11 @@
|
|||
import ImmichLogo from '../immich-logo.svelte';
|
||||
import SearchBar from '../search-bar/search-bar.svelte';
|
||||
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
|
||||
import Magnify from 'svelte-material-icons/Magnify.svelte';
|
||||
import IconButton from '$lib/components/elements/buttons/icon-button.svelte';
|
||||
import Cog from 'svelte-material-icons/Cog.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import UserAvatar from '../user-avatar.svelte';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { mdiMagnify, mdiTrayArrowUp, mdiCog } from '@mdi/js';
|
||||
export let user: UserResponseDto;
|
||||
export let showUploadButton = true;
|
||||
|
||||
|
@ -56,7 +55,7 @@
|
|||
<a href={AppRoute.SEARCH} id="search-button" class="pl-4 sm:hidden">
|
||||
<IconButton title="Search">
|
||||
<div class="flex gap-2">
|
||||
<Magnify size="1.5em" />
|
||||
<Icon path={mdiMagnify} size="1.5em" />
|
||||
</div>
|
||||
</IconButton>
|
||||
</a>
|
||||
|
@ -68,7 +67,7 @@
|
|||
<div in:fly={{ x: 50, duration: 250 }}>
|
||||
<LinkButton on:click={() => dispatch('uploadClicked')}>
|
||||
<div class="flex gap-2">
|
||||
<TrayArrowUp size="1.5em" />
|
||||
<Icon path={mdiTrayArrowUp} size="1.5em" />
|
||||
<span class="hidden md:block">Upload</span>
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
@ -95,7 +94,8 @@
|
|||
</span>
|
||||
</div>
|
||||
<div class="block sm:hidden" aria-hidden="true">
|
||||
<Cog
|
||||
<Icon
|
||||
path={mdiCog}
|
||||
size="1.5em"
|
||||
class="dark:text-immich-dark-fg {$page.url.pathname.includes('/admin')
|
||||
? 'text-immich-primary dark:text-immich-dark-primary'
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
<script lang="ts">
|
||||
import { fade } from 'svelte/transition';
|
||||
import CloseCircleOutline from 'svelte-material-icons/CloseCircleOutline.svelte';
|
||||
import InformationOutline from 'svelte-material-icons/InformationOutline.svelte';
|
||||
import WindowClose from 'svelte-material-icons/WindowClose.svelte';
|
||||
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import {
|
||||
ImmichNotification,
|
||||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { onMount } from 'svelte';
|
||||
import { mdiCloseCircleOutline, mdiInformationOutline, mdiWindowClose } from '@mdi/js';
|
||||
|
||||
export let notificationInfo: ImmichNotification;
|
||||
|
||||
|
@ -17,7 +15,7 @@
|
|||
let errorPrimaryColor = '#E64132';
|
||||
let warningPrimaryColor = '#D08613';
|
||||
|
||||
$: icon = notificationInfo.type === NotificationType.Error ? CloseCircleOutline : InformationOutline;
|
||||
$: icon = notificationInfo.type === NotificationType.Error ? mdiCloseCircleOutline : mdiInformationOutline;
|
||||
|
||||
$: backgroundColor = () => {
|
||||
if (notificationInfo.type === NotificationType.Info) {
|
||||
|
@ -93,13 +91,13 @@
|
|||
>
|
||||
<div class="flex justify-between">
|
||||
<div class="flex place-items-center gap-2">
|
||||
<svelte:component this={icon} color={primaryColor()} size="20" />
|
||||
<Icon path={icon} color={primaryColor()} size="20" />
|
||||
<h2 style:color={primaryColor()} class="font-medium" data-testid="title">
|
||||
{notificationInfo.type.toString()}
|
||||
</h2>
|
||||
</div>
|
||||
<button on:click|stopPropagation={discard}>
|
||||
<svelte:component this={WindowClose} size="20" />
|
||||
<Icon path={mdiWindowClose} size="20" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import Magnify from 'svelte-material-icons/Magnify.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { isSearchEnabled, preventRaceConditionSearchBar, savedSearchTerms } from '$lib/stores/search.store';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { mdiClose, mdiMagnify } from '@mdi/js';
|
||||
export let value = '';
|
||||
export let grayTheme: boolean;
|
||||
|
||||
|
@ -82,7 +82,7 @@
|
|||
<div class="absolute inset-y-0 left-0 flex items-center pl-6">
|
||||
<div class="dark:text-immich-dark-fg/75">
|
||||
<button class="flex items-center">
|
||||
<Magnify size="1.5em" />
|
||||
<Icon path={mdiMagnify} size="1.5em" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -108,7 +108,7 @@
|
|||
type="reset"
|
||||
class="rounded-full p-2 hover:bg-immich-primary/5 active:bg-immich-primary/10 dark:text-immich-dark-fg/75 dark:hover:bg-immich-dark-primary/25 dark:active:bg-immich-dark-primary/[.35]"
|
||||
>
|
||||
<Close size="1.5em" />
|
||||
<Icon path={mdiClose} size="1.5em" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -153,11 +153,13 @@
|
|||
onSearch();
|
||||
}}
|
||||
>
|
||||
<Magnify size="1.5em" />
|
||||
<Icon path={mdiMagnify} size="1.5em" />
|
||||
{savedSearchTerm}
|
||||
</button>
|
||||
<div class="absolute right-5 top-0 items-center justify-center py-3">
|
||||
<button type="button" on:click={() => clearSearchTerm(savedSearchTerm)}><Close size="18" /></button>
|
||||
<button type="button" on:click={() => clearSearchTerm(savedSearchTerm)}
|
||||
><Icon path={mdiClose} size="18" /></button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import FullScreenModal from './full-screen-modal.svelte';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
|
||||
const shortcuts = {
|
||||
general: [
|
||||
|
@ -30,7 +30,7 @@
|
|||
<div class="relative px-4 pt-4">
|
||||
<h1 class="px-4 py-4 font-medium text-immich-primary dark:text-immich-dark-primary">Keyboard Shortcuts</h1>
|
||||
<div class="absolute inset-y-0 right-0 px-4 py-4">
|
||||
<CircleIconButton logo={Close} on:click={() => dispatch('close')} />
|
||||
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,32 +4,28 @@
|
|||
import SideBarSection from '$lib/components/shared-components/side-bar/side-bar-section.svelte';
|
||||
import StatusBox from '$lib/components/shared-components/status-box.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import AccountMultipleOutline from 'svelte-material-icons/AccountMultipleOutline.svelte';
|
||||
import Cog from 'svelte-material-icons/Cog.svelte';
|
||||
import Server from 'svelte-material-icons/Server.svelte';
|
||||
import Tools from 'svelte-material-icons/Tools.svelte';
|
||||
import Sync from 'svelte-material-icons/Sync.svelte';
|
||||
import { mdiAccountMultipleOutline, mdiCog, mdiServer, mdiSync, mdiTools } from '@mdi/js';
|
||||
</script>
|
||||
|
||||
<SideBarSection>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.ADMIN_USER_MANAGEMENT} draggable="false">
|
||||
<SideBarButton
|
||||
title="Users"
|
||||
logo={AccountMultipleOutline}
|
||||
icon={mdiAccountMultipleOutline}
|
||||
isSelected={$page.route.id === AppRoute.ADMIN_USER_MANAGEMENT}
|
||||
/>
|
||||
</a>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.ADMIN_JOBS} draggable="false">
|
||||
<SideBarButton title="Jobs" logo={Sync} isSelected={$page.route.id === AppRoute.ADMIN_JOBS} />
|
||||
<SideBarButton title="Jobs" icon={mdiSync} isSelected={$page.route.id === AppRoute.ADMIN_JOBS} />
|
||||
</a>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.ADMIN_SETTINGS} draggable="false">
|
||||
<SideBarButton title="Settings" logo={Cog} isSelected={$page.route.id === AppRoute.ADMIN_SETTINGS} />
|
||||
<SideBarButton title="Settings" icon={mdiCog} isSelected={$page.route.id === AppRoute.ADMIN_SETTINGS} />
|
||||
</a>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.ADMIN_STATS} draggable="false">
|
||||
<SideBarButton title="Server Stats" logo={Server} isSelected={$page.route.id === AppRoute.ADMIN_STATS} />
|
||||
<SideBarButton title="Server Stats" icon={mdiServer} isSelected={$page.route.id === AppRoute.ADMIN_STATS} />
|
||||
</a>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.ADMIN_REPAIR} draggable="false">
|
||||
<SideBarButton title="Repair" logo={Tools} isSelected={$page.route.id === AppRoute.ADMIN_REPAIR} />
|
||||
<SideBarButton title="Repair" icon={mdiTools} isSelected={$page.route.id === AppRoute.ADMIN_REPAIR} />
|
||||
</a>
|
||||
<div class="mb-6 mt-auto">
|
||||
<StatusBox />
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts">
|
||||
import type Icon from 'svelte-material-icons/AbTesting.svelte';
|
||||
import InformationOutline from 'svelte-material-icons/InformationOutline.svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiInformationOutline } from '@mdi/js';
|
||||
|
||||
export let title: string;
|
||||
export let logo: typeof Icon;
|
||||
export let icon: string;
|
||||
export let isSelected: boolean;
|
||||
export let flippedLogo = false;
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
|||
"
|
||||
>
|
||||
<div class="flex w-full place-items-center gap-4 overflow-hidden truncate">
|
||||
<svelte:component this={logo} size="1.5em" class="shrink-0 {flippedLogo ? '-scale-x-100' : ''}" />
|
||||
<Icon path={icon} size="1.5em" class="shrink-0" flipped={flippedLogo} />
|
||||
<p class="text-sm font-medium">{title}</p>
|
||||
</div>
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
|||
on:mouseleave={() => (showMoreInformation = false)}
|
||||
>
|
||||
<div class="p-1 text-gray-600 hover:cursor-help dark:text-gray-400">
|
||||
<InformationOutline />
|
||||
<Icon path={mdiInformationOutline} />
|
||||
</div>
|
||||
|
||||
{#if showMoreInformation}
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { locale, sidebarSettings } from '$lib/stores/preferences.store';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { AssetApiGetAssetStatsRequest, api } from '@api';
|
||||
import AccountMultipleOutline from 'svelte-material-icons/AccountMultipleOutline.svelte';
|
||||
import AccountMultiple from 'svelte-material-icons/AccountMultiple.svelte';
|
||||
import ImageAlbum from 'svelte-material-icons/ImageAlbum.svelte';
|
||||
import ImageMultipleOutline from 'svelte-material-icons/ImageMultipleOutline.svelte';
|
||||
import ImageMultiple from 'svelte-material-icons/ImageMultiple.svelte';
|
||||
import ArchiveArrowDownOutline from 'svelte-material-icons/ArchiveArrowDownOutline.svelte';
|
||||
import Magnify from 'svelte-material-icons/Magnify.svelte';
|
||||
import Map from 'svelte-material-icons/Map.svelte';
|
||||
import Account from 'svelte-material-icons/Account.svelte';
|
||||
import TrashCanOutline from 'svelte-material-icons/TrashCanOutline.svelte';
|
||||
import HeartMultipleOutline from 'svelte-material-icons/HeartMultipleOutline.svelte';
|
||||
import HeartMultiple from 'svelte-material-icons/HeartMultiple.svelte';
|
||||
import {
|
||||
mdiAccount,
|
||||
mdiAccountMultiple,
|
||||
mdiAccountMultipleOutline,
|
||||
mdiArchiveArrowDownOutline,
|
||||
mdiHeartMultiple,
|
||||
mdiHeartMultipleOutline,
|
||||
mdiImageAlbum,
|
||||
mdiImageMultiple,
|
||||
mdiImageMultipleOutline,
|
||||
mdiMagnify,
|
||||
mdiMap,
|
||||
mdiTrashCanOutline,
|
||||
} from '@mdi/js';
|
||||
import { AppRoute } from '../../../constants';
|
||||
import LoadingSpinner from '../loading-spinner.svelte';
|
||||
import StatusBox from '../status-box.svelte';
|
||||
import SideBarButton from './side-bar-button.svelte';
|
||||
import { locale, sidebarSettings } from '$lib/stores/preferences.store';
|
||||
import SideBarSection from './side-bar-section.svelte';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
|
||||
const getStats = async (dto: AssetApiGetAssetStatsRequest) => {
|
||||
const { data: stats } = await api.assetApi.getAssetStats(dto);
|
||||
|
@ -45,7 +47,7 @@
|
|||
<a data-sveltekit-preload-data="hover" data-sveltekit-noscroll href={AppRoute.PHOTOS} draggable="false">
|
||||
<SideBarButton
|
||||
title="Photos"
|
||||
logo={isPhotosSelected ? ImageMultiple : ImageMultipleOutline}
|
||||
icon={isPhotosSelected ? mdiImageMultiple : mdiImageMultipleOutline}
|
||||
isSelected={isPhotosSelected}
|
||||
>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
|
@ -62,23 +64,23 @@
|
|||
</a>
|
||||
{#if $featureFlags.search}
|
||||
<a data-sveltekit-preload-data="hover" data-sveltekit-noscroll href={AppRoute.EXPLORE} draggable="false">
|
||||
<SideBarButton title="Explore" logo={Magnify} isSelected={$page.route.id === '/(user)/explore'} />
|
||||
<SideBarButton title="Explore" icon={mdiMagnify} isSelected={$page.route.id === '/(user)/explore'} />
|
||||
</a>
|
||||
{/if}
|
||||
{#if $featureFlags.map}
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.MAP} draggable="false">
|
||||
<SideBarButton title="Map" logo={Map} isSelected={$page.route.id === '/(user)/map'} />
|
||||
<SideBarButton title="Map" icon={mdiMap} isSelected={$page.route.id === '/(user)/map'} />
|
||||
</a>
|
||||
{/if}
|
||||
{#if $sidebarSettings.people}
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.PEOPLE} draggable="false">
|
||||
<SideBarButton title="People" logo={Account} isSelected={$page.route.id === '/(user)/people'} />
|
||||
<SideBarButton title="People" icon={mdiAccount} isSelected={$page.route.id === '/(user)/people'} />
|
||||
</a>
|
||||
{/if}
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.SHARING} draggable="false">
|
||||
<SideBarButton
|
||||
title="Sharing"
|
||||
logo={isSharingSelected ? AccountMultiple : AccountMultipleOutline}
|
||||
icon={isSharingSelected ? mdiAccountMultiple : mdiAccountMultipleOutline}
|
||||
isSelected={isSharingSelected}
|
||||
>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
|
@ -100,7 +102,7 @@
|
|||
<a data-sveltekit-preload-data="hover" href={AppRoute.FAVORITES} draggable="false">
|
||||
<SideBarButton
|
||||
title="Favorites"
|
||||
logo={isFavoritesSelected ? HeartMultiple : HeartMultipleOutline}
|
||||
icon={isFavoritesSelected ? mdiHeartMultiple : mdiHeartMultipleOutline}
|
||||
isSelected={isFavoritesSelected}
|
||||
>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
|
@ -116,7 +118,12 @@
|
|||
</SideBarButton>
|
||||
</a>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.ALBUMS} draggable="false">
|
||||
<SideBarButton title="Albums" logo={ImageAlbum} flippedLogo={true} isSelected={$page.route.id === '/(user)/albums'}>
|
||||
<SideBarButton
|
||||
title="Albums"
|
||||
icon={mdiImageAlbum}
|
||||
flippedLogo={true}
|
||||
isSelected={$page.route.id === '/(user)/albums'}
|
||||
>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
{#await getAlbumCount()}
|
||||
<LoadingSpinner />
|
||||
|
@ -129,7 +136,7 @@
|
|||
</SideBarButton>
|
||||
</a>
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.ARCHIVE} draggable="false">
|
||||
<SideBarButton title="Archive" logo={ArchiveArrowDownOutline} isSelected={$page.route.id === '/(user)/archive'}>
|
||||
<SideBarButton title="Archive" icon={mdiArchiveArrowDownOutline} isSelected={$page.route.id === '/(user)/archive'}>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
{#await getStats({ isArchived: true })}
|
||||
<LoadingSpinner />
|
||||
|
@ -145,7 +152,7 @@
|
|||
|
||||
{#if $featureFlags.trash}
|
||||
<a data-sveltekit-preload-data="hover" href={AppRoute.TRASH} draggable="false">
|
||||
<SideBarButton title="Trash" logo={TrashCanOutline} isSelected={isTrashSelected}>
|
||||
<SideBarButton title="Trash" icon={mdiTrashCanOutline} isSelected={isTrashSelected}>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
{#await getStats({ isTrashed: true })}
|
||||
<LoadingSpinner />
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
import { websocketStore } from '$lib/stores/websocket';
|
||||
import { ServerInfoResponseDto, api } from '@api';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import Cloud from 'svelte-material-icons/Cloud.svelte';
|
||||
import Dns from 'svelte-material-icons/Dns.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { asByteUnitString } from '../../utils/byte-units';
|
||||
import LoadingSpinner from './loading-spinner.svelte';
|
||||
import { mdiCloud, mdiDns } from '@mdi/js';
|
||||
|
||||
const { serverVersion, connected } = websocketStore;
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
<div class="dark:text-immich-dark-fg">
|
||||
<div class="storage-status grid grid-cols-[64px_auto]">
|
||||
<div class="pb-[2.15rem] pl-5 pr-6 text-immich-primary dark:text-immich-dark-primary group-hover:sm:pb-0 md:pb-0">
|
||||
<Cloud size={'24'} />
|
||||
<Icon path={mdiCloud} size={'24'} />
|
||||
</div>
|
||||
<div class="hidden group-hover:sm:block md:block">
|
||||
<p class="text-sm font-medium text-immich-primary dark:text-immich-dark-primary">Storage</p>
|
||||
|
@ -68,7 +68,7 @@
|
|||
</div>
|
||||
<div class="server-status grid grid-cols-[64px_auto]">
|
||||
<div class="pb-11 pl-5 pr-6 text-immich-primary dark:text-immich-dark-primary group-hover:sm:pb-0 md:pb-0">
|
||||
<Dns size={'24'} />
|
||||
<Icon path={mdiDns} size={'24'} />
|
||||
</div>
|
||||
<div class="hidden text-xs group-hover:sm:block md:block">
|
||||
<p class="text-sm font-medium text-immich-primary dark:text-immich-dark-primary">Server</p>
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
import ImmichLogo from './immich-logo.svelte';
|
||||
import { getFilenameExtension } from '$lib/utils/asset-utils';
|
||||
import { uploadAssetsStore } from '$lib/stores/upload';
|
||||
import Cancel from 'svelte-material-icons/Cancel.svelte';
|
||||
import Refresh from 'svelte-material-icons/Refresh.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { fileUploadHandler } from '$lib/utils/file-uploader';
|
||||
import { mdiRefresh, mdiCancel } from '@mdi/js';
|
||||
|
||||
export let uploadAsset: UploadAsset;
|
||||
|
||||
|
@ -84,14 +84,14 @@
|
|||
title="Retry upload"
|
||||
class="flex h-full w-full place-content-center place-items-center text-sm"
|
||||
>
|
||||
<span class="text-immich-dark-gray dark:text-immich-dark-fg"><Refresh size="20" /></span>
|
||||
<span class="text-immich-dark-gray dark:text-immich-dark-fg"><Icon path={mdiRefresh} size="20" /></span>
|
||||
</button>
|
||||
<button
|
||||
on:click={() => uploadAssetsStore.removeUploadAsset(uploadAsset.id)}
|
||||
title="Dismiss error"
|
||||
class="flex h-full w-full place-content-center place-items-center text-sm"
|
||||
>
|
||||
<span class="text-immich-error"><Cancel size="20" /></span>
|
||||
<span class="text-immich-error"><Icon path={mdiCancel} size="20" /></span>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -2,14 +2,12 @@
|
|||
import { quartInOut } from 'svelte/easing';
|
||||
import { fade, scale } from 'svelte/transition';
|
||||
import { uploadAssetsStore } from '$lib/stores/upload';
|
||||
import CloudUploadOutline from 'svelte-material-icons/CloudUploadOutline.svelte';
|
||||
import WindowMinimize from 'svelte-material-icons/WindowMinimize.svelte';
|
||||
import Cancel from 'svelte-material-icons/Cancel.svelte';
|
||||
import Cog from 'svelte-material-icons/Cog.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { notificationController, NotificationType } from './notification/notification';
|
||||
import UploadAssetPreview from './upload-asset-preview.svelte';
|
||||
import { uploadExecutionQueue } from '$lib/utils/file-uploader';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { mdiCog, mdiWindowMinimize, mdiCancel, mdiCloudUploadOutline } from '@mdi/js';
|
||||
|
||||
let showDetail = false;
|
||||
let showOptions = false;
|
||||
|
@ -75,14 +73,14 @@
|
|||
<div class="flex flex-row">
|
||||
<CircleIconButton
|
||||
title="Toggle settings"
|
||||
logo={Cog}
|
||||
icon={mdiCog}
|
||||
size="14"
|
||||
padding="1"
|
||||
on:click={() => (showOptions = !showOptions)}
|
||||
/>
|
||||
<CircleIconButton
|
||||
title="Minimize"
|
||||
logo={WindowMinimize}
|
||||
icon={mdiWindowMinimize}
|
||||
size="14"
|
||||
padding="1"
|
||||
on:click={() => (showDetail = false)}
|
||||
|
@ -91,7 +89,7 @@
|
|||
{#if $hasError}
|
||||
<CircleIconButton
|
||||
title="Dismiss all errors"
|
||||
logo={Cancel}
|
||||
icon={mdiCancel}
|
||||
size="14"
|
||||
padding="1"
|
||||
on:click={() => uploadAssetsStore.dismissErrors()}
|
||||
|
@ -148,7 +146,7 @@
|
|||
class="flex h-16 w-16 place-content-center place-items-center rounded-full bg-gray-200 p-5 text-sm text-immich-primary shadow-lg dark:bg-gray-600 dark:text-immich-gray"
|
||||
>
|
||||
<div class="animate-pulse">
|
||||
<CloudUploadOutline size="30" />
|
||||
<Icon path={mdiCloudUploadOutline} size="30" />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { api, AssetResponseDto, SharedLinkResponseDto, SharedLinkType, ThumbnailFormat } from '@api';
|
||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||
import OpenInNew from 'svelte-material-icons/OpenInNew.svelte';
|
||||
import Delete from 'svelte-material-icons/TrashCanOutline.svelte';
|
||||
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
|
||||
import CircleEditOutline from 'svelte-material-icons/CircleEditOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import * as luxon from 'luxon';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { mdiCircleEditOutline, mdiContentCopy, mdiDelete, mdiOpenInNew } from '@mdi/js';
|
||||
|
||||
export let link: SharedLinkResponseDto;
|
||||
|
||||
|
@ -110,7 +108,7 @@
|
|||
on:click={() => goto(`/share/${link.key}`)}
|
||||
on:keydown={() => goto(`/share/${link.key}`)}
|
||||
>
|
||||
<OpenInNew />
|
||||
<Icon path={mdiOpenInNew} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -148,9 +146,9 @@
|
|||
|
||||
<div class="flex flex-auto flex-col place-content-center place-items-end text-right">
|
||||
<div class="flex">
|
||||
<CircleIconButton logo={Delete} on:click={() => dispatch('delete')} />
|
||||
<CircleIconButton logo={CircleEditOutline} on:click={() => dispatch('edit')} />
|
||||
<CircleIconButton logo={ContentCopy} on:click={() => dispatch('copy')} />
|
||||
<CircleIconButton icon={mdiDelete} on:click={() => dispatch('delete')} />
|
||||
<CircleIconButton icon={mdiCircleEditOutline} on:click={() => dispatch('edit')} />
|
||||
<CircleIconButton icon={mdiContentCopy} on:click={() => dispatch('copy')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,14 +3,17 @@
|
|||
import type { AuthDeviceResponseDto } from '@api';
|
||||
import { DateTime, ToRelativeCalendarOptions } from 'luxon';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import Android from 'svelte-material-icons/Android.svelte';
|
||||
import Apple from 'svelte-material-icons/Apple.svelte';
|
||||
import AppleSafari from 'svelte-material-icons/AppleSafari.svelte';
|
||||
import GoogleChrome from 'svelte-material-icons/GoogleChrome.svelte';
|
||||
import Help from 'svelte-material-icons/Help.svelte';
|
||||
import Linux from 'svelte-material-icons/Linux.svelte';
|
||||
import MicrosoftWindows from 'svelte-material-icons/MicrosoftWindows.svelte';
|
||||
import TrashCanOutline from 'svelte-material-icons/TrashCanOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import {
|
||||
mdiAndroid,
|
||||
mdiApple,
|
||||
mdiAppleSafari,
|
||||
mdiMicrosoftWindows,
|
||||
mdiLinux,
|
||||
mdiGoogleChrome,
|
||||
mdiTrashCanOutline,
|
||||
mdiHelp,
|
||||
} from '@mdi/js';
|
||||
|
||||
export let device: AuthDeviceResponseDto;
|
||||
|
||||
|
@ -26,19 +29,19 @@
|
|||
<!-- TODO: Device Image -->
|
||||
<div class="hidden items-center justify-center pr-2 text-immich-primary dark:text-immich-dark-primary sm:flex">
|
||||
{#if device.deviceOS === 'Android'}
|
||||
<Android size="40" />
|
||||
<Icon path={mdiAndroid} size="40" />
|
||||
{:else if device.deviceOS === 'iOS' || device.deviceOS === 'Mac OS'}
|
||||
<Apple size="40" />
|
||||
<Icon path={mdiApple} size="40" />
|
||||
{:else if device.deviceOS.indexOf('Safari') !== -1}
|
||||
<AppleSafari size="40" />
|
||||
<Icon path={mdiAppleSafari} size="40" />
|
||||
{:else if device.deviceOS.indexOf('Windows') !== -1}
|
||||
<MicrosoftWindows size="40" />
|
||||
<Icon path={mdiMicrosoftWindows} size="40" />
|
||||
{:else if device.deviceOS === 'Linux'}
|
||||
<Linux size="40" />
|
||||
<Icon path={mdiLinux} size="40" />
|
||||
{:else if device.deviceOS === 'Chromium OS' || device.deviceType === 'Chrome' || device.deviceType === 'Chromium'}
|
||||
<GoogleChrome size="40" />
|
||||
<Icon path={mdiGoogleChrome} size="40" />
|
||||
{:else}
|
||||
<Help size="40" />
|
||||
<Icon path={mdiHelp} size="40" />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex grow flex-row justify-between gap-1 pl-4 sm:pl-0">
|
||||
|
@ -62,7 +65,7 @@
|
|||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
title="Log out"
|
||||
>
|
||||
<TrashCanOutline size="16" />
|
||||
<Icon path={mdiTrashCanOutline} size="16" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
import ConfirmDialogue from '../shared-components/confirm-dialogue.svelte';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { fade } from 'svelte/transition';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Database from 'svelte-material-icons/Database.svelte';
|
||||
import Upload from 'svelte-material-icons/Upload.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import Pulse from 'svelte-loading-spinners/Pulse.svelte';
|
||||
import { slide } from 'svelte/transition';
|
||||
import LibraryImportPathsForm from '../forms/library-import-paths-form.svelte';
|
||||
|
@ -19,6 +17,7 @@
|
|||
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
|
||||
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
|
||||
import { getContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import { mdiDatabase, mdiDotsVertical, mdiUpload } from '@mdi/js';
|
||||
|
||||
let libraries: LibraryResponseDto[] = [];
|
||||
|
||||
|
@ -317,9 +316,9 @@
|
|||
>
|
||||
<td class="w-1/6 px-10 text-sm">
|
||||
{#if library.type === LibraryType.External}
|
||||
<Database size="40" title="External library (created on {library.createdAt})" />
|
||||
<Icon path={mdiDatabase} size="40" title="External library (created on {library.createdAt})" />
|
||||
{:else if library.type === LibraryType.Upload}
|
||||
<Upload size="40" title="Upload library (created on {library.createdAt})" />
|
||||
<Icon path={mdiUpload} size="40" title="Upload library (created on {library.createdAt})" />
|
||||
{/if}</td
|
||||
>
|
||||
|
||||
|
@ -340,7 +339,7 @@
|
|||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
on:click|stopPropagation|preventDefault={(e) => showMenu(e, library, index)}
|
||||
>
|
||||
<DotsVertical size="16" />
|
||||
<Icon path={mdiDotsVertical} size="16" />
|
||||
</button>
|
||||
|
||||
{#if showContextMenu}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { UserResponseDto, api } from '@api';
|
||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import PartnerSelectionModal from './partner-selection-modal.svelte';
|
||||
import { handleError } from '../../utils/handle-error';
|
||||
import ConfirmDialogue from '../shared-components/confirm-dialogue.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
|
||||
export let user: UserResponseDto;
|
||||
|
||||
|
@ -64,7 +64,7 @@
|
|||
</div>
|
||||
<CircleIconButton
|
||||
on:click={() => (removePartner = partner)}
|
||||
logo={Close}
|
||||
icon={mdiClose}
|
||||
size={'16'}
|
||||
title="Remove partner"
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { api, APIKeyResponseDto } from '@api';
|
||||
import PencilOutline from 'svelte-material-icons/PencilOutline.svelte';
|
||||
import TrashCanOutline from 'svelte-material-icons/TrashCanOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { handleError } from '../../utils/handle-error';
|
||||
import APIKeyForm from '../forms/api-key-form.svelte';
|
||||
|
@ -10,6 +9,7 @@
|
|||
import { notificationController, NotificationType } from '../shared-components/notification/notification';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
import { mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
|
||||
|
||||
export let keys: APIKeyResponseDto[];
|
||||
|
||||
|
@ -143,13 +143,13 @@
|
|||
on:click={() => (editKey = key)}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<PencilOutline size="16" />
|
||||
<Icon path={mdiPencilOutline} size="16" />
|
||||
</button>
|
||||
<button
|
||||
on:click={() => (deleteKey = key)}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<TrashCanOutline size="16" />
|
||||
<Icon path={mdiTrashCanOutline} size="16" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -16,11 +16,7 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import FormatListBulletedSquare from 'svelte-material-icons/FormatListBulletedSquare.svelte';
|
||||
import ViewGridOutline from 'svelte-material-icons/ViewGridOutline.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import PlusBoxOutline from 'svelte-material-icons/PlusBoxOutline.svelte';
|
||||
import { useAlbums } from './albums.bloc';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
|
@ -37,13 +33,20 @@
|
|||
} from '$lib/components/shared-components/notification/notification';
|
||||
import type { AlbumResponseDto } from '@api';
|
||||
import TableHeader from '$lib/components/elements/table-header.svelte';
|
||||
import ArrowDownThin from 'svelte-material-icons/ArrowDownThin.svelte';
|
||||
import ArrowUpThin from 'svelte-material-icons/ArrowUpThin.svelte';
|
||||
import PencilOutline from 'svelte-material-icons/PencilOutline.svelte';
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
import EditAlbumForm from '$lib/components/forms/edit-album-form.svelte';
|
||||
import TrashCanOutline from 'svelte-material-icons/TrashCanOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { orderBy } from 'lodash-es';
|
||||
import {
|
||||
mdiPlusBoxOutline,
|
||||
mdiArrowDownThin,
|
||||
mdiArrowUpThin,
|
||||
mdiFormatListBulletedSquare,
|
||||
mdiPencilOutline,
|
||||
mdiTrashCanOutline,
|
||||
mdiViewGridOutline,
|
||||
mdiDeleteOutline,
|
||||
} from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
let shouldShowEditUserForm = false;
|
||||
|
@ -210,7 +213,7 @@
|
|||
<div class="flex place-items-center gap-2" slot="buttons">
|
||||
<LinkButton on:click={handleCreateAlbum}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<PlusBoxOutline size="18" />
|
||||
<Icon path={mdiPlusBoxOutline} size="18" />
|
||||
Create album
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
@ -220,7 +223,7 @@
|
|||
render={(option) => {
|
||||
return {
|
||||
title: option.sortTitle,
|
||||
icon: option.sortDesc ? ArrowDownThin : ArrowUpThin,
|
||||
icon: option.sortDesc ? mdiArrowDownThin : mdiArrowUpThin,
|
||||
};
|
||||
}}
|
||||
on:select={(event) => {
|
||||
|
@ -236,10 +239,10 @@
|
|||
<LinkButton on:click={() => handleChangeListMode()}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
{#if $albumViewSettings.view === AlbumViewMode.List}
|
||||
<ViewGridOutline size="18" />
|
||||
<Icon path={mdiViewGridOutline} size="18" />
|
||||
<p class="hidden sm:block">Cover</p>
|
||||
{:else}
|
||||
<FormatListBulletedSquare size="18" />
|
||||
<Icon path={mdiFormatListBulletedSquare} size="18" />
|
||||
<p class="hidden sm:block">List</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -293,13 +296,13 @@
|
|||
on:click|stopPropagation={() => handleEdit(album)}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<PencilOutline size="16" />
|
||||
<Icon path={mdiPencilOutline} size="16" />
|
||||
</button>
|
||||
<button
|
||||
on:click|stopPropagation={() => chooseAlbumToDelete(album)}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<TrashCanOutline size="16" />
|
||||
<Icon path={mdiTrashCanOutline} size="16" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -323,7 +326,7 @@
|
|||
<ContextMenu {...$contextMenuPosition} on:outclick={closeAlbumContextMenu} on:escape={closeAlbumContextMenu}>
|
||||
<MenuOption on:click={() => setAlbumToDelete()}>
|
||||
<span class="flex place-content-center place-items-center gap-2">
|
||||
<DeleteOutline size="18" />
|
||||
<Icon path={mdiDeleteOutline} size="18" />
|
||||
<p>Delete album</p>
|
||||
</span>
|
||||
</MenuOption>
|
||||
|
|
|
@ -35,17 +35,20 @@
|
|||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { TimeBucketSize, UserResponseDto, api } from '@api';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import FileImagePlusOutline from 'svelte-material-icons/FileImagePlusOutline.svelte';
|
||||
import FolderDownloadOutline from 'svelte-material-icons/FolderDownloadOutline.svelte';
|
||||
import Link from 'svelte-material-icons/Link.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import ShareVariantOutline from 'svelte-material-icons/ShareVariantOutline.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { getContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import {
|
||||
mdiPlus,
|
||||
mdiDotsVertical,
|
||||
mdiArrowLeft,
|
||||
mdiFileImagePlusOutline,
|
||||
mdiShareVariantOutline,
|
||||
mdiDeleteOutline,
|
||||
mdiFolderDownloadOutline,
|
||||
mdiLink,
|
||||
} from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -313,11 +316,11 @@
|
|||
<AssetSelectControlBar assets={$selectedAssets} clearSelect={() => assetInteractionStore.clearMultiselect()}>
|
||||
<CreateSharedLink />
|
||||
<SelectAllAssets {assetStore} {assetInteractionStore} />
|
||||
<AssetSelectContextMenu icon={Plus} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
<AddToAlbum shared />
|
||||
</AssetSelectContextMenu>
|
||||
<AssetSelectContextMenu icon={DotsVertical} title="Menu">
|
||||
<AssetSelectContextMenu icon={mdiDotsVertical} title="Menu">
|
||||
{#if isAllUserOwned}
|
||||
<FavoriteAction menuItem removeFavorite={isAllFavorite} />
|
||||
{/if}
|
||||
|
@ -333,33 +336,33 @@
|
|||
</AssetSelectControlBar>
|
||||
{:else}
|
||||
{#if viewMode === ViewMode.VIEW || viewMode === ViewMode.ALBUM_OPTIONS}
|
||||
<ControlAppBar showBackButton backIcon={ArrowLeft} on:close-button-click={() => goto(backUrl)}>
|
||||
<ControlAppBar showBackButton backIcon={mdiArrowLeft} on:close-button-click={() => goto(backUrl)}>
|
||||
<svelte:fragment slot="trailing">
|
||||
<CircleIconButton
|
||||
title="Add Photos"
|
||||
on:click={() => (viewMode = ViewMode.SELECT_ASSETS)}
|
||||
logo={FileImagePlusOutline}
|
||||
icon={mdiFileImagePlusOutline}
|
||||
/>
|
||||
|
||||
{#if isOwned}
|
||||
<CircleIconButton
|
||||
title="Share"
|
||||
on:click={() => (viewMode = ViewMode.SELECT_USERS)}
|
||||
logo={ShareVariantOutline}
|
||||
icon={mdiShareVariantOutline}
|
||||
/>
|
||||
<CircleIconButton
|
||||
title="Delete album"
|
||||
on:click={() => (viewMode = ViewMode.CONFIRM_DELETE)}
|
||||
logo={DeleteOutline}
|
||||
icon={mdiDeleteOutline}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if album.assetCount > 0}
|
||||
<CircleIconButton title="Download" on:click={handleDownloadAlbum} logo={FolderDownloadOutline} />
|
||||
<CircleIconButton title="Download" on:click={handleDownloadAlbum} icon={mdiFolderDownloadOutline} />
|
||||
|
||||
{#if isOwned}
|
||||
<div use:clickOutside on:outclick={() => (viewMode = ViewMode.VIEW)}>
|
||||
<CircleIconButton title="Album options" on:click={handleOpenAlbumOptions} logo={DotsVertical}>
|
||||
<CircleIconButton title="Album options" on:click={handleOpenAlbumOptions} icon={mdiDotsVertical}>
|
||||
{#if viewMode === ViewMode.ALBUM_OPTIONS}
|
||||
<ContextMenu {...contextMenuPosition}>
|
||||
<MenuOption on:click={() => (viewMode = ViewMode.SELECT_THUMBNAIL)} text="Set album cover" />
|
||||
|
@ -465,7 +468,7 @@
|
|||
backgroundColor="#d3d3d3"
|
||||
forceDark
|
||||
size="20"
|
||||
logo={Link}
|
||||
icon={mdiLink}
|
||||
on:click={() => (viewMode = ViewMode.LINK_SHARING)}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -487,7 +490,7 @@
|
|||
backgroundColor="#d3d3d3"
|
||||
forceDark
|
||||
size="20"
|
||||
logo={Plus}
|
||||
icon={mdiPlus}
|
||||
on:click={() => (viewMode = ViewMode.SELECT_USERS)}
|
||||
title="Add more users"
|
||||
/>
|
||||
|
@ -518,7 +521,9 @@
|
|||
on:click={() => (viewMode = ViewMode.SELECT_ASSETS)}
|
||||
class="mt-5 flex w-full place-items-center gap-6 rounded-md border bg-immich-bg px-8 py-8 text-immich-fg transition-all hover:bg-gray-100 hover:text-immich-primary dark:border-none dark:bg-immich-dark-gray dark:text-immich-dark-fg dark:hover:text-immich-dark-primary"
|
||||
>
|
||||
<span class="text-text-immich-primary dark:text-immich-dark-primary"><Plus size="24" /> </span>
|
||||
<span class="text-text-immich-primary dark:text-immich-dark-primary"
|
||||
><Icon path={mdiPlus} size="24" />
|
||||
</span>
|
||||
<span class="text-lg">Select photos</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
|
||||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { TimeBucketSize } from '@api';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiPlus, mdiDotsVertical } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -33,12 +32,12 @@
|
|||
<ArchiveAction unarchive onArchive={(ids) => assetStore.removeAssets(ids)} />
|
||||
<CreateSharedLink />
|
||||
<SelectAllAssets {assetStore} {assetInteractionStore} />
|
||||
<AssetSelectContextMenu icon={Plus} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
<AddToAlbum shared />
|
||||
</AssetSelectContextMenu>
|
||||
<DeleteAssets onAssetDelete={(assetId) => assetStore.removeAsset(assetId)} />
|
||||
<AssetSelectContextMenu icon={DotsVertical} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiDotsVertical} title="Add">
|
||||
<DownloadAction menuItem />
|
||||
<FavoriteAction menuItem removeFavorite={isAllFavorite} />
|
||||
</AssetSelectContextMenu>
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { AssetTypeEnum, SearchExploreResponseDto, api } from '@api';
|
||||
import ClockOutline from 'svelte-material-icons/ClockOutline.svelte';
|
||||
import HeartMultipleOutline from 'svelte-material-icons/HeartMultipleOutline.svelte';
|
||||
import MotionPlayOutline from 'svelte-material-icons/MotionPlayOutline.svelte';
|
||||
import PlayCircleOutline from 'svelte-material-icons/PlayCircleOutline.svelte';
|
||||
import Rotate360Icon from 'svelte-material-icons/Rotate360.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import {
|
||||
mdiHeartMultipleOutline,
|
||||
mdiClockOutline,
|
||||
mdiPlayCircleOutline,
|
||||
mdiMotionPlayOutline,
|
||||
mdiRotate360,
|
||||
} from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -118,7 +121,7 @@
|
|||
class="flex w-full content-center gap-2 text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary"
|
||||
draggable="false"
|
||||
>
|
||||
<HeartMultipleOutline size={24} />
|
||||
<Icon path={mdiHeartMultipleOutline} size={24} />
|
||||
<span>Favorites</span>
|
||||
</a>
|
||||
<a
|
||||
|
@ -126,7 +129,7 @@
|
|||
class="flex w-full content-center gap-2 text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary"
|
||||
draggable="false"
|
||||
>
|
||||
<ClockOutline size={24} />
|
||||
<Icon path={mdiClockOutline} size={24} />
|
||||
<span>Recently added</span>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -138,7 +141,7 @@
|
|||
href="/search?type={AssetTypeEnum.Video}"
|
||||
class="flex w-full items-center gap-2 text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary"
|
||||
>
|
||||
<PlayCircleOutline size={24} />
|
||||
<Icon path={mdiPlayCircleOutline} size={24} />
|
||||
<span>Videos</span>
|
||||
</a>
|
||||
<div>
|
||||
|
@ -146,7 +149,7 @@
|
|||
href="/search?motion=true"
|
||||
class="flex w-full items-center gap-2 text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary"
|
||||
>
|
||||
<MotionPlayOutline size={24} />
|
||||
<Icon path={mdiMotionPlayOutline} size={24} />
|
||||
<span>Motion photos</span>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -155,7 +158,7 @@
|
|||
href="/search?exifInfo.projectionType=EQUIRECTANGULAR"
|
||||
class="flex w-full items-center gap-2 text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary"
|
||||
>
|
||||
<Rotate360Icon size={24} />
|
||||
<Icon path={mdiRotate360} size={24} />
|
||||
<span>Panorama photos</span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
|
||||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { TimeBucketSize } from '@api';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiDotsVertical, mdiPlus } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -34,12 +33,12 @@
|
|||
<FavoriteAction removeFavorite onFavorite={(ids) => assetStore.removeAssets(ids)} />
|
||||
<CreateSharedLink />
|
||||
<SelectAllAssets {assetStore} {assetInteractionStore} />
|
||||
<AssetSelectContextMenu icon={Plus} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
<AddToAlbum shared />
|
||||
</AssetSelectContextMenu>
|
||||
<DeleteAssets onAssetDelete={(assetId) => assetStore.removeAsset(assetId)} />
|
||||
<AssetSelectContextMenu icon={DotsVertical} title="Menu">
|
||||
<AssetSelectContextMenu icon={mdiDotsVertical} title="Menu">
|
||||
<DownloadAction menuItem />
|
||||
<ArchiveAction menuItem unarchive={isAllArchive} />
|
||||
</AssetSelectContextMenu>
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
import { isEqual, omit } from 'lodash-es';
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import Cog from 'svelte-material-icons/Cog.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiCog } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -135,7 +136,7 @@
|
|||
title="Open map settings"
|
||||
on:click={() => (showSettingsModal = true)}
|
||||
>
|
||||
<Cog size="100%" class="p-1" />
|
||||
<Icon path={mdiCog} size="100%" class="p-1" />
|
||||
</button>
|
||||
</Control>
|
||||
</Map>
|
||||
|
|
|
@ -12,9 +12,8 @@
|
|||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { TimeBucketSize } from '@api';
|
||||
import { onDestroy } from 'svelte';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiPlus, mdiArrowLeft } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -31,14 +30,14 @@
|
|||
{#if $isMultiSelectState}
|
||||
<AssetSelectControlBar assets={$selectedAssets} clearSelect={assetInteractionStore.clearMultiselect}>
|
||||
<CreateSharedLink />
|
||||
<AssetSelectContextMenu icon={Plus} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
<AddToAlbum shared />
|
||||
</AssetSelectContextMenu>
|
||||
<DownloadAction />
|
||||
</AssetSelectControlBar>
|
||||
{:else}
|
||||
<ControlAppBar showBackButton backIcon={ArrowLeft} on:close-button-click={() => goto(AppRoute.SHARING)}>
|
||||
<ControlAppBar showBackButton backIcon={mdiArrowLeft} on:close-button-click={() => goto(AppRoute.SHARING)}>
|
||||
<svelte:fragment slot="leading">
|
||||
<p class="whitespace-nowrap text-immich-fg dark:text-immich-dark-fg">
|
||||
{data.partner.firstName}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script lang="ts">
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import AccountOff from 'svelte-material-icons/AccountOff.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import PeopleCard from '$lib/components/faces-page/people-card.svelte';
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
|
@ -15,19 +14,20 @@
|
|||
} from '$lib/components/shared-components/notification/notification';
|
||||
import ShowHide from '$lib/components/faces-page/show-hide.svelte';
|
||||
import IconButton from '$lib/components/elements/buttons/icon-button.svelte';
|
||||
import EyeOutline from 'svelte-material-icons/EyeOutline.svelte';
|
||||
import ImageThumbnail from '$lib/components/assets/thumbnail/image-thumbnail.svelte';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { browser } from '$app/environment';
|
||||
import MergeSuggestionModal from '$lib/components/faces-page/merge-suggestion-modal.svelte';
|
||||
import SetBirthDateModal from '$lib/components/faces-page/set-birth-date-modal.svelte';
|
||||
import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
|
||||
import { mdiAccountOff, mdiEyeOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
let selectHidden = false;
|
||||
let initialHiddenValues: Record<string, boolean> = {};
|
||||
|
||||
let eyeColorMap: Record<string, string> = {};
|
||||
let eyeColorMap: Record<string, 'black' | 'white'> = {};
|
||||
|
||||
let people = data.people.people;
|
||||
let countTotalPeople = data.people.total;
|
||||
|
@ -362,7 +362,7 @@
|
|||
{#if countTotalPeople > 0}
|
||||
<IconButton on:click={() => (selectHidden = !selectHidden)}>
|
||||
<div class="flex flex-wrap place-items-center justify-center gap-x-1 text-sm">
|
||||
<EyeOutline size="18" />
|
||||
<Icon path={mdiEyeOutline} size="18" />
|
||||
<p class="ml-2">Show & hide faces</p>
|
||||
</div>
|
||||
</IconButton>
|
||||
|
@ -388,7 +388,7 @@
|
|||
{:else}
|
||||
<div class="flex min-h-[calc(66vh_-_11rem)] w-full place-content-center items-center dark:text-white">
|
||||
<div class="flex flex-col content-center items-center text-center">
|
||||
<AccountOff size="3.5em" />
|
||||
<Icon path={mdiAccountOff} size="3.5em" />
|
||||
<p class="mt-5 text-3xl font-medium">No people</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -29,13 +29,11 @@
|
|||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { AssetResponseDto, PersonResponseDto, TimeBucketSize, api } from '@api';
|
||||
import { onMount } from 'svelte';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import { mdiPlus, mdiDotsVertical, mdiArrowLeft } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -370,12 +368,12 @@
|
|||
<AssetSelectControlBar assets={$selectedAssets} clearSelect={() => assetInteractionStore.clearMultiselect()}>
|
||||
<CreateSharedLink />
|
||||
<SelectAllAssets {assetStore} {assetInteractionStore} />
|
||||
<AssetSelectContextMenu icon={Plus} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
<AddToAlbum shared />
|
||||
</AssetSelectContextMenu>
|
||||
<DeleteAssets onAssetDelete={(assetId) => $assetStore.removeAsset(assetId)} />
|
||||
<AssetSelectContextMenu icon={DotsVertical} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiDotsVertical} title="Add">
|
||||
<DownloadAction menuItem filename="{data.person.name || 'immich'}.zip" />
|
||||
<FavoriteAction menuItem removeFavorite={isAllFavorite} />
|
||||
<ArchiveAction menuItem unarchive={isAllArchive} onArchive={(ids) => $assetStore.removeAssets(ids)} />
|
||||
|
@ -383,9 +381,9 @@
|
|||
</AssetSelectControlBar>
|
||||
{:else}
|
||||
{#if viewMode === ViewMode.VIEW_ASSETS || viewMode === ViewMode.SUGGEST_MERGE || viewMode === ViewMode.BIRTH_DATE}
|
||||
<ControlAppBar showBackButton backIcon={ArrowLeft} on:close-button-click={() => goto(previousRoute)}>
|
||||
<ControlAppBar showBackButton backIcon={mdiArrowLeft} on:close-button-click={() => goto(previousRoute)}>
|
||||
<svelte:fragment slot="trailing">
|
||||
<AssetSelectContextMenu icon={DotsVertical} title="Menu">
|
||||
<AssetSelectContextMenu icon={mdiDotsVertical} title="Menu">
|
||||
<MenuOption text="Change feature photo" on:click={() => (viewMode = ViewMode.SELECT_FACE)} />
|
||||
<MenuOption text="Set date of birth" on:click={() => (viewMode = ViewMode.BIRTH_DATE)} />
|
||||
<MenuOption text="Merge face" on:click={() => (viewMode = ViewMode.MERGE_FACES)} />
|
||||
|
|
|
@ -18,10 +18,9 @@
|
|||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
import { TimeBucketSize } from '@api';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { mdiDotsVertical, mdiPlus } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -52,7 +51,7 @@
|
|||
<AssetSelectControlBar assets={$selectedAssets} clearSelect={() => assetInteractionStore.clearMultiselect()}>
|
||||
<CreateSharedLink on:escape={() => (handleEscapeKey = true)} />
|
||||
<SelectAllAssets {assetStore} {assetInteractionStore} />
|
||||
<AssetSelectContextMenu icon={Plus} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
<AddToAlbum shared />
|
||||
</AssetSelectContextMenu>
|
||||
|
@ -60,7 +59,7 @@
|
|||
on:escape={() => (handleEscapeKey = true)}
|
||||
onAssetDelete={(assetId) => assetStore.removeAsset(assetId)}
|
||||
/>
|
||||
<AssetSelectContextMenu icon={DotsVertical} title="Menu">
|
||||
<AssetSelectContextMenu icon={mdiDotsVertical} title="Menu">
|
||||
<FavoriteAction menuItem removeFavorite={isAllFavorite} />
|
||||
<DownloadAction menuItem />
|
||||
<ArchiveAction menuItem onArchive={(ids) => assetStore.removeAssets(ids)} />
|
||||
|
|
|
@ -13,12 +13,8 @@
|
|||
import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte';
|
||||
import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte';
|
||||
import type { AssetResponseDto } from '@api';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import ImageOffOutline from 'svelte-material-icons/ImageOffOutline.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import SelectAll from 'svelte-material-icons/SelectAll.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import AlbumCard from '$lib/components/album-page/album-card.svelte';
|
||||
|
@ -28,6 +24,7 @@
|
|||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { preventRaceConditionSearchBar } from '$lib/stores/search.store';
|
||||
import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
|
||||
import { mdiArrowLeft, mdiDotsVertical, mdiImageOffOutline, mdiPlus, mdiSelectAll } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -109,21 +106,21 @@
|
|||
{#if isMultiSelectionMode}
|
||||
<AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new Set())}>
|
||||
<CreateSharedLink />
|
||||
<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
|
||||
<AssetSelectContextMenu icon={Plus} title="Add">
|
||||
<CircleIconButton title="Select all" icon={mdiSelectAll} on:click={handleSelectAll} />
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
<AddToAlbum shared />
|
||||
</AssetSelectContextMenu>
|
||||
<DeleteAssets {onAssetDelete} />
|
||||
|
||||
<AssetSelectContextMenu icon={DotsVertical} title="Add">
|
||||
<AssetSelectContextMenu icon={mdiDotsVertical} title="Add">
|
||||
<DownloadAction menuItem />
|
||||
<FavoriteAction menuItem removeFavorite={isAllFavorite} />
|
||||
<ArchiveAction menuItem unarchive={isAllArchived} />
|
||||
</AssetSelectContextMenu>
|
||||
</AssetSelectControlBar>
|
||||
{:else}
|
||||
<ControlAppBar on:close-button-click={() => goto(previousRoute)} backIcon={ArrowLeft}>
|
||||
<ControlAppBar on:close-button-click={() => goto(previousRoute)} backIcon={mdiArrowLeft}>
|
||||
<div class="w-full flex-1 pl-4">
|
||||
<SearchBar grayTheme={false} value={term} />
|
||||
</div>
|
||||
|
@ -155,7 +152,7 @@
|
|||
{:else}
|
||||
<div class="flex min-h-[calc(66vh_-_11rem)] w-full place-content-center items-center dark:text-white">
|
||||
<div class="flex flex-col content-center items-center text-center">
|
||||
<ImageOffOutline size="3.5em" />
|
||||
<Icon path={mdiImageOffOutline} size="3.5em" />
|
||||
<p class="mt-5 text-3xl font-medium">No results</p>
|
||||
<p class="text-base font-normal">Try a synonym or more general keyword</p>
|
||||
</div>
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { api } from '@api';
|
||||
import Link from 'svelte-material-icons/Link.svelte';
|
||||
import PlusBoxOutline from 'svelte-material-icons/PlusBoxOutline.svelte';
|
||||
import { flip } from 'svelte/animate';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiLink, mdiPlusBoxOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -43,14 +43,14 @@
|
|||
<div class="flex" slot="buttons">
|
||||
<LinkButton on:click={createSharedAlbum}>
|
||||
<div class="flex flex-wrap place-items-center justify-center gap-x-1 text-sm">
|
||||
<PlusBoxOutline size="18" class="shrink-0" />
|
||||
<Icon path={mdiPlusBoxOutline} size="18" class="shrink-0" />
|
||||
<span class="leading-none max-sm:text-xs">Create shared album</span>
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
||||
<LinkButton on:click={() => goto(AppRoute.SHARED_LINKS)}>
|
||||
<div class="flex flex-wrap place-items-center justify-center gap-x-1 text-sm">
|
||||
<Link size="18" class="shrink-0" />
|
||||
<Icon path={mdiLink} size="18" class="shrink-0" />
|
||||
<span class="leading-none max-sm:text-xs">Shared links</span>
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script lang="ts">
|
||||
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
|
||||
import ArrowLeft from 'svelte-material-icons/ArrowLeft.svelte';
|
||||
import { api, copyToClipboard, SharedLinkResponseDto } from '@api';
|
||||
import { goto } from '$app/navigation';
|
||||
import SharedLinkCard from '$lib/components/sharedlinks-page/shared-link-card.svelte';
|
||||
|
@ -13,6 +12,7 @@
|
|||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { mdiArrowLeft } from '@mdi/js';
|
||||
|
||||
let sharedLinks: SharedLinkResponseDto[] = [];
|
||||
let editSharedLink: SharedLinkResponseDto | null = null;
|
||||
|
@ -53,7 +53,7 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<ControlAppBar backIcon={ArrowLeft} on:close-button-click={() => goto(AppRoute.SHARING)}>
|
||||
<ControlAppBar backIcon={mdiArrowLeft} on:close-button-click={() => goto(AppRoute.SHARING)}>
|
||||
<svelte:fragment slot="leading">Shared links</svelte:fragment>
|
||||
</ControlAppBar>
|
||||
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { api, TimeBucketSize } from '@api';
|
||||
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
|
||||
import HistoryOutline from 'svelte-material-icons/History.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { featureFlags, serverConfig } from '$lib/stores/server-config.store';
|
||||
import { goto } from '$app/navigation';
|
||||
import empty3Url from '$lib/assets/empty-3.svg';
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import { mdiDeleteOutline, mdiHistory } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -74,13 +74,13 @@
|
|||
<div class="flex place-items-center gap-2" slot="buttons">
|
||||
<LinkButton on:click={handleRestoreTrash}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<HistoryOutline size="18" />
|
||||
<Icon path={mdiHistory} size="18" />
|
||||
Restore All
|
||||
</div>
|
||||
</LinkButton>
|
||||
<LinkButton on:click={() => (isShowEmptyConfirmation = true)}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<DeleteOutline size="18" />
|
||||
<Icon path={mdiDeleteOutline} size="18" />
|
||||
Empty Trash
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<script>
|
||||
import { page } from '$app/stores';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
|
||||
import CodeTags from 'svelte-material-icons/CodeTags.svelte';
|
||||
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
|
||||
import Message from 'svelte-material-icons/Message.svelte';
|
||||
import PartyPopper from 'svelte-material-icons/PartyPopper.svelte';
|
||||
import { mdiCodeTags, mdiContentCopy, mdiMessage, mdiPartyPopper } from '@mdi/js';
|
||||
import { copyToClipboard } from '../api/utils';
|
||||
|
||||
const handleCopy = async () => {
|
||||
|
@ -43,7 +41,7 @@
|
|||
on:click={() => handleCopy()}
|
||||
class="rounded-full bg-immich-primary px-3 py-2 text-sm text-white shadow-md transition-colors hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:hover:bg-immich-dark-primary/80"
|
||||
>
|
||||
<ContentCopy size={24} />
|
||||
<Icon path={mdiContentCopy} size={24} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -71,7 +69,7 @@
|
|||
class="flex grow basis-0 justify-center p-4"
|
||||
>
|
||||
<button class="flex flex-col place-content-center place-items-center gap-2">
|
||||
<Message size={24} />
|
||||
<Icon path={mdiMessage} size={24} />
|
||||
<p class="text-sm">Get Help</p>
|
||||
</button>
|
||||
</a>
|
||||
|
@ -83,7 +81,7 @@
|
|||
class="flex grow basis-0 justify-center p-4"
|
||||
>
|
||||
<button class="flex flex-col place-content-center place-items-center gap-2">
|
||||
<PartyPopper size={24} />
|
||||
<Icon path={mdiPartyPopper} size={24} />
|
||||
<p class="text-sm">Read Changelog</p>
|
||||
</button>
|
||||
</a>
|
||||
|
@ -95,7 +93,7 @@
|
|||
class="flex grow basis-0 justify-center p-4"
|
||||
>
|
||||
<button class="flex flex-col place-content-center place-items-center gap-2">
|
||||
<CodeTags size={24} />
|
||||
<Icon path={mdiCodeTags} size={24} />
|
||||
<p class="text-sm">Check Logs</p>
|
||||
</button>
|
||||
</a>
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
import { AppRoute } from '$lib/constants';
|
||||
import { AllJobStatusResponseDto, api } from '@api';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import CogIcon from 'svelte-material-icons/Cog.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiCog } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -34,7 +35,7 @@
|
|||
<a href="{AppRoute.ADMIN_SETTINGS}?open=job-settings">
|
||||
<LinkButton>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<CogIcon size="18" />
|
||||
<Icon path={mdiCog} size="18" />
|
||||
Manage Concurrency
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
|
|
@ -12,12 +12,9 @@
|
|||
import { downloadBlob } from '$lib/utils/asset-utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { FileReportItemDto, api, copyToClipboard } from '@api';
|
||||
import CheckAll from 'svelte-material-icons/CheckAll.svelte';
|
||||
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
|
||||
import Download from 'svelte-material-icons/Download.svelte';
|
||||
import Refresh from 'svelte-material-icons/Refresh.svelte';
|
||||
import Wrench from 'svelte-material-icons/Wrench.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiWrench, mdiCheckAll, mdiDownload, mdiRefresh, mdiContentCopy } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -178,25 +175,25 @@
|
|||
<div class="flex justify-end gap-2" slot="buttons">
|
||||
<LinkButton on:click={() => handleRepair()} disabled={matches.length === 0 || repairing}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<Wrench size="18" />
|
||||
<Icon path={mdiWrench} size="18" />
|
||||
Repair All
|
||||
</div>
|
||||
</LinkButton>
|
||||
<LinkButton on:click={() => handleCheckAll()} disabled={extras.length === 0 || checking}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<CheckAll size="18" />
|
||||
<Icon path={mdiCheckAll} size="18" />
|
||||
Check All
|
||||
</div>
|
||||
</LinkButton>
|
||||
<LinkButton on:click={() => handleDownload()} disabled={extras.length + orphans.length === 0}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<Download size="18" />
|
||||
<Icon path={mdiDownload} size="18" />
|
||||
Export
|
||||
</div>
|
||||
</LinkButton>
|
||||
<LinkButton on:click={() => handleRefresh()}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<Refresh size="18" />
|
||||
<Icon path={mdiRefresh} size="18" />
|
||||
Refresh
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
@ -273,7 +270,7 @@
|
|||
title={orphan.pathValue}
|
||||
>
|
||||
<td on:click={() => copyToClipboard(orphan.pathValue)}>
|
||||
<CircleIconButton logo={ContentCopy} size="18" />
|
||||
<CircleIconButton icon={mdiContentCopy} size="18" />
|
||||
</td>
|
||||
<td class="truncate text-sm font-mono text-left" title={orphan.pathValue}>
|
||||
{orphan.pathValue}
|
||||
|
@ -313,7 +310,7 @@
|
|||
title={extra.filename}
|
||||
>
|
||||
<td on:click={() => copyToClipboard(extra.filename)}>
|
||||
<CircleIconButton logo={ContentCopy} size="18" />
|
||||
<CircleIconButton icon={mdiContentCopy} size="18" />
|
||||
</td>
|
||||
<td class="w-full text-md text-ellipsis flex justify-between pr-5">
|
||||
<span class="text-ellipsis grow truncate font-mono text-sm pr-5" title={extra.filename}
|
||||
|
|
|
@ -17,11 +17,10 @@
|
|||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { downloadBlob } from '$lib/utils/asset-utils';
|
||||
import { copyToClipboard } from '@api';
|
||||
import Alert from 'svelte-material-icons/Alert.svelte';
|
||||
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
|
||||
import Download from 'svelte-material-icons/Download.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import NewVersionCheckSettings from '$lib/components/admin-page/settings/new-version-check-settings/new-version-check-settings.svelte';
|
||||
import { mdiAlert, mdiContentCopy, mdiDownload } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -39,7 +38,7 @@
|
|||
|
||||
{#if $featureFlags.configFile}
|
||||
<div class="mb-8 flex flex-row items-center gap-2 rounded-md bg-gray-100 p-3 dark:bg-gray-800">
|
||||
<Alert class="text-yellow-400" size={18} />
|
||||
<Icon path={mdiAlert} class="text-yellow-400" size={18} />
|
||||
<h2 class="text-md text-immich-primary dark:text-immich-dark-primary">Config is currently set by a config file</h2>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -48,13 +47,13 @@
|
|||
<div class="flex justify-end gap-2" slot="buttons">
|
||||
<LinkButton on:click={() => copyToClipboard(JSON.stringify(configs, null, 2))}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<ContentCopy size="18" />
|
||||
<Icon path={mdiContentCopy} size="18" />
|
||||
Copy to Clipboard
|
||||
</div>
|
||||
</LinkButton>
|
||||
<LinkButton on:click={() => downloadConfig()}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<Download size="18" />
|
||||
<Icon path={mdiDownload} size="18" />
|
||||
Export as JSON
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { api, UserResponseDto } from '@api';
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import PencilOutline from 'svelte-material-icons/PencilOutline.svelte';
|
||||
import TrashCanOutline from 'svelte-material-icons/TrashCanOutline.svelte';
|
||||
import DeleteRestore from 'svelte-material-icons/DeleteRestore.svelte';
|
||||
import Check from 'svelte-material-icons/Check.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
import CreateUserForm from '$lib/components/forms/create-user-form.svelte';
|
||||
import EditUserForm from '$lib/components/forms/edit-user-form.svelte';
|
||||
|
@ -17,6 +12,7 @@
|
|||
import Button from '$lib/components/elements/buttons/button.svelte';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { mdiCheck, mdiClose, mdiDeleteRestore, mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -196,9 +192,9 @@
|
|||
<td class="w-2/12 text-ellipsis break-all px-2 text-sm">
|
||||
<div class="container mx-auto flex flex-wrap justify-center">
|
||||
{#if user.externalPath}
|
||||
<Check size="16" />
|
||||
<Icon path={mdiCheck} size="16" />
|
||||
{:else}
|
||||
<Close size="16" />
|
||||
<Icon path={mdiClose} size="16" />
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
|
@ -208,14 +204,14 @@
|
|||
on:click={() => editUserHandler(user)}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<PencilOutline size="16" />
|
||||
<Icon path={mdiPencilOutline} size="16" />
|
||||
</button>
|
||||
{#if user.id !== data.user.id}
|
||||
<button
|
||||
on:click={() => deleteUserHandler(user)}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<TrashCanOutline size="16" />
|
||||
<Icon path={mdiTrashCanOutline} size="16" />
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
|
@ -225,7 +221,7 @@
|
|||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
title={`scheduled removal on ${getDeleteDate(user)}`}
|
||||
>
|
||||
<DeleteRestore size="16" />
|
||||
<Icon path={mdiDeleteRestore} size="16" />
|
||||
</button>
|
||||
{/if}
|
||||
</td>
|
||||
|
@ -265,13 +261,13 @@
|
|||
on:click={() => editUserHandler(user)}
|
||||
class="rounded-full bg-immich-primary p-2 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700 max-sm:mb-1 sm:p-3"
|
||||
>
|
||||
<PencilOutline size="16" />
|
||||
<Icon path={mdiPencilOutline} size="16" />
|
||||
</button>
|
||||
<button
|
||||
on:click={() => deleteUserHandler(user)}
|
||||
class="rounded-full bg-immich-primary p-2 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700 sm:p-3"
|
||||
>
|
||||
<TrashCanOutline size="16" />
|
||||
<Icon path={mdiTrashCanOutline} size="16" />
|
||||
</button>
|
||||
{/if}
|
||||
{#if isDeleted(user)}
|
||||
|
@ -280,7 +276,7 @@
|
|||
class="rounded-full bg-immich-primary p-2 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700 sm:p-3"
|
||||
title={`scheduled removal on ${getDeleteDate(user)}`}
|
||||
>
|
||||
<DeleteRestore size="16" />
|
||||
<Icon path={mdiDeleteRestore} size="16" />
|
||||
</button>
|
||||
{/if}
|
||||
</td>
|
||||
|
|
Loading…
Reference in a new issue