mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
first pass at replacing all CircleIconButtons
This commit is contained in:
parent
0b18f5c12a
commit
1f6ad41d3f
@ -2,44 +2,23 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import { onMount } from 'svelte';
|
||||
import { mdiCast, mdiCastConnected } from '@mdi/js';
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { CastDestinationType, castManager } from '$lib/managers/cast-manager.svelte';
|
||||
import { GCastDestination } from '$lib/utils/cast/gcast-destination.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
whiteHover?: boolean;
|
||||
navBar?: boolean;
|
||||
}
|
||||
|
||||
let { whiteHover, navBar }: Props = $props();
|
||||
|
||||
onMount(async () => {
|
||||
await castManager.initialize();
|
||||
});
|
||||
|
||||
const getButtonColor = () => {
|
||||
return castManager.isCasting ? 'primary' : whiteHover ? undefined : 'opaque';
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if castManager.availableDestinations.length > 0 && castManager.availableDestinations[0].type === CastDestinationType.GCAST}
|
||||
{#if navBar}
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
size="medium"
|
||||
color={castManager.isCasting ? 'primary' : 'secondary'}
|
||||
icon={castManager.isCasting ? mdiCastConnected : mdiCast}
|
||||
onclick={() => void GCastDestination.showCastDialog()}
|
||||
aria-label={$t('cast')}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton
|
||||
color={getButtonColor()}
|
||||
icon={castManager.isCasting ? mdiCastConnected : mdiCast}
|
||||
onclick={GCastDestination.showCastDialog}
|
||||
title={$t('cast')}
|
||||
/>
|
||||
{/if}
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
size="medium"
|
||||
color={castManager.isCasting ? 'primary' : 'secondary'}
|
||||
icon={castManager.isCasting ? mdiCastConnected : mdiCast}
|
||||
onclick={() => void GCastDestination.showCastDialog()}
|
||||
aria-label={$t('cast')}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import JobTileButton from './job-tile-button.svelte';
|
||||
import JobTileStatus from './job-tile-status.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
@ -75,12 +76,12 @@
|
||||
<span class="text-sm">
|
||||
{$t('admin.jobs_failed', { values: { jobCount: jobCounts.failed.toLocaleString($locale) } })}
|
||||
</span>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
color="primary"
|
||||
icon={mdiClose}
|
||||
title={$t('clear_message')}
|
||||
size="12"
|
||||
padding="1"
|
||||
aria-label={$t('clear_message')}
|
||||
size="tiny"
|
||||
shape="round"
|
||||
onclick={() => onCommand({ command: JobCommand.ClearFailed, force: false })}
|
||||
/>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@
|
||||
import { SettingInputFieldType } from '$lib/constants';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import type { SystemConfigDto } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiMinusCircle } from '@mdi/js';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -48,12 +48,11 @@
|
||||
{#each config.machineLearning.urls as _, i (i)}
|
||||
{#snippet removeButton()}
|
||||
{#if config.machineLearning.urls.length > 1}
|
||||
<CircleIconButton
|
||||
size="24"
|
||||
class="ms-2"
|
||||
padding="2"
|
||||
color="red"
|
||||
title=""
|
||||
<IconButton
|
||||
size="large"
|
||||
shape="round"
|
||||
color="danger"
|
||||
aria-label=""
|
||||
onclick={() => config.machineLearning.urls.splice(i, 1)}
|
||||
icon={mdiMinusCircle}
|
||||
/>
|
||||
|
@ -4,6 +4,7 @@
|
||||
import { getContextMenuPositionFromEvent, type ContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import { getShortDateRange } from '$lib/utils/date-time';
|
||||
import type { AlbumResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiDotsVertical } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -42,12 +43,13 @@
|
||||
class="absolute end-6 top-6 opacity-0 group-hover:opacity-100 focus-within:opacity-100"
|
||||
data-testid="context-button-parent"
|
||||
>
|
||||
<CircleIconButton
|
||||
color="opaque"
|
||||
title={$t('show_album_options')}
|
||||
<IconButton
|
||||
color="secondary"
|
||||
aria-label={$t('show_album_options')}
|
||||
icon={mdiDotsVertical}
|
||||
size="20"
|
||||
padding="2"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
size="medium"
|
||||
class="icon-white-drop-shadow"
|
||||
onclick={showAlbumContextMenu}
|
||||
/>
|
||||
|
@ -7,7 +7,7 @@
|
||||
import { delay } from '$lib/utils/asset-utils';
|
||||
import { navigate } from '$lib/utils/navigation';
|
||||
import { getAlbumInfo, type AlbumResponseDto, type MapMarkerResponseDto } from '@immich/sdk';
|
||||
import { LoadingSpinner, Modal, ModalBody } from '@immich/ui';
|
||||
import { IconButton, LoadingSpinner, Modal, ModalBody } from '@immich/ui';
|
||||
import { mdiMapOutline } from '@mdi/js';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -103,7 +103,14 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<CircleIconButton title={$t('map')} onclick={openMap} icon={mdiMapOutline} />
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
icon={mdiMapOutline}
|
||||
onclick={openMap}
|
||||
aria-label={$t('map')}
|
||||
/>
|
||||
|
||||
{#if albumMapViewManager.isInMapView}
|
||||
<Modal title={$t('map')} size="medium" onClose={closeMap}>
|
||||
|
@ -2,7 +2,7 @@
|
||||
import SharedLinkCopy from '$lib/components/sharedlinks-page/actions/shared-link-copy.svelte';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import type { AlbumResponseDto, SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { Text } from '@immich/ui';
|
||||
import { IconButton, Text } from '@immich/ui';
|
||||
import { mdiQrcode } from '@mdi/js';
|
||||
import { DateTime } from 'luxon';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -40,7 +40,14 @@
|
||||
<Text size="tiny" color="muted">{getShareProperties()}</Text>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<CircleIconButton title={$t('view_qr_code')} icon={mdiQrcode} onclick={onViewQrCode} />
|
||||
<IconButton
|
||||
aria-label={$t('view_qr_code')}
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiQrcode}
|
||||
onclick={onViewQrCode}
|
||||
/>
|
||||
<SharedLinkCopy link={sharedLink} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,7 +14,6 @@
|
||||
import { mdiFileImagePlusOutline, mdiFolderDownloadOutline } from '@mdi/js';
|
||||
import { onDestroy } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import DownloadAction from '../photos-page/actions/download-action.svelte';
|
||||
import AssetGrid from '../photos-page/asset-grid.svelte';
|
||||
import ControlAppBar from '../shared-components/control-app-bar.svelte';
|
||||
@ -22,6 +21,7 @@
|
||||
import ThemeButton from '../shared-components/theme-button.svelte';
|
||||
import AlbumSummary from './album-summary.svelte';
|
||||
import CastButton from '$lib/cast/cast-button.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
sharedLink: SharedLinkResponseDto;
|
||||
@ -104,19 +104,25 @@
|
||||
{/snippet}
|
||||
|
||||
{#snippet trailing()}
|
||||
<CastButton whiteHover />
|
||||
<CastButton />
|
||||
|
||||
{#if sharedLink.allowUpload}
|
||||
<CircleIconButton
|
||||
title={$t('add_photos')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('add_photos')}
|
||||
onclick={() => openFileUploadDialog({ albumId: album.id })}
|
||||
icon={mdiFileImagePlusOutline}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if album.assetCount > 0 && sharedLink.allowDownload}
|
||||
<CircleIconButton
|
||||
title={$t('download')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('download')}
|
||||
onclick={() => downloadAlbum(album)}
|
||||
icon={mdiFolderDownloadOutline}
|
||||
/>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { shortcut } from '$lib/actions/shortcut';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiArrowLeft } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -12,4 +13,11 @@
|
||||
|
||||
<svelte:document use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
|
||||
|
||||
<CircleIconButton color="opaque" icon={mdiArrowLeft} title={$t('go_back')} onclick={onClose} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiArrowLeft}
|
||||
aria-label={$t('go_back')}
|
||||
onclick={onClose}
|
||||
/>
|
||||
|
@ -15,6 +15,7 @@
|
||||
import { mdiDeleteForeverOutline, mdiDeleteOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import type { OnAction, PreAction } from './action';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
asset: AssetResponseDto;
|
||||
@ -79,10 +80,12 @@
|
||||
]}
|
||||
/>
|
||||
|
||||
<CircleIconButton
|
||||
color="opaque"
|
||||
<IconButton
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
icon={asset.isTrashed ? mdiDeleteForeverOutline : mdiDeleteOutline}
|
||||
title={asset.isTrashed ? $t('permanently_delete') : $t('delete')}
|
||||
aria-label={asset.isTrashed ? $t('permanently_delete') : $t('delete')}
|
||||
onclick={() => trashOrDelete(asset.isTrashed)}
|
||||
/>
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
import type { TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||
import { downloadFile } from '$lib/utils/asset-utils';
|
||||
import { getAssetInfo } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiFolderDownloadOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -21,7 +22,13 @@
|
||||
<svelte:document use:shortcut={{ shortcut: { key: 'd', shift: true }, onShortcut: onDownloadFile }} />
|
||||
|
||||
{#if !menuItem}
|
||||
<CircleIconButton color="opaque" icon={mdiFolderDownloadOutline} title={$t('download')} onclick={onDownloadFile} />
|
||||
<IconButton
|
||||
color="primary"
|
||||
shape="round"
|
||||
icon={mdiFolderDownloadOutline}
|
||||
aria-label={$t('download')}
|
||||
onclick={onDownloadFile}
|
||||
/>
|
||||
{:else}
|
||||
<MenuOption icon={mdiFolderDownloadOutline} text={$t('download')} onClick={onDownloadFile} />
|
||||
{/if}
|
||||
|
@ -11,6 +11,7 @@
|
||||
import { mdiHeart, mdiHeartOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import type { OnAction } from './action';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
asset: AssetResponseDto;
|
||||
@ -47,9 +48,11 @@
|
||||
|
||||
<svelte:document use:shortcut={{ shortcut: { key: 'f' }, onShortcut: toggleFavorite }} />
|
||||
|
||||
<CircleIconButton
|
||||
color="opaque"
|
||||
<IconButton
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
icon={asset.isFavorite ? mdiHeart : mdiHeartOutline}
|
||||
title={asset.isFavorite ? $t('unfavorite') : $t('to_favorite')}
|
||||
aria-label={asset.isFavorite ? $t('unfavorite') : $t('to_favorite')}
|
||||
onclick={toggleFavorite}
|
||||
/>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<script lang="ts"></script>
|
||||
<script lang="ts">
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiMotionPauseOutline, mdiPlaySpeed } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -10,9 +11,10 @@
|
||||
let { isPlaying, onClick }: Props = $props();
|
||||
</script>
|
||||
|
||||
<CircleIconButton
|
||||
color="opaque"
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="primary"
|
||||
icon={isPlaying ? mdiMotionPauseOutline : mdiPlaySpeed}
|
||||
title={isPlaying ? $t('stop_motion_photo') : $t('play_motion_photo')}
|
||||
aria-label={isPlaying ? $t('stop_motion_photo') : $t('play_motion_photo')}
|
||||
onclick={() => onClick(!isPlaying)}
|
||||
/>
|
||||
|
@ -4,6 +4,7 @@
|
||||
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
||||
import { makeSharedLinkUrl } from '$lib/utils';
|
||||
import type { AssetResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiShareVariantOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -22,4 +23,11 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<CircleIconButton color="opaque" icon={mdiShareVariantOutline} onclick={handleClick} title={$t('share')} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
icon={mdiShareVariantOutline}
|
||||
onclick={handleClick}
|
||||
aria-label={$t('share')}
|
||||
/>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { shortcut } from '$lib/actions/shortcut';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiInformationOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -12,4 +13,11 @@
|
||||
|
||||
<svelte:document use:shortcut={{ shortcut: { key: 'i' }, onShortcut: onShowDetail }} />
|
||||
|
||||
<CircleIconButton color="opaque" icon={mdiInformationOutline} onclick={onShowDetail} title={$t('info')} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
icon={mdiInformationOutline}
|
||||
onclick={onShowDetail}
|
||||
aria-label={$t('info')}
|
||||
/>
|
||||
|
@ -12,10 +12,10 @@
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { isTenMinutesApart } from '$lib/utils/timesince';
|
||||
import { ReactionType, type ActivityResponseDto, type AssetTypeEnum, type UserResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiClose, mdiDeleteOutline, mdiDotsVertical, mdiHeart, mdiSend } from '@mdi/js';
|
||||
import * as luxon from 'luxon';
|
||||
import { t } from 'svelte-i18n';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||
import { NotificationType, notificationController } from '../shared-components/notification/notification';
|
||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||
@ -125,7 +125,14 @@
|
||||
bind:clientHeight={activityHeight}
|
||||
>
|
||||
<div class="flex place-items-center gap-2">
|
||||
<CircleIconButton onclick={onClose} icon={mdiClose} title={$t('close')} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
onclick={onClose}
|
||||
icon={mdiClose}
|
||||
aria-label={$t('close')}
|
||||
/>
|
||||
|
||||
<p class="text-lg text-immich-fg dark:text-immich-dark-fg">{$t('activity')}</p>
|
||||
</div>
|
||||
@ -159,7 +166,7 @@
|
||||
title={$t('comment_options')}
|
||||
align="top-right"
|
||||
direction="left"
|
||||
size="16"
|
||||
size="small"
|
||||
>
|
||||
<MenuOption
|
||||
activeColor="bg-red-200"
|
||||
@ -212,7 +219,7 @@
|
||||
title={$t('reaction_options')}
|
||||
align="top-right"
|
||||
direction="left"
|
||||
size="16"
|
||||
size="small"
|
||||
>
|
||||
<MenuOption
|
||||
activeColor="bg-red-200"
|
||||
@ -269,9 +276,11 @@
|
||||
</div>
|
||||
{:else if message}
|
||||
<div class="flex items-end w-fit ms-0">
|
||||
<CircleIconButton
|
||||
title={$t('send_message')}
|
||||
size="15"
|
||||
<IconButton
|
||||
shape="round"
|
||||
aria-label={$t('send_message')}
|
||||
size="small"
|
||||
variant="ghost"
|
||||
icon={mdiSend}
|
||||
class="dark:text-immich-dark-gray"
|
||||
onclick={() => handleSendComment()}
|
||||
|
@ -35,6 +35,7 @@
|
||||
type PersonResponseDto,
|
||||
type StackResponseDto,
|
||||
} from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import {
|
||||
mdiAlertOutline,
|
||||
mdiCogRefreshOutline,
|
||||
@ -122,22 +123,37 @@
|
||||
<ShareAction {asset} />
|
||||
{/if}
|
||||
{#if asset.isOffline}
|
||||
<CircleIconButton color="alert" icon={mdiAlertOutline} onclick={onShowDetail} title={$t('asset_offline')} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="danger"
|
||||
icon={mdiAlertOutline}
|
||||
onclick={onShowDetail}
|
||||
aria-label={$t('asset_offline')}
|
||||
/>
|
||||
{/if}
|
||||
{#if asset.livePhotoVideoId}
|
||||
{@render motionPhoto?.()}
|
||||
{/if}
|
||||
{#if asset.type === AssetTypeEnum.Image}
|
||||
<CircleIconButton
|
||||
color="opaque"
|
||||
hideMobile={true}
|
||||
<IconButton
|
||||
class="hidden sm:flex"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={$photoZoomState && $photoZoomState.currentZoom > 1 ? mdiMagnifyMinusOutline : mdiMagnifyPlusOutline}
|
||||
title={$t('zoom_image')}
|
||||
aria-label={$t('zoom_image')}
|
||||
onclick={onZoomImage}
|
||||
/>
|
||||
{/if}
|
||||
{#if canCopyImageToClipboard() && asset.type === AssetTypeEnum.Image}
|
||||
<CircleIconButton color="opaque" icon={mdiContentCopy} title={$t('copy_image')} onclick={() => onCopyImage?.()} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiContentCopy}
|
||||
aria-label={$t('copy_image')}
|
||||
onclick={() => onCopyImage?.()}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if !isOwner && showDownloadButton}
|
||||
@ -151,20 +167,11 @@
|
||||
{#if isOwner}
|
||||
<FavoriteAction {asset} {onAction} />
|
||||
{/if}
|
||||
<!-- {#if showEditorButton}
|
||||
<CircleIconButton
|
||||
color="opaque"
|
||||
hideMobile={true}
|
||||
icon={mdiImageEditOutline}
|
||||
onclick={showEditorHandler}
|
||||
title={$t('editor')}
|
||||
/>
|
||||
{/if} -->
|
||||
|
||||
{#if isOwner}
|
||||
<DeleteAction {asset} {onAction} {preAction} />
|
||||
|
||||
<ButtonContextMenu direction="left" align="top-right" color="opaque" title={$t('more')} icon={mdiDotsVertical}>
|
||||
<ButtonContextMenu direction="left" align="top-right" color="secondary" title={$t('more')} icon={mdiDotsVertical}>
|
||||
{#if showSlideshow && !isLocked}
|
||||
<MenuOption icon={mdiPresentationPlay} text={$t('slideshow')} onClick={onPlaySlideshow} />
|
||||
{/if}
|
||||
|
@ -27,6 +27,7 @@
|
||||
type AssetResponseDto,
|
||||
type ExifResponseDto,
|
||||
} from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import {
|
||||
mdiCalendar,
|
||||
mdiCameraIris,
|
||||
@ -42,7 +43,6 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import { slide } from 'svelte/transition';
|
||||
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import PersonSidePanel from '../faces-page/person-side-panel.svelte';
|
||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||
@ -158,7 +158,14 @@
|
||||
|
||||
<section class="relative p-2">
|
||||
<div class="flex place-items-center gap-2">
|
||||
<CircleIconButton icon={mdiClose} title={$t('close')} onclick={onClose} />
|
||||
<IconButton
|
||||
icon={mdiClose}
|
||||
aria-label={$t('close')}
|
||||
onclick={onClose}
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
/>
|
||||
<p class="text-lg text-immich-fg dark:text-immich-dark-fg">{$t('info')}</p>
|
||||
</div>
|
||||
|
||||
@ -193,30 +200,34 @@
|
||||
<h2>{$t('people').toUpperCase()}</h2>
|
||||
<div class="flex gap-2 items-center">
|
||||
{#if people.some((person) => person.isHidden)}
|
||||
<CircleIconButton
|
||||
title={$t('show_hidden_people')}
|
||||
<IconButton
|
||||
aria-label={$t('show_hidden_people')}
|
||||
icon={showingHiddenPeople ? mdiEyeOff : mdiEye}
|
||||
padding="1"
|
||||
buttonSize="32"
|
||||
size="medium"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onclick={() => (showingHiddenPeople = !showingHiddenPeople)}
|
||||
/>
|
||||
{/if}
|
||||
<CircleIconButton
|
||||
title={$t('tag_people')}
|
||||
<IconButton
|
||||
aria-label={$t('tag_people')}
|
||||
icon={mdiPlus}
|
||||
padding="1"
|
||||
size="20"
|
||||
buttonSize="32"
|
||||
size="medium"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onclick={() => (isFaceEditMode.value = !isFaceEditMode.value)}
|
||||
/>
|
||||
|
||||
{#if people.length > 0 || unassignedFaces.length > 0}
|
||||
<CircleIconButton
|
||||
title={$t('edit_people')}
|
||||
<IconButton
|
||||
aria-label={$t('edit_people')}
|
||||
icon={mdiPencil}
|
||||
padding="1"
|
||||
size="20"
|
||||
buttonSize="32"
|
||||
size="medium"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onclick={() => (showEditFaces = true)}
|
||||
/>
|
||||
{/if}
|
||||
@ -369,11 +380,13 @@
|
||||
<p class="break-all flex place-items-center gap-2 whitespace-pre-wrap">
|
||||
{asset.originalFileName}
|
||||
{#if isOwner}
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
icon={mdiInformationOutline}
|
||||
title={$t('show_file_location')}
|
||||
size="16"
|
||||
padding="2"
|
||||
aria-label={$t('show_file_location')}
|
||||
size="small"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onclick={toggleAssetPath}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -5,7 +5,7 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fly, slide } from 'svelte/transition';
|
||||
import { getByteUnitString } from '../../utils/byte-units';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
const abort = (downloadKey: string, download: DownloadProgress) => {
|
||||
download.abort?.abort();
|
||||
@ -42,10 +42,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute end-2">
|
||||
<CircleIconButton
|
||||
title={$t('close')}
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
aria-label={$t('close')}
|
||||
onclick={() => abort(downloadKey, download)}
|
||||
size="20"
|
||||
size="large"
|
||||
icon={mdiClose}
|
||||
class="dark:text-immich-dark-gray"
|
||||
/>
|
||||
|
@ -9,6 +9,7 @@
|
||||
rotateDegrees,
|
||||
type CropAspectRatio,
|
||||
} from '$lib/stores/asset-editor.store';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiBackupRestore, mdiCropFree, mdiRotateLeft, mdiRotateRight, mdiSquareOutline } from '@mdi/js';
|
||||
import { tick } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -147,7 +148,25 @@
|
||||
<h2>{$t('editor_crop_tool_h2_rotation').toUpperCase()}</h2>
|
||||
</div>
|
||||
<ul class="flex-wrap flex-row flex gap-x-6 gap-y-4 justify-center">
|
||||
<li><CircleIconButton title={$t('anti_clockwise')} onclick={() => rotate(false)} icon={mdiRotateLeft} /></li>
|
||||
<li><CircleIconButton title={$t('clockwise')} onclick={() => rotate(true)} icon={mdiRotateRight} /></li>
|
||||
<li>
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('anti_clockwise')}
|
||||
onclick={() => rotate(false)}
|
||||
icon={mdiRotateLeft}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('clockwise')}
|
||||
onclick={() => rotate(true)}
|
||||
icon={mdiRotateRight}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -4,10 +4,10 @@
|
||||
import { editTypes, showCancelConfirmDialog } from '$lib/stores/asset-editor.store';
|
||||
import { websocketEvents } from '$lib/stores/websocket';
|
||||
import { type AssetResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import CircleIconButton from '../../elements/buttons/circle-icon-button.svelte';
|
||||
|
||||
onMount(() => {
|
||||
return websocketEvents.on('on_asset_update', (assetUpdate) => {
|
||||
@ -44,17 +44,25 @@
|
||||
|
||||
<section class="relative p-2 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
|
||||
<div class="flex place-items-center gap-2">
|
||||
<CircleIconButton icon={mdiClose} title={$t('close')} onclick={onClose} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
icon={mdiClose}
|
||||
aria-label={$t('close')}
|
||||
onclick={onClose}
|
||||
/>
|
||||
<p class="text-lg text-immich-fg dark:text-immich-dark-fg capitalize">{$t('editor')}</p>
|
||||
</div>
|
||||
<section class="px-4 py-4">
|
||||
<ul class="flex w-full justify-around">
|
||||
{#each editTypes as etype (etype.name)}
|
||||
<li>
|
||||
<CircleIconButton
|
||||
color={etype.name === selectedType ? 'primary' : 'opaque'}
|
||||
<IconButton
|
||||
shape="round"
|
||||
color={etype.name === selectedType ? 'primary' : 'secondary'}
|
||||
icon={etype.icon}
|
||||
title={etype.name}
|
||||
aria-label={etype.name}
|
||||
onclick={() => selectType(etype.name)}
|
||||
/>
|
||||
</li>
|
||||
|
@ -3,6 +3,7 @@
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import { castManager, CastState } from '$lib/managers/cast-manager.svelte';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiCastConnected, mdiPause, mdiPlay } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -83,11 +84,13 @@
|
||||
<LoadingSpinner />
|
||||
</div>
|
||||
{:else}
|
||||
<CircleIconButton
|
||||
color="opaque"
|
||||
<IconButton
|
||||
color="primary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
icon={castManager.castState == CastState.PLAYING ? mdiPause : mdiPlay}
|
||||
onclick={() => handlePlayPauseButton()}
|
||||
title={castManager.castState == CastState.PLAYING ? 'Pause' : 'Play'}
|
||||
aria-label={castManager.castState == CastState.PLAYING ? 'Pause' : 'Play'}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { render, screen } from '@testing-library/svelte';
|
||||
|
||||
describe('CircleIconButton component', () => {
|
||||
it('should render as a button', () => {
|
||||
render(CircleIconButton, { icon: '', title: 'test' });
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toBeInTheDocument();
|
||||
expect(button).toHaveAttribute('type', 'button');
|
||||
expect(button).not.toHaveAttribute('href');
|
||||
expect(button).toHaveAttribute('title', 'test');
|
||||
});
|
||||
|
||||
it('should render as a link if href prop is set', () => {
|
||||
render(CircleIconButton, { props: { href: '/test', icon: '', title: 'test' } });
|
||||
const link = screen.getByRole('link');
|
||||
expect(link).toBeInTheDocument();
|
||||
expect(link).toHaveAttribute('href', '/test');
|
||||
expect(link).not.toHaveAttribute('type');
|
||||
});
|
||||
|
||||
it('should render icon inside button', () => {
|
||||
render(CircleIconButton, { icon: '', title: 'test' });
|
||||
const button = screen.getByRole('button');
|
||||
const icon = button.querySelector('svg');
|
||||
expect(icon).toBeInTheDocument();
|
||||
expect(icon).toHaveAttribute('aria-label', 'test');
|
||||
});
|
||||
});
|
@ -3,6 +3,7 @@
|
||||
import { mdiClose, mdiMagnify } from '@mdi/js';
|
||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@ -42,11 +43,13 @@
|
||||
? 'rounded-2xl'
|
||||
: 'rounded-t-lg'} bg-gray-200 p-2 dark:bg-immich-dark-gray gap-2 place-items-center h-full"
|
||||
>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiMagnify}
|
||||
title={$t('search')}
|
||||
size="16"
|
||||
padding="2"
|
||||
aria-label={$t('search')}
|
||||
size="small"
|
||||
onclick={() => onSearch({ force: true })}
|
||||
/>
|
||||
<input
|
||||
@ -64,6 +67,14 @@
|
||||
</div>
|
||||
{/if}
|
||||
{#if name}
|
||||
<CircleIconButton icon={mdiClose} title={$t('clear_value')} size="16" padding="2" onclick={resetSearch} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiClose}
|
||||
aria-label={$t('clear_value')}
|
||||
size="small"
|
||||
onclick={resetSearch}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -7,6 +7,7 @@
|
||||
import { zoomImageToBase64 } from '$lib/utils/people-utils';
|
||||
import { getPersonNameWithHiddenValue } from '$lib/utils/person';
|
||||
import { AssetTypeEnum, getAllPeople, type AssetFaceResponseDto, type PersonResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiArrowLeftThin, mdiClose, mdiMagnify, mdiPlus } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -78,19 +79,36 @@
|
||||
<div class="flex place-items-center justify-between gap-2">
|
||||
{#if !searchFaces}
|
||||
<div class="flex items-center gap-2">
|
||||
<CircleIconButton icon={mdiArrowLeftThin} title={$t('back')} onclick={onClose} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiArrowLeftThin}
|
||||
aria-label={$t('back')}
|
||||
onclick={onClose}
|
||||
/>
|
||||
<p class="flex text-lg text-immich-fg dark:text-immich-dark-fg">{$t('select_face')}</p>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2">
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiMagnify}
|
||||
title={$t('search_for_existing_person')}
|
||||
aria-label={$t('search_for_existing_person')}
|
||||
onclick={() => {
|
||||
searchFaces = true;
|
||||
}}
|
||||
/>
|
||||
{#if !isShowLoadingNewPerson}
|
||||
<CircleIconButton icon={mdiPlus} title={$t('create_new_person')} onclick={handleCreatePerson} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiPlus}
|
||||
aria-label={$t('create_new_person')}
|
||||
onclick={handleCreatePerson}
|
||||
/>
|
||||
{:else}
|
||||
<div class="flex place-content-center place-items-center">
|
||||
<LoadingSpinner />
|
||||
@ -98,7 +116,14 @@
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<CircleIconButton icon={mdiArrowLeftThin} title={$t('back')} onclick={onClose} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiArrowLeftThin}
|
||||
aria-label={$t('back')}
|
||||
onclick={onClose}
|
||||
/>
|
||||
<div class="w-full flex">
|
||||
<SearchPeople
|
||||
type="input"
|
||||
@ -112,7 +137,14 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<CircleIconButton icon={mdiClose} title={$t('cancel_search')} onclick={() => (searchFaces = false)} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiClose}
|
||||
aria-label={$t('cancel_search')}
|
||||
onclick={() => (searchFaces = false)}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="px-4 py-4 text-sm">
|
||||
|
@ -11,10 +11,9 @@
|
||||
import { getPeopleThumbnailUrl } from '$lib/utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { updatePeople, type PersonResponseDto } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiClose, mdiEye, mdiEyeOff, mdiEyeSettings, mdiRestart } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
|
||||
interface Props {
|
||||
people: PersonResponseDto[];
|
||||
@ -114,7 +113,14 @@
|
||||
class="fixed top-0 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 title={$t('close')} icon={mdiClose} onclick={onClose} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('close')}
|
||||
icon={mdiClose}
|
||||
onclick={onClose}
|
||||
/>
|
||||
<div class="flex gap-2 items-center">
|
||||
<p id={titleId} class="ms-2">{$t('show_and_hide_people')}</p>
|
||||
<p class="text-sm text-gray-400 dark:text-gray-600">({totalPeopleCount.toLocaleString($locale)})</p>
|
||||
@ -122,8 +128,22 @@
|
||||
</div>
|
||||
<div class="flex items-center justify-end">
|
||||
<div class="flex items-center md:me-4">
|
||||
<CircleIconButton title={$t('reset_people_visibility')} icon={mdiRestart} onclick={handleResetVisibility} />
|
||||
<CircleIconButton title={toggleButton.label} icon={toggleButton.icon} onclick={handleToggleVisibility} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('reset_people_visibility')}
|
||||
icon={mdiRestart}
|
||||
onclick={handleResetVisibility}
|
||||
/>
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={toggleButton.label}
|
||||
icon={toggleButton.icon}
|
||||
onclick={handleToggleVisibility}
|
||||
/>
|
||||
</div>
|
||||
<Button loading={showLoadingSpinner} onclick={handleSaveVisibility} size="small">{$t('done')}</Button>
|
||||
</div>
|
||||
|
@ -6,14 +6,13 @@
|
||||
import { modalManager } from '$lib/managers/modal-manager.svelte';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { getAllPeople, getPerson, mergePerson, type PersonResponseDto } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiCallMerge, mdiMerge, mdiSwapHorizontal } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { flip } from 'svelte/animate';
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import ControlAppBar from '../shared-components/control-app-bar.svelte';
|
||||
import { NotificationType, notificationController } from '../shared-components/notification/notification';
|
||||
import FaceThumbnail from './face-thumbnail.svelte';
|
||||
@ -133,10 +132,13 @@
|
||||
</div>
|
||||
{#if selectedPeople.length === 1}
|
||||
<div class="absolute bottom-2">
|
||||
<CircleIconButton
|
||||
title={$t('swap_merge_direction')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('swap_merge_direction')}
|
||||
icon={mdiSwapHorizontal}
|
||||
size="24"
|
||||
size="large"
|
||||
onclick={handleSwapPeople}
|
||||
/>
|
||||
</div>
|
||||
|
@ -4,6 +4,7 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import FaceThumbnail from './face-thumbnail.svelte';
|
||||
import { mdiSwapVertical } from '@mdi/js';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
screenHeight: number;
|
||||
@ -31,15 +32,17 @@
|
||||
</div>
|
||||
|
||||
{#if handleSearch}
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiSwapVertical}
|
||||
onclick={() => {
|
||||
sortBySimilarirty = !sortBySimilarirty;
|
||||
handleSearch(sortBySimilarirty);
|
||||
}}
|
||||
color="neutral"
|
||||
title={$t('sort_people_by_similarity')}
|
||||
></CircleIconButton>
|
||||
aria-label={$t('sort_people_by_similarity')}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
||||
import { NotificationType, notificationController } from '../shared-components/notification/notification';
|
||||
import AssignFaceSidePanel from './assign-face-side-panel.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
assetId: string;
|
||||
@ -196,7 +197,14 @@
|
||||
>
|
||||
<div class="flex place-items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<CircleIconButton icon={mdiArrowLeftThin} title={$t('back')} onclick={onClose} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiArrowLeftThin}
|
||||
aria-label={$t('back')}
|
||||
onclick={onClose}
|
||||
/>
|
||||
<p class="flex text-lg text-immich-fg dark:text-immich-dark-fg">{$t('edit_faces')}</p>
|
||||
</div>
|
||||
{#if !isShowLoadingDone}
|
||||
@ -303,22 +311,22 @@
|
||||
|
||||
<div class="absolute -end-[5px] -top-[5px] h-[20px] w-[20px] rounded-full">
|
||||
{#if selectedPersonToCreate[face.id] || selectedPersonToReassign[face.id]}
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="primary"
|
||||
icon={mdiRestart}
|
||||
title={$t('reset')}
|
||||
size="18"
|
||||
padding="1"
|
||||
aria-label={$t('reset')}
|
||||
size="medium"
|
||||
class="absolute start-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform"
|
||||
onclick={() => handleReset(face.id)}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
color="primary"
|
||||
icon={mdiPencil}
|
||||
title={$t('select_new_face')}
|
||||
size="18"
|
||||
padding="1"
|
||||
aria-label={$t('select_new_face')}
|
||||
size="medium"
|
||||
class="absolute start-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform"
|
||||
onclick={() => handleFacePicker(face)}
|
||||
/>
|
||||
@ -335,12 +343,12 @@
|
||||
</div>
|
||||
{#if face.person != null}
|
||||
<div class="absolute -end-[5px] top-[25px] h-[20px] w-[20px] rounded-full">
|
||||
<CircleIconButton
|
||||
color="red"
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="danger"
|
||||
icon={mdiTrashCan}
|
||||
title={$t('delete_face')}
|
||||
size="18"
|
||||
padding="1"
|
||||
aria-label={$t('delete_face')}
|
||||
size="medium"
|
||||
class="absolute start-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform"
|
||||
onclick={() => deleteAssetFace(face)}
|
||||
/>
|
||||
|
@ -2,7 +2,7 @@
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { ValidateLibraryImportPathResponseDto } from '@immich/sdk';
|
||||
import { validate, type LibraryResponseDto } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiAlertOutline, mdiCheckCircleOutline, mdiPencilOutline, mdiRefresh } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -198,11 +198,12 @@
|
||||
|
||||
<td class="w-4/5 text-ellipsis px-4 text-sm">{validatedPath.importPath}</td>
|
||||
<td class="w-1/5 text-ellipsis flex justify-center">
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="primary"
|
||||
icon={mdiPencilOutline}
|
||||
title={$t('edit_import_path')}
|
||||
size="16"
|
||||
aria-label={$t('edit_import_path')}
|
||||
size="small"
|
||||
onclick={() => {
|
||||
editImportPath = listIndex;
|
||||
editedImportPath = validatedPath.importPath;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { type LibraryResponseDto } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiPencilOutline } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -130,11 +130,12 @@
|
||||
>
|
||||
<td class="w-3/4 text-ellipsis px-4 text-sm">{exclusionPattern}</td>
|
||||
<td class="w-1/4 text-ellipsis flex justify-center">
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="primary"
|
||||
icon={mdiPencilOutline}
|
||||
title={$t('edit_exclusion_pattern')}
|
||||
size="16"
|
||||
aria-label={$t('edit_exclusion_pattern')}
|
||||
size="small"
|
||||
onclick={() => {
|
||||
editExclusionPattern = listIndex;
|
||||
editedExclusionPattern = exclusionPattern;
|
||||
|
@ -2,6 +2,7 @@
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
|
||||
import { copyToClipboard } from '$lib/utils';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiCodeTags, mdiContentCopy, mdiMessage, mdiPartyPopper } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -40,10 +41,11 @@
|
||||
🚨 {$t('error_title')}
|
||||
</h1>
|
||||
<div class="flex justify-end">
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="primary"
|
||||
icon={mdiContentCopy}
|
||||
title={$t('copy_error')}
|
||||
aria-label={$t('copy_error')}
|
||||
onclick={() => handleCopy()}
|
||||
/>
|
||||
</div>
|
||||
|
@ -320,7 +320,14 @@
|
||||
clearSelect={() => cancelMultiselect(assetInteraction)}
|
||||
>
|
||||
<CreateSharedLink />
|
||||
<CircleIconButton title={$t('select_all')} icon={mdiSelectAll} onclick={handleSelectAll} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('select_all')}
|
||||
icon={mdiSelectAll}
|
||||
onclick={handleSelectAll}
|
||||
/>
|
||||
|
||||
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
||||
<AddToAlbum />
|
||||
@ -361,8 +368,11 @@
|
||||
{/snippet}
|
||||
|
||||
<div class="flex place-content-center place-items-center gap-2 overflow-hidden">
|
||||
<CircleIconButton
|
||||
title={paused ? $t('play_memories') : $t('pause_memories')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={paused ? $t('play_memories') : $t('pause_memories')}
|
||||
icon={paused ? mdiPlay : mdiPause}
|
||||
onclick={() => handlePromiseError(handleAction('PlayPauseButtonClick', paused ? 'play' : 'pause'))}
|
||||
class="hover:text-black"
|
||||
@ -380,8 +390,11 @@
|
||||
{(current.assetIndex + 1).toLocaleString($locale)}/{current.memory.assets.length.toLocaleString($locale)}
|
||||
</p>
|
||||
</div>
|
||||
<CircleIconButton
|
||||
title={$videoViewerMuted ? $t('unmute_memories') : $t('mute_memories')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$videoViewerMuted ? $t('unmute_memories') : $t('mute_memories')}
|
||||
icon={$videoViewerMuted ? mdiVolumeOff : mdiVolumeHigh}
|
||||
onclick={() => ($videoViewerMuted = !$videoViewerMuted)}
|
||||
/>
|
||||
@ -399,7 +412,14 @@
|
||||
onclick={() => memoryWrapper?.scrollIntoView({ behavior: 'smooth' })}
|
||||
disabled={!galleryInView}
|
||||
>
|
||||
<CircleIconButton title={$t('hide_gallery')} icon={mdiChevronUp} color="light" onclick={() => {}} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('hide_gallery')}
|
||||
icon={mdiChevronUp}
|
||||
onclick={() => {}}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
@ -499,11 +519,10 @@
|
||||
/> -->
|
||||
<ButtonContextMenu
|
||||
icon={mdiDotsVertical}
|
||||
padding="3"
|
||||
title={$t('menu')}
|
||||
onclick={() => handlePromiseError(handleAction('ContextMenuClick', 'pause'))}
|
||||
direction="left"
|
||||
size="20"
|
||||
size="medium"
|
||||
align="bottom-right"
|
||||
class="text-white dark:text-white"
|
||||
>
|
||||
@ -532,10 +551,12 @@
|
||||
<!-- CONTROL BUTTONS -->
|
||||
{#if current.previous}
|
||||
<div class="absolute top-1/2 start-0 ms-4">
|
||||
<CircleIconButton
|
||||
title={$t('previous_memory')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
aria-label={$t('previous_memory')}
|
||||
icon={mdiChevronLeft}
|
||||
color="dark"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
onclick={handlePreviousAsset}
|
||||
/>
|
||||
</div>
|
||||
@ -543,10 +564,12 @@
|
||||
|
||||
{#if current.next}
|
||||
<div class="absolute top-1/2 end-0 me-4">
|
||||
<CircleIconButton
|
||||
title={$t('next_memory')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
aria-label={$t('next_memory')}
|
||||
icon={mdiChevronRight}
|
||||
color="dark"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
onclick={handleNextAsset}
|
||||
/>
|
||||
</div>
|
||||
@ -614,10 +637,12 @@
|
||||
class:opacity-0={galleryInView}
|
||||
class:opacity-100={!galleryInView}
|
||||
>
|
||||
<CircleIconButton
|
||||
title={$t('show_gallery')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('show_gallery')}
|
||||
icon={mdiChevronDown}
|
||||
color="light"
|
||||
onclick={() => memoryGallery?.scrollIntoView({ behavior: 'smooth' })}
|
||||
/>
|
||||
</div>
|
||||
|
@ -6,6 +6,7 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
onArchive?: OnArchive;
|
||||
@ -41,8 +42,15 @@
|
||||
|
||||
{#if !menuItem}
|
||||
{#if loading}
|
||||
<CircleIconButton title={$t('loading')} icon={mdiTimerSand} onclick={() => {}} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('loading')}
|
||||
icon={mdiTimerSand}
|
||||
onclick={() => {}}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton title={text} {icon} onclick={handleArchive} />
|
||||
<IconButton shape="round" color="secondary" variant="ghost" aria-label={text} {icon} onclick={handleArchive} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
@ -6,6 +6,7 @@
|
||||
import { makeSharedLinkUrl } from '$lib/utils';
|
||||
import { mdiShareVariantOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
const { getAssets } = getAssetControlContext();
|
||||
|
||||
@ -20,4 +21,11 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<CircleIconButton title={$t('share')} icon={mdiShareVariantOutline} onclick={handleClick} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('share')}
|
||||
icon={mdiShareVariantOutline}
|
||||
onclick={handleClick}
|
||||
/>
|
||||
|
@ -6,6 +6,7 @@
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import DeleteAssetDialog from '../delete-asset-dialog.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
onAssetDelete: OnDelete;
|
||||
@ -44,9 +45,23 @@
|
||||
{#if menuItem}
|
||||
<MenuOption text={label} icon={mdiDeleteOutline} onClick={handleTrash} />
|
||||
{:else if loading}
|
||||
<CircleIconButton title={$t('loading')} icon={mdiTimerSand} onclick={() => {}} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('loading')}
|
||||
icon={mdiTimerSand}
|
||||
onclick={() => {}}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton title={label} icon={mdiDeleteForeverOutline} onclick={handleTrash} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={label}
|
||||
icon={mdiDeleteForeverOutline}
|
||||
onclick={handleTrash}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if isShowConfirmation}
|
||||
|
@ -8,6 +8,7 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
filename?: string;
|
||||
@ -39,5 +40,12 @@
|
||||
{#if menuItem}
|
||||
<MenuOption text={$t('download')} icon={menuItemIcon} onClick={handleDownloadFiles} />
|
||||
{:else}
|
||||
<CircleIconButton title={$t('download')} icon={mdiCloudDownloadOutline} onclick={handleDownloadFiles} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('download')}
|
||||
icon={mdiCloudDownloadOutline}
|
||||
onclick={handleDownloadFiles}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -10,6 +10,7 @@
|
||||
import { mdiHeartMinusOutline, mdiHeartOutline, mdiTimerSand } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
onFavorite?: OnFavorite;
|
||||
@ -67,8 +68,15 @@
|
||||
|
||||
{#if !menuItem}
|
||||
{#if loading}
|
||||
<CircleIconButton title={$t('loading')} icon={mdiTimerSand} onclick={() => {}} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('loading')}
|
||||
icon={mdiTimerSand}
|
||||
onclick={() => {}}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton title={text} {icon} onclick={handleFavorite} />
|
||||
<IconButton shape="round" color="secondary" variant="ghost" aria-label={text} {icon} onclick={handleFavorite} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
@ -9,6 +9,7 @@
|
||||
import { mdiLinkOff, mdiMotionPlayOutline, mdiTimerSand } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
onLink: OnLink;
|
||||
@ -75,8 +76,15 @@
|
||||
|
||||
{#if !menuItem}
|
||||
{#if loading}
|
||||
<CircleIconButton title={$t('loading')} icon={mdiTimerSand} onclick={() => {}} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('loading')}
|
||||
icon={mdiTimerSand}
|
||||
onclick={() => {}}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton title={text} {icon} onclick={onClick} />
|
||||
<IconButton shape="round" color="secondary" variant="ghost" aria-label={text} {icon} onclick={onClick} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
@ -5,6 +5,7 @@
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { modalManager } from '$lib/managers/modal-manager.svelte';
|
||||
import { getAlbumInfo, removeAssetFromAlbum, type AlbumResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiDeleteOutline, mdiImageRemoveOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
@ -60,5 +61,12 @@
|
||||
{#if menuItem}
|
||||
<MenuOption text={$t('remove_from_album')} icon={mdiImageRemoveOutline} onClick={removeFromAlbum} />
|
||||
{:else}
|
||||
<CircleIconButton title={$t('remove_from_album')} icon={mdiDeleteOutline} onclick={removeFromAlbum} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('remove_from_album')}
|
||||
icon={mdiDeleteOutline}
|
||||
onclick={removeFromAlbum}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -7,6 +7,7 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import { NotificationType, notificationController } from '../../shared-components/notification/notification';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
sharedLink: SharedLinkResponseDto;
|
||||
@ -58,4 +59,11 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<CircleIconButton title={$t('remove_from_shared_link')} onclick={handleRemove} icon={mdiDeleteOutline} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('remove_from_shared_link')}
|
||||
onclick={handleRemove}
|
||||
icon={mdiDeleteOutline}
|
||||
/>
|
||||
|
@ -2,7 +2,7 @@
|
||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { type AssetStore, isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
||||
import { cancelMultiselect, selectAllAssets } from '$lib/utils/asset-utils';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiSelectAll, mdiSelectRemove } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -34,8 +34,11 @@
|
||||
{$isSelectingAllAssets ? $t('unselect_all') : $t('select_all')}
|
||||
</Button>
|
||||
{:else}
|
||||
<CircleIconButton
|
||||
title={$isSelectingAllAssets ? $t('unselect_all') : $t('select_all')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$isSelectingAllAssets ? $t('unselect_all') : $t('select_all')}
|
||||
icon={$isSelectingAllAssets ? mdiSelectRemove : mdiSelectAll}
|
||||
onclick={$isSelectingAllAssets ? handleCancel : handleSelectAll}
|
||||
/>
|
||||
|
@ -3,6 +3,7 @@
|
||||
import { tagAssets } from '$lib/utils/asset-utils';
|
||||
import { mdiTagMultipleOutline, mdiTimerSand } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||
import { getAssetControlContext } from '../asset-select-control-bar.svelte';
|
||||
|
||||
@ -39,9 +40,16 @@
|
||||
|
||||
{#if !menuItem}
|
||||
{#if loading}
|
||||
<CircleIconButton title={$t('loading')} icon={mdiTimerSand} onclick={() => {}} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('loading')}
|
||||
icon={mdiTimerSand}
|
||||
onclick={() => {}}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton title={text} {icon} onclick={handleOpen} />
|
||||
<IconButton shape="round" color="secondary" variant="ghost" aria-label={text} {icon} onclick={handleOpen} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
|
@ -16,13 +16,13 @@
|
||||
import { mdiArrowLeft, mdiFileImagePlusOutline, mdiFolderDownloadOutline, mdiSelectAll } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import AssetViewer from '../asset-viewer/asset-viewer.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 { NotificationType, notificationController } from '../shared-components/notification/notification';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
sharedLink: SharedLinkResponseDto;
|
||||
@ -95,7 +95,14 @@
|
||||
assets={assetInteraction.selectedAssets}
|
||||
clearSelect={() => cancelMultiselect(assetInteraction)}
|
||||
>
|
||||
<CircleIconButton title={$t('select_all')} icon={mdiSelectAll} onclick={handleSelectAll} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('select_all')}
|
||||
icon={mdiSelectAll}
|
||||
onclick={handleSelectAll}
|
||||
/>
|
||||
{#if sharedLink?.allowDownload}
|
||||
<DownloadAction filename="immich-shared.zip" />
|
||||
{/if}
|
||||
@ -111,15 +118,25 @@
|
||||
|
||||
{#snippet trailing()}
|
||||
{#if sharedLink?.allowUpload}
|
||||
<CircleIconButton
|
||||
title={$t('add_photos')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('add_photos')}
|
||||
onclick={() => handleUploadAssets()}
|
||||
icon={mdiFileImagePlusOutline}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if sharedLink?.allowDownload}
|
||||
<CircleIconButton title={$t('download')} onclick={downloadAssets} icon={mdiFolderDownloadOutline} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('download')}
|
||||
onclick={downloadAssets}
|
||||
icon={mdiFolderDownloadOutline}
|
||||
/>
|
||||
{/if}
|
||||
{/snippet}
|
||||
</ControlAppBar>
|
||||
|
@ -29,6 +29,7 @@
|
||||
import { t } from 'svelte-i18n';
|
||||
import type { FormEventHandler } from 'svelte/elements';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
@ -329,7 +330,7 @@
|
||||
class:pointer-events-none={!selectedOption}
|
||||
>
|
||||
{#if selectedOption}
|
||||
<CircleIconButton onclick={onClear} title={$t('clear_value')} icon={mdiClose} size="16" padding="2" />
|
||||
<IconButton shape="round" color="secondary" variant="ghost" onclick={onClear} aria-label={$t('clear_value')} icon={mdiClose} size="small" />
|
||||
{:else if !isOpen}
|
||||
<Icon path={mdiUnfoldMoreHorizontal} ariaHidden={true} />
|
||||
{/if}
|
||||
|
@ -1,10 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { contextMenuNavigation } from '$lib/actions/context-menu-navigation';
|
||||
import { shortcuts } from '$lib/actions/shortcut';
|
||||
import CircleIconButton, {
|
||||
type Color,
|
||||
type Padding,
|
||||
} from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
|
||||
import { languageManager } from '$lib/managers/language-manager.svelte';
|
||||
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
|
||||
@ -14,6 +10,7 @@
|
||||
type Align,
|
||||
} from '$lib/utils/context-menu';
|
||||
import { generateId } from '$lib/utils/generate-id';
|
||||
import { IconButton, type Color, type Size, type Variants } from '@immich/ui';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
@ -30,8 +27,8 @@
|
||||
// TODO change to start vs end
|
||||
direction?: 'left' | 'right';
|
||||
color?: Color;
|
||||
size?: string | undefined;
|
||||
padding?: Padding | undefined;
|
||||
size?: Size | undefined;
|
||||
variant?: Variants | undefined;
|
||||
/**
|
||||
* Additional classes to apply to the button.
|
||||
*/
|
||||
@ -49,9 +46,9 @@
|
||||
title,
|
||||
align = 'top-left',
|
||||
direction = 'right',
|
||||
color = 'transparent',
|
||||
color = 'info',
|
||||
size = undefined,
|
||||
padding = undefined,
|
||||
variant = 'ghost',
|
||||
buttonClass = undefined,
|
||||
hideContent = false,
|
||||
children,
|
||||
@ -161,12 +158,13 @@
|
||||
{...restProps}
|
||||
>
|
||||
<div bind:this={buttonContainer}>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
{color}
|
||||
{icon}
|
||||
{padding}
|
||||
{size}
|
||||
{title}
|
||||
shape="round"
|
||||
{variant}
|
||||
aria-label={title}
|
||||
aria-controls={menuId}
|
||||
aria-expanded={isOpen}
|
||||
aria-haspopup={true}
|
||||
|
@ -2,11 +2,11 @@
|
||||
import { browser } from '$app/environment';
|
||||
|
||||
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
import { onDestroy, onMount, type Snippet } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fly } from 'svelte/transition';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
|
||||
interface Props {
|
||||
showBackButton?: boolean;
|
||||
@ -82,7 +82,16 @@
|
||||
>
|
||||
<div class="flex place-items-center sm:gap-6 justify-self-start dark:text-immich-dark-fg">
|
||||
{#if showBackButton}
|
||||
<CircleIconButton title={$t('close')} onclick={handleClose} icon={backIcon} size="24" class={buttonClass} />
|
||||
<IconButton
|
||||
aria-label={$t('close')}
|
||||
onclick={handleClose}
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
icon={backIcon}
|
||||
size="large"
|
||||
class={buttonClass}
|
||||
/>
|
||||
{/if}
|
||||
{@render leading?.()}
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -36,5 +37,13 @@
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<CircleIconButton onclick={onClose} icon={mdiClose} size="20" title={$t('close')} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onclick={onClose}
|
||||
icon={mdiClose}
|
||||
size="medium"
|
||||
aria-label={$t('close')}
|
||||
/>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
import { modalManager } from '$lib/managers/modal-manager.svelte';
|
||||
import AvatarEditModal from '$lib/modals/AvatarEditModal.svelte';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiCog, mdiLogout, mdiPencil, mdiWrench } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fade } from 'svelte/transition';
|
||||
@ -33,13 +33,12 @@
|
||||
<div class="relative">
|
||||
<UserAvatar user={$user} size="xl" />
|
||||
<div class="absolute bottom-0 end-0 rounded-full w-6 h-6">
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
color="primary"
|
||||
icon={mdiPencil}
|
||||
title={$t('edit_avatar')}
|
||||
class="border"
|
||||
size="12"
|
||||
padding="2"
|
||||
aria-label={$t('edit_avatar')}
|
||||
size="tiny"
|
||||
shape="round"
|
||||
onclick={async () => {
|
||||
onClose();
|
||||
await modalManager.show(AvatarEditModal, {});
|
||||
|
@ -128,7 +128,7 @@
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<ThemeButton padding="2" />
|
||||
<ThemeButton />
|
||||
|
||||
<div>
|
||||
<IconButton
|
||||
@ -163,7 +163,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<CastButton navBar />
|
||||
<CastButton />
|
||||
|
||||
<div
|
||||
use:clickOutside={{
|
||||
|
@ -7,6 +7,7 @@
|
||||
type ComponentNotification,
|
||||
type Notification,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiCloseCircleOutline, mdiInformationOutline, mdiWindowClose } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -87,12 +88,14 @@
|
||||
{:else if notification.type == NotificationType.Info}{$t('info')}{/if}
|
||||
</h2>
|
||||
</div>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
icon={mdiWindowClose}
|
||||
title={$t('close')}
|
||||
aria-label={$t('close')}
|
||||
class="dark:text-immich-dark-gray"
|
||||
size="20"
|
||||
padding="2"
|
||||
size="medium"
|
||||
onclick={discard}
|
||||
aria-hidden={true}
|
||||
tabindex={-1}
|
||||
|
@ -14,6 +14,7 @@
|
||||
import { onDestroy, tick } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import SearchHistoryBox from './search-history-box.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
value?: string;
|
||||
@ -271,7 +272,15 @@
|
||||
</div>
|
||||
|
||||
<div class="absolute inset-y-0 {showClearIcon ? 'end-14' : 'end-2'} flex items-center ps-6 transition-all">
|
||||
<CircleIconButton title={$t('show_search_options')} icon={mdiTune} onclick={onFilterClick} size="20" />
|
||||
<IconButton
|
||||
aria-label={$t('show_search_options')}
|
||||
shape="round"
|
||||
icon={mdiTune}
|
||||
onclick={onFilterClick}
|
||||
size="medium"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isFocus}
|
||||
@ -290,11 +299,28 @@
|
||||
|
||||
{#if showClearIcon}
|
||||
<div class="absolute inset-y-0 end-0 flex items-center pe-2">
|
||||
<CircleIconButton onclick={onClear} icon={mdiClose} title={$t('clear')} size="20" />
|
||||
<IconButton
|
||||
onclick={onClear}
|
||||
icon={mdiClose}
|
||||
aria-label={$t('clear')}
|
||||
size="medium"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="absolute inset-y-0 start-0 flex items-center ps-2">
|
||||
<CircleIconButton type="submit" title={$t('search')} icon={mdiMagnify} size="20" onclick={() => {}} />
|
||||
<IconButton
|
||||
type="submit"
|
||||
aria-label={$t('search')}
|
||||
icon={mdiMagnify}
|
||||
size="medium"
|
||||
onclick={() => {}}
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { searchStore } from '$lib/stores/search.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiClose, mdiMagnify } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fly } from 'svelte/transition';
|
||||
@ -132,11 +133,13 @@
|
||||
{savedSearchTerm}
|
||||
</div>
|
||||
<div aria-hidden={true} class="absolute end-5 top-0 items-center justify-center py-3">
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiClose}
|
||||
title={$t('remove')}
|
||||
size="18"
|
||||
padding="1"
|
||||
aria-label={$t('remove')}
|
||||
size="medium"
|
||||
tabindex={-1}
|
||||
onclick={() => handleClearSingle(savedSearchTerm)}
|
||||
/>
|
||||
|
@ -13,7 +13,7 @@
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { getButtonVisibility } from '$lib/utils/purchase-utils';
|
||||
import { updateMyPreferences } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiClose, mdiInformationOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fade } from 'svelte/transition';
|
||||
@ -129,13 +129,16 @@
|
||||
<div class="h-10 w-10">
|
||||
<ImmichLogo noText class="h-[32px]" />
|
||||
</div>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiClose}
|
||||
onclick={() => {
|
||||
showMessage = false;
|
||||
}}
|
||||
title={$t('close')}
|
||||
size="18"
|
||||
aria-label={$t('close')}
|
||||
size="medium"
|
||||
class="text-immich-dark-gray/85 dark:text-immich-gray"
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,27 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { moonPath, moonViewBox, sunPath, sunViewBox } from '$lib/assets/svg-paths';
|
||||
import CircleIconButton, { type Padding } from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { themeManager } from '$lib/managers/theme-manager.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiWeatherNight, mdiWhiteBalanceSunny } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
let icon = $derived(themeManager.isDark ? sunPath : moonPath);
|
||||
let viewBox = $derived(themeManager.isDark ? sunViewBox : moonViewBox);
|
||||
|
||||
interface Props {
|
||||
padding?: Padding;
|
||||
}
|
||||
|
||||
let { padding = '3' }: Props = $props();
|
||||
let icon = $derived(themeManager.isDark ? mdiWhiteBalanceSunny : mdiWeatherNight);
|
||||
</script>
|
||||
|
||||
{#if !themeManager.theme.system}
|
||||
<CircleIconButton
|
||||
title={$t('toggle_theme')}
|
||||
<IconButton
|
||||
aria-label={$t('toggle_theme')}
|
||||
{icon}
|
||||
{viewBox}
|
||||
role="switch"
|
||||
aria-checked={themeManager.isDark ? 'true' : 'false'}
|
||||
onclick={() => themeManager.toggleTheme()}
|
||||
{padding}
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
/>
|
||||
{/if}
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiArrowUpLeft, mdiChevronRight } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -18,12 +19,14 @@
|
||||
<nav class="flex items-center py-2">
|
||||
{#if !isRoot}
|
||||
<div>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiArrowUpLeft}
|
||||
title={$t('to_parent')}
|
||||
aria-label={$t('to_parent')}
|
||||
href={getLink(pathSegments.slice(0, -1).join('/'))}
|
||||
class="me-2"
|
||||
padding="2"
|
||||
onclick={() => {}}
|
||||
/>
|
||||
</div>
|
||||
@ -34,12 +37,14 @@
|
||||
>
|
||||
<ol class="flex gap-2 items-center">
|
||||
<li>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
{icon}
|
||||
href={getLink('')}
|
||||
{title}
|
||||
size="1.25em"
|
||||
padding="2"
|
||||
aria-label={title}
|
||||
size="medium"
|
||||
aria-current={isRoot ? 'page' : undefined}
|
||||
onclick={() => {}}
|
||||
/>
|
||||
|
@ -3,11 +3,11 @@
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { uploadAssetsStore } from '$lib/stores/upload';
|
||||
import { uploadExecutionQueue } from '$lib/utils/file-uploader';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiCancel, mdiCloudUploadOutline, mdiCog, mdiWindowMinimize } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { quartInOut } from 'svelte/easing';
|
||||
import { fade, scale } from 'svelte/transition';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import { notificationController, NotificationType } from './notification/notification';
|
||||
import UploadAssetPreview from './upload-asset-preview.svelte';
|
||||
|
||||
@ -79,27 +79,33 @@
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<div class="flex flex-row">
|
||||
<CircleIconButton
|
||||
title={$t('toggle_settings')}
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
icon={mdiCog}
|
||||
size="14"
|
||||
padding="1"
|
||||
size="small"
|
||||
onclick={() => (showOptions = !showOptions)}
|
||||
aria-label={$t('toggle_settings')}
|
||||
/>
|
||||
<CircleIconButton
|
||||
title={$t('minimize')}
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
aria-label={$t('minimize')}
|
||||
icon={mdiWindowMinimize}
|
||||
size="14"
|
||||
padding="1"
|
||||
size="small"
|
||||
onclick={() => (showDetail = false)}
|
||||
/>
|
||||
</div>
|
||||
{#if $isDismissible}
|
||||
<CircleIconButton
|
||||
title={$t('dismiss_all_errors')}
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
aria-label={$t('dismiss_all_errors')}
|
||||
icon={mdiCancel}
|
||||
size="14"
|
||||
padding="1"
|
||||
size="small"
|
||||
onclick={() => uploadAssetsStore.dismissErrors()}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -2,6 +2,7 @@
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
import { copyToClipboard, makeSharedLinkUrl } from '$lib/utils';
|
||||
import type { SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiContentCopy } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -20,5 +21,12 @@
|
||||
{#if menuItem}
|
||||
<MenuOption text={$t('copy_link')} icon={mdiContentCopy} onClick={handleCopy} />
|
||||
{:else}
|
||||
<CircleIconButton title={$t('copy_link')} icon={mdiContentCopy} onclick={handleCopy} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
aria-label={$t('copy_link')}
|
||||
icon={mdiContentCopy}
|
||||
onclick={handleCopy}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiDelete } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -14,5 +15,12 @@
|
||||
{#if menuItem}
|
||||
<MenuOption text={$t('delete_link')} icon={mdiDelete} onClick={onDelete} />
|
||||
{:else}
|
||||
<CircleIconButton title={$t('delete_link')} icon={mdiDelete} onclick={onDelete} />
|
||||
<IconButton
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
aria-label={$t('delete_link')}
|
||||
icon={mdiDelete}
|
||||
onclick={onDelete}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -3,6 +3,7 @@
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import type { SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiCircleEditOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@ -21,5 +22,12 @@
|
||||
{#if menuItem}
|
||||
<MenuOption text={$t('edit_link')} icon={mdiCircleEditOutline} onClick={onEdit} />
|
||||
{:else}
|
||||
<CircleIconButton title={$t('edit_link')} icon={mdiCircleEditOutline} onclick={onEdit} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('edit_link')}
|
||||
icon={mdiCircleEditOutline}
|
||||
onclick={onEdit}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -2,6 +2,7 @@
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import type { SessionResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import {
|
||||
mdiAndroid,
|
||||
mdiApple,
|
||||
@ -74,11 +75,13 @@
|
||||
</div>
|
||||
{#if !device.current && onDelete}
|
||||
<div>
|
||||
<CircleIconButton
|
||||
color="primary"
|
||||
<IconButton
|
||||
color="danger"
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
icon={mdiTrashCanOutline}
|
||||
title={$t('log_out')}
|
||||
size="16"
|
||||
aria-label={$t('log_out')}
|
||||
size="small"
|
||||
onclick={onDelete}
|
||||
/>
|
||||
</div>
|
||||
|
@ -12,12 +12,11 @@
|
||||
type PartnerResponseDto,
|
||||
type UserResponseDto,
|
||||
} from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiCheck, mdiClose } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { handleError } from '../../utils/handle-error';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import Icon from '../elements/icon.svelte';
|
||||
|
||||
interface PartnerSharing {
|
||||
@ -144,11 +143,14 @@
|
||||
</div>
|
||||
|
||||
{#if partner.sharedByMe}
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onclick={() => handleRemovePartner(partner.user)}
|
||||
icon={mdiClose}
|
||||
size="16"
|
||||
title={$t('stop_sharing_photos_with_user')}
|
||||
size="small"
|
||||
aria-label={$t('stop_sharing_photos_with_user')}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@
|
||||
updateApiKey,
|
||||
type ApiKeyResponseDto,
|
||||
} from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { fade } from 'svelte/transition';
|
||||
@ -127,18 +127,20 @@
|
||||
>{new Date(key.createdAt).toLocaleDateString($locale, dateFormats.settings)}
|
||||
</td>
|
||||
<td class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-1/3">
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="primary"
|
||||
icon={mdiPencilOutline}
|
||||
title={$t('edit_key')}
|
||||
size="16"
|
||||
aria-label={$t('edit_key')}
|
||||
size="small"
|
||||
onclick={() => handleUpdate(key)}
|
||||
/>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="primary"
|
||||
icon={mdiTrashCanOutline}
|
||||
title={$t('delete_key')}
|
||||
size="16"
|
||||
aria-label={$t('delete_key')}
|
||||
size="small"
|
||||
onclick={() => handleDelete(key)}
|
||||
/>
|
||||
</td>
|
||||
|
@ -7,12 +7,11 @@
|
||||
import { getPeopleThumbnailUrl } from '$lib/utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { mergePerson, type PersonResponseDto } from '@immich/sdk';
|
||||
import { Button, Modal, ModalBody, ModalFooter } from '@immich/ui';
|
||||
import { Button, IconButton, Modal, ModalBody, ModalFooter } from '@immich/ui';
|
||||
import { mdiArrowLeft, mdiMerge } from '@mdi/js';
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import ImageThumbnail from '../components/assets/thumbnail/image-thumbnail.svelte';
|
||||
import CircleIconButton from '../components/elements/buttons/circle-icon-button.svelte';
|
||||
|
||||
interface Props {
|
||||
personToMerge: PersonResponseDto;
|
||||
@ -75,8 +74,11 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="mx-0.5 flex md:mx-2">
|
||||
<CircleIconButton
|
||||
title={$t('swap_merge_direction')}
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('swap_merge_direction')}
|
||||
icon={mdiMerge}
|
||||
onclick={() => ([personToMerge, personToBeMergedInto] = [personToBeMergedInto, personToMerge])}
|
||||
/>
|
||||
|
@ -68,7 +68,7 @@
|
||||
updateAlbumInfo,
|
||||
type AlbumUserAddDto,
|
||||
} from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import {
|
||||
mdiArrowLeft,
|
||||
mdiCogOutline,
|
||||
@ -492,10 +492,11 @@
|
||||
<div class="my-3 flex gap-x-1">
|
||||
<!-- link -->
|
||||
{#if album.hasSharedLink && isOwned}
|
||||
<CircleIconButton
|
||||
title={$t('create_link_to_share')}
|
||||
color="gray"
|
||||
size="20"
|
||||
<IconButton
|
||||
aria-label={$t('create_link_to_share')}
|
||||
color="secondary"
|
||||
size="medium"
|
||||
shape="round"
|
||||
icon={mdiLink}
|
||||
onclick={handleShareLink}
|
||||
/>
|
||||
@ -515,22 +516,24 @@
|
||||
|
||||
<!-- display ellipsis if there are readonly users too -->
|
||||
{#if albumHasViewers}
|
||||
<CircleIconButton
|
||||
title={$t('view_all_users')}
|
||||
color="gray"
|
||||
size="20"
|
||||
<IconButton
|
||||
shape="round"
|
||||
aria-label={$t('view_all_users')}
|
||||
color="secondary"
|
||||
size="medium"
|
||||
icon={mdiDotsVertical}
|
||||
onclick={handleEditUsers}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if isOwned}
|
||||
<CircleIconButton
|
||||
color="gray"
|
||||
size="20"
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
size="medium"
|
||||
icon={mdiPlus}
|
||||
onclick={handleShare}
|
||||
title={$t('add_more_users')}
|
||||
aria-label={$t('add_more_users')}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
@ -627,11 +630,14 @@
|
||||
{#if viewMode === AlbumPageViewMode.VIEW}
|
||||
<ControlAppBar showBackButton backIcon={mdiArrowLeft} onClose={() => goto(backUrl)}>
|
||||
{#snippet trailing()}
|
||||
<CastButton whiteHover />
|
||||
<CastButton />
|
||||
|
||||
{#if isEditor}
|
||||
<CircleIconButton
|
||||
title={$t('add_photos')}
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="secondary"
|
||||
aria-label={$t('add_photos')}
|
||||
onclick={async () => {
|
||||
assetStore.suspendTransitions = true;
|
||||
viewMode = AlbumPageViewMode.SELECT_ASSETS;
|
||||
@ -646,18 +652,44 @@
|
||||
{/if}
|
||||
|
||||
{#if isOwned}
|
||||
<CircleIconButton title={$t('share')} onclick={handleShare} icon={mdiShareVariantOutline} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('share')}
|
||||
onclick={handleShare}
|
||||
icon={mdiShareVariantOutline}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<AlbumMap {album} />
|
||||
|
||||
{#if album.assetCount > 0}
|
||||
<CircleIconButton title={$t('slideshow')} onclick={handleStartSlideshow} icon={mdiPresentationPlay} />
|
||||
<CircleIconButton title={$t('download')} onclick={handleDownloadAlbum} icon={mdiFolderDownloadOutline} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('slideshow')}
|
||||
onclick={handleStartSlideshow}
|
||||
icon={mdiPresentationPlay}
|
||||
/>
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('download')}
|
||||
onclick={handleDownloadAlbum}
|
||||
icon={mdiFolderDownloadOutline}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if isOwned}
|
||||
<ButtonContextMenu icon={mdiDotsVertical} title={$t('album_options')} offset={{ x: 175, y: 25 }}>
|
||||
<ButtonContextMenu
|
||||
icon={mdiDotsVertical}
|
||||
title={$t('album_options')}
|
||||
color="secondary"
|
||||
offset={{ x: 175, y: 25 }}
|
||||
>
|
||||
{#if album.assetCount > 0}
|
||||
<MenuOption
|
||||
icon={mdiImageOutline}
|
||||
|
@ -29,6 +29,7 @@
|
||||
import { cancelMultiselect } from '$lib/utils/asset-utils';
|
||||
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
||||
import { buildTree, normalizeTreePath } from '$lib/utils/tree-utils';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiDotsVertical, mdiFolder, mdiFolderHome, mdiFolderOutline, mdiPlus, mdiSelectAll } from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -134,7 +135,14 @@
|
||||
clearSelect={() => cancelMultiselect(assetInteraction)}
|
||||
>
|
||||
<CreateSharedLink />
|
||||
<CircleIconButton title={$t('select_all')} icon={mdiSelectAll} onclick={handleSelectAllAssets} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('select_all')}
|
||||
icon={mdiSelectAll}
|
||||
onclick={handleSelectAllAssets}
|
||||
/>
|
||||
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
||||
<AddToAlbum onAddToAlbum={() => cancelMultiselect(assetInteraction)} />
|
||||
<AddToAlbum onAddToAlbum={() => cancelMultiselect(assetInteraction)} shared />
|
||||
|
@ -44,6 +44,7 @@
|
||||
searchSmart,
|
||||
type SmartSearchDto,
|
||||
} from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiArrowLeft, mdiDotsVertical, mdiImageOffOutline, mdiPlus, mdiSelectAll } from '@mdi/js';
|
||||
import { tick } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
@ -268,7 +269,14 @@
|
||||
clearSelect={() => cancelMultiselect(assetInteraction)}
|
||||
>
|
||||
<CreateSharedLink />
|
||||
<CircleIconButton title={$t('select_all')} icon={mdiSelectAll} onclick={handleSelectAll} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('select_all')}
|
||||
icon={mdiSelectAll}
|
||||
onclick={handleSelectAll}
|
||||
/>
|
||||
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
||||
<AddToAlbum {onAddToAlbum} />
|
||||
<AddToAlbum shared {onAddToAlbum} />
|
||||
@ -400,7 +408,14 @@
|
||||
clearSelect={() => cancelMultiselect(assetInteraction)}
|
||||
>
|
||||
<CreateSharedLink />
|
||||
<CircleIconButton title={$t('select_all')} icon={mdiSelectAll} onclick={handleSelectAll} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$t('select_all')}
|
||||
icon={mdiSelectAll}
|
||||
onclick={handleSelectAll}
|
||||
/>
|
||||
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
||||
<AddToAlbum {onAddToAlbum} />
|
||||
<AddToAlbum shared {onAddToAlbum} />
|
||||
|
@ -3,7 +3,7 @@
|
||||
import UserSettingsList from '$lib/components/user-settings-page/user-settings-list.svelte';
|
||||
import { modalManager } from '$lib/managers/modal-manager.svelte';
|
||||
import ShortcutsModal from '$lib/modals/ShortcutsModal.svelte';
|
||||
import { Container } from '@immich/ui';
|
||||
import { Container, IconButton } from '@immich/ui';
|
||||
import { mdiKeyboard } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
import type { PageData } from './$types';
|
||||
@ -17,9 +17,12 @@
|
||||
|
||||
<UserPageLayout title={data.meta.title}>
|
||||
{#snippet buttons()}
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiKeyboard}
|
||||
title={$t('show_keyboard_shortcuts')}
|
||||
aria-label={$t('show_keyboard_shortcuts')}
|
||||
onclick={() => modalManager.show(ShortcutsModal, {})}
|
||||
/>
|
||||
{/snippet}
|
||||
|
@ -193,11 +193,13 @@
|
||||
<div class="text-sm dark:text-white">
|
||||
<p>{$t('duplicates_description')}</p>
|
||||
</div>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
icon={mdiInformationOutline}
|
||||
title={$t('deduplication_info')}
|
||||
size="16"
|
||||
padding="2"
|
||||
aria-label={$t('deduplication_info')}
|
||||
size="small"
|
||||
onclick={() => modalManager.show(DuplicatesInformationModal, {})}
|
||||
/>
|
||||
</div>
|
||||
|
@ -314,9 +314,10 @@
|
||||
align="top-right"
|
||||
direction="left"
|
||||
color="primary"
|
||||
size="16"
|
||||
size="medium"
|
||||
icon={mdiDotsVertical}
|
||||
title={$t('library_options')}
|
||||
variant="filled"
|
||||
>
|
||||
<MenuOption onClick={() => onScanClicked(library)} text={$t('scan_library')} />
|
||||
<hr />
|
||||
|
Loading…
x
Reference in New Issue
Block a user