refactor(web): use declaration tags instead of @const (#32639)
(cherry picked from commit c6d1e15c77c5f3786b26b292def27247b258cde5)
This commit is contained in:
@@ -164,6 +164,7 @@ export default defineConfig(
|
||||
'@typescript-eslint/switch-exhaustiveness-check': ['error', { considerDefaultExhaustiveForUnions: true }],
|
||||
'svelte/button-has-type': 'error',
|
||||
'object-shorthand': ['error', 'always'],
|
||||
'svelte/no-at-const-tags': 'error',
|
||||
'svelte/no-navigation-without-resolve': 'off',
|
||||
'unicorn/prefer-early-return': 'off',
|
||||
'unicorn/prefer-ternary': 'off',
|
||||
|
||||
+2
-2
@@ -36,8 +36,8 @@
|
||||
"@photo-sphere-viewer/resolution-plugin": "^5.14.0",
|
||||
"@photo-sphere-viewer/settings-plugin": "^5.14.0",
|
||||
"@photo-sphere-viewer/video-plugin": "^5.14.0",
|
||||
"@tanstack/svelte-query": "^6.3.2",
|
||||
"@simplewebauthn/browser": "14.0.0",
|
||||
"@tanstack/svelte-query": "^6.3.2",
|
||||
"@types/geojson": "^7946.0.16",
|
||||
"@zoom-image/core": "^0.43.0",
|
||||
"@zoom-image/svelte": "^0.3.0",
|
||||
@@ -101,7 +101,7 @@
|
||||
"eslint-plugin-better-tailwindcss": "^4.5.0",
|
||||
"eslint-plugin-compat": "^7.0.0",
|
||||
"eslint-plugin-prettier": "^5.5.6",
|
||||
"eslint-plugin-svelte": "^3.12.4",
|
||||
"eslint-plugin-svelte": "^3.23.1",
|
||||
"eslint-plugin-unicorn": "^75.0.0",
|
||||
"factory.ts": "^1.4.1",
|
||||
"globals": "^17.0.0",
|
||||
|
||||
@@ -70,9 +70,11 @@
|
||||
</div>
|
||||
|
||||
{#each data.series as day, idx (day.date)}
|
||||
{@const date = DateTime.fromISO(day.date, { zone: 'utc' }).toLocaleString(
|
||||
{ month: 'short', day: 'numeric' },
|
||||
{ locale: $locale },
|
||||
{const date = $derived(
|
||||
DateTime.fromISO(day.date, { zone: 'utc' }).toLocaleString(
|
||||
{ month: 'short', day: 'numeric' },
|
||||
{ locale: $locale },
|
||||
),
|
||||
)}
|
||||
<div
|
||||
class="aspect-square size-full rounded-sm {itemColors(day.count)} row-start-(--heatmap-row-start)"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
{@render button()}
|
||||
</div>
|
||||
{:else}
|
||||
{@const albumId = albumIds[0]}
|
||||
{const albumId = $derived(albumIds[0])}
|
||||
{#if albumId}
|
||||
<AlbumThumbnail {albumId} onDelete={() => (albumIds = [])} />
|
||||
{:else}
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<Select options={schema.enum} bind:value={getString, setValue} />
|
||||
</Field>
|
||||
{:else if schema.array}
|
||||
{@const values = getValue<string[]>([])}
|
||||
{const values = $derived(getValue<string[]>([]))}
|
||||
<Field {label} {description}>
|
||||
<Input value={values.join(',')} disabled />
|
||||
<HelperText>{$t('unsupported_field_type')}</HelperText>
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
preload = false,
|
||||
contextMenuItems,
|
||||
}: Props = $props();
|
||||
|
||||
const owner = $derived(album.albumUsers[0].user);
|
||||
</script>
|
||||
|
||||
<div
|
||||
@@ -74,7 +76,6 @@
|
||||
{/if}
|
||||
|
||||
{#if showOwner}
|
||||
{@const owner = album.albumUsers[0].user}
|
||||
{#if owner.id === authManager.user.id}
|
||||
<p>{$t('owned')}</p>
|
||||
{:else}
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
{#if !isCollapsed}
|
||||
<div class="grid grid-auto-fill-56 gap-y-4" transition:slide={{ duration: 300 }}>
|
||||
{#each albums as album, index (album.id)}
|
||||
{@const { Edit, Share, Download, Leave, Delete } = getAlbumActions($t, album)}
|
||||
{@const items = [Edit, Share, Download, Leave, Delete]}
|
||||
{const { Edit, Share, Download, Leave, Delete } = $derived(getAlbumActions($t, album))}
|
||||
{const items = $derived([Edit, Share, Download, Leave, Delete])}
|
||||
<a
|
||||
href={Route.viewAlbum(album)}
|
||||
class="h-fit"
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
</tbody>
|
||||
{:else}
|
||||
{#each groupedAlbums as albumGroup (albumGroup.id)}
|
||||
{@const isCollapsed = isAlbumGroupCollapsed($albumViewSettings, albumGroup.id)}
|
||||
{@const iconRotation = isCollapsed ? 'rotate-0' : 'rotate-90'}
|
||||
{const isCollapsed = $derived(isAlbumGroupCollapsed($albumViewSettings, albumGroup.id))}
|
||||
{const iconRotation = $derived(isCollapsed ? 'rotate-0' : 'rotate-90')}
|
||||
<tbody
|
||||
class="mt-4 block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray dark:text-immich-dark-fg"
|
||||
>
|
||||
|
||||
@@ -649,10 +649,9 @@
|
||||
{/if}
|
||||
|
||||
{#if stack && withStacked && !assetViewerManager.isShowEditor && $slideshowState === SlideshowState.None}
|
||||
{@const stackedAssets = stack.assets}
|
||||
<div id="stack-slideshow" class="absolute bottom-0 col-span-4 col-start-1 w-fit max-w-full">
|
||||
<div class="no-wrap horizontal-scrollbar relative flex flex-row overflow-x-auto overflow-y-hidden">
|
||||
{#each stackedAssets as stackedAsset (stackedAsset.id)}
|
||||
{#each stack.assets as stackedAsset (stackedAsset.id)}
|
||||
<div
|
||||
class={['relative inline-block px-1 pb-2 transition-all']}
|
||||
style:bottom={stackedAsset.id === asset.id ? '0' : '-10px'}
|
||||
|
||||
@@ -142,11 +142,11 @@
|
||||
<ActionMenuItem action={StackActions.RemoveAsset} />
|
||||
|
||||
{#if album}
|
||||
{@const { SetCover } = getAlbumAssetActions($t, album, asset)}
|
||||
{const { SetCover } = $derived(getAlbumAssetActions($t, album, asset))}
|
||||
<ActionMenuItem action={SetCover} />
|
||||
{/if}
|
||||
{#if person}
|
||||
{@const { SetFeaturedPhoto } = getPersonAssetActions($t, person, asset)}
|
||||
{const { SetFeaturedPhoto } = $derived(getPersonAssetActions($t, person, asset))}
|
||||
<ActionMenuItem action={SetFeaturedPhoto} />
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
{getMegapixel(asset.exifInfo.exifImageHeight, asset.exifInfo.exifImageWidth)} MP
|
||||
</p>
|
||||
{/if}
|
||||
{@const { width, height } = getDimensions(asset.exifInfo)}
|
||||
{const { width, height } = $derived(getDimensions(asset.exifInfo))}
|
||||
<p>{width} × {height}</p>
|
||||
{/if}
|
||||
{#if asset.exifInfo?.fileSizeInByte}
|
||||
@@ -295,8 +295,8 @@
|
||||
onOpenInMapView={() => goto(Route.map({ ...latlng, zoom: 12.5 }))}
|
||||
>
|
||||
{#snippet popup({ marker })}
|
||||
{@const { lat, lon } = marker}
|
||||
<div class="flex flex-col items-center gap-1">
|
||||
{const { lat, lon } = $derived(marker)}
|
||||
<Text fontWeight="bold">{lat.toPrecision(6)}, {lon.toPrecision(6)}</Text>
|
||||
<Link
|
||||
href="https://www.openstreetmap.org/?mlat={lat}&mlon={lon}&zoom=13#map=15/{lat}/{lon}"
|
||||
|
||||
@@ -103,8 +103,10 @@
|
||||
|
||||
<div class="mt-2 grid {visiblePeople.length <= 6 ? 'grid-cols-3 gap-3' : 'grid-cols-4 gap-2'}">
|
||||
{#each visiblePeople as person (person.id)}
|
||||
{@const personFaces = faceManager.facesByPersonId.get(person.id) ?? []}
|
||||
{@const isHighlighted = personFaces.some((f) => assetViewerManager.highlightedFaces.some((b) => b.id === f.id))}
|
||||
{const personFaces = $derived(faceManager.facesByPersonId.get(person.id) ?? [])}
|
||||
{const isHighlighted = $derived(
|
||||
personFaces.some((f) => assetViewerManager.highlightedFaces.some((b) => b.id === f.id)),
|
||||
)}
|
||||
<a
|
||||
class="group outline-none"
|
||||
href={Route.viewPerson(person, { previousRoute })}
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
</svg>
|
||||
</div>
|
||||
{#each boundingBoxes as boundingbox (boundingbox.id)}
|
||||
{@const isActive = assetViewerManager.highlightedFaces.some((f) => f.id === boundingbox.id)}
|
||||
{const isActive = $derived(assetViewerManager.highlightedFaces.some((f) => f.id === boundingbox.id))}
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div
|
||||
class="pointer-events-auto absolute rounded-lg {isActive && 'border-3 border-solid border-white'}"
|
||||
@@ -274,9 +274,10 @@
|
||||
onpointerleave={() => assetViewerManager.clearHighlightedFaces()}
|
||||
>
|
||||
{#if isActive && boundingbox.name}
|
||||
{@const labelAbove =
|
||||
{const labelAbove = $derived(
|
||||
boundingbox.top + boundingbox.height + faceLabelOffset > overlaySize.height &&
|
||||
boundingbox.top >= faceLabelOffset}
|
||||
boundingbox.top >= faceLabelOffset,
|
||||
)}
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="absolute rounded-sm bg-white/90 px-2 py-1 text-sm font-medium whitespace-nowrap text-black shadow-lg"
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
></div>
|
||||
|
||||
{#each edges as edge (edge)}
|
||||
{@const rotatedEdge = rotateBoundary(edges, edge, transformManager.normalizedRotation / 90)}
|
||||
{const rotatedEdge = $derived(rotateBoundary(edges, edge, transformManager.normalizedRotation / 90))}
|
||||
<button
|
||||
class={['absolute', edge]}
|
||||
style={`${edge}: -10px`}
|
||||
@@ -104,7 +104,7 @@
|
||||
{/each}
|
||||
|
||||
{#each corners as corner (corner)}
|
||||
{@const rotatedCorner = rotateBoundary(corners, corner, transformManager.normalizedRotation / 90)}
|
||||
{const rotatedCorner = $derived(rotateBoundary(corners, corner, transformManager.normalizedRotation / 90))}
|
||||
<button
|
||||
class={['corner', corner]}
|
||||
onmousedown={(e) => transformManager.handleMouseDownOn(e, corner)}
|
||||
|
||||
@@ -238,8 +238,8 @@
|
||||
</div>
|
||||
{:else}
|
||||
{#each peopleWithFaces as face, index (face.id)}
|
||||
{@const personName = face.person ? face.person.name : $t('face_unassigned')}
|
||||
{@const isHighlighted = assetViewerManager.highlightedFaces.some((b) => b.id === face.id)}
|
||||
{const personName = face.person ? face.person.name : $t('face_unassigned')}
|
||||
{const isHighlighted = $derived(assetViewerManager.highlightedFaces.some((b) => b.id === face.id))}
|
||||
<div class="relative h-29 w-24">
|
||||
<div
|
||||
role="button"
|
||||
|
||||
@@ -348,8 +348,8 @@
|
||||
>
|
||||
{#each assets as asset, index (asset.id + '-' + index)}
|
||||
{#if isInOrNearViewport(index)}
|
||||
{@const currentAsset = toTimelineAsset(asset)}
|
||||
<div class="absolute" style:overflow="clip" style={getStyle(index)}>
|
||||
{const currentAsset = toTimelineAsset(asset)}
|
||||
<Thumbnail
|
||||
readonly={disableAssetSelect}
|
||||
onClick={() => {
|
||||
|
||||
@@ -100,9 +100,9 @@
|
||||
</div>
|
||||
|
||||
{#each filteredSearchTerms as savedSearchTerm, i (i)}
|
||||
{@const index = showClearAll ? i + 1 : i}
|
||||
<div class="flex w-full items-center justify-between text-black dark:text-gray-300">
|
||||
<div class="relative w-full items-center">
|
||||
{const index = $derived(showClearAll ? i + 1 : i)}
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
id={getId(index)}
|
||||
|
||||
@@ -46,14 +46,14 @@
|
||||
</div>
|
||||
{:then people}
|
||||
{#if people && people.length > 0}
|
||||
{@const peopleList = showAllPeople
|
||||
? filterPeople(people, name)
|
||||
: filterPeople(people, name).slice(0, numberOfPeople)}
|
||||
|
||||
<div id="people-selection" class="max-h-80 immich-scrollbar overflow-y-auto">
|
||||
<Text class="pb-5">{$t('people_search_description')}</Text>
|
||||
<SearchBar bind:name placeholder={$t('filter_people')} showLoadingSpinner={false} />
|
||||
|
||||
{const peopleList = $derived(
|
||||
showAllPeople ? filterPeople(people, name) : filterPeople(people, name).slice(0, numberOfPeople),
|
||||
)}
|
||||
|
||||
<SingleGridRow
|
||||
class="space-between grid immich-scrollbar grid-auto-fill-20 gap-5 overflow-y-auto pt-5"
|
||||
bind:itemCount={numberOfPeople}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
{#if selectedTags?.size}
|
||||
<section class="flex flex-wrap gap-2 pt-5">
|
||||
{#each selectedTags as tagId (tagId)}
|
||||
{@const tag = tagMap[tagId]}
|
||||
{const tag = $derived(tagMap[tagId])}
|
||||
{#if tag}
|
||||
<Button
|
||||
size="small"
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
<!-- Image grid -->
|
||||
<div data-image-grid class="relative overflow-clip" style:height={height + 'px'} style:width={width + 'px'}>
|
||||
{#each viewerAssets as viewerAsset (viewerAsset.id)}
|
||||
{@const position = viewerAsset.position!}
|
||||
{@const asset = viewerAsset.asset!}
|
||||
{const position = viewerAsset.position!}
|
||||
{const asset = viewerAsset.asset!}
|
||||
|
||||
<!-- note: don't remove data-asset-id - its used by web e2e tests -->
|
||||
<div
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
</script>
|
||||
|
||||
{#each filterIsInOrNearViewport(timelineMonth.timelineDays) as timelineDay, groupIndex (timelineDay.day)}
|
||||
{@const isTimelineDaySelected = assetInteraction.selectedGroup.has(timelineDay.groupTitle)}
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<section
|
||||
class={[{ 'transition-all': !timelineMonth.timelineManager.suspendTransitions }]}
|
||||
@@ -76,10 +75,10 @@
|
||||
style:width={timelineDay.width + 'px'}
|
||||
>
|
||||
{#if !singleSelect}
|
||||
{const isTimelineDaySelected = $derived(assetInteraction.selectedGroup.has(timelineDay.groupTitle))}
|
||||
<div
|
||||
class="w-0 overflow-hidden transition-all duration-200 ease-out hover:cursor-pointer"
|
||||
class:w-8={hoveredTimelineDay === timelineDay.groupTitle ||
|
||||
assetInteraction.selectedGroup.has(timelineDay.groupTitle)}
|
||||
class:w-8={hoveredTimelineDay === timelineDay.groupTitle || isTimelineDaySelected}
|
||||
onclick={() => onTimelineDaySelect(timelineDay, assetsSnapshot(timelineDay.getAssets()))}
|
||||
onkeydown={() => onTimelineDaySelect(timelineDay, assetsSnapshot(timelineDay.getAssets()))}
|
||||
>
|
||||
|
||||
@@ -634,24 +634,21 @@
|
||||
</section>
|
||||
|
||||
{#each timelineManager.months as timelineMonth (timelineMonth.viewId)}
|
||||
{@const isInOrNearViewport = timelineMonth.isInOrNearViewport}
|
||||
{@const absoluteHeight = timelineMonth.top}
|
||||
|
||||
{#if !timelineMonth.isLoaded}
|
||||
<div
|
||||
style:height={timelineMonth.height + 'px'}
|
||||
style:position="absolute"
|
||||
style:transform={`translate3d(0,${absoluteHeight}px,0)`}
|
||||
style:transform={`translate3d(0,${timelineMonth.top}px,0)`}
|
||||
style:width="100%"
|
||||
>
|
||||
<Skeleton {invisible} height={timelineMonth.height} title={timelineMonth.title} />
|
||||
</div>
|
||||
{:else if isInOrNearViewport}
|
||||
{:else if timelineMonth.isInOrNearViewport}
|
||||
<div
|
||||
class="timeline-month"
|
||||
style:height={timelineMonth.height + 'px'}
|
||||
style:position="absolute"
|
||||
style:transform={`translate3d(0,${absoluteHeight}px,0)`}
|
||||
style:transform={`translate3d(0,${timelineMonth.top}px,0)`}
|
||||
style:width="100%"
|
||||
>
|
||||
<Month
|
||||
@@ -663,10 +660,11 @@
|
||||
onTimelineDaySelect={handleGroupSelect}
|
||||
>
|
||||
{#snippet thumbnail({ asset, position, timelineDay, groupIndex })}
|
||||
{@const isAssetSelectionCandidate = assetInteraction.hasSelectionCandidate(asset.id)}
|
||||
{@const isAssetSelected =
|
||||
assetInteraction.hasSelectedAsset(asset.id) || timelineManager.albumAssets.has(asset.id)}
|
||||
{@const isAssetDisabled = timelineManager.albumAssets.has(asset.id)}
|
||||
{const isAssetSelectionCandidate = $derived(assetInteraction.hasSelectionCandidate(asset.id))}
|
||||
{const isAssetSelected = $derived(
|
||||
assetInteraction.hasSelectedAsset(asset.id) || timelineManager.albumAssets.has(asset.id),
|
||||
)}
|
||||
{const isAssetDisabled = $derived(timelineManager.albumAssets.has(asset.id))}
|
||||
<Thumbnail
|
||||
showStackedIcon={withStacked}
|
||||
{showArchiveIcon}
|
||||
|
||||
@@ -112,8 +112,8 @@
|
||||
)}"
|
||||
>
|
||||
{#each options as option (option)}
|
||||
{@const renderedOption = renderOption(option)}
|
||||
{@const buttonStyle = renderedOption.disabled ? '' : 'transition-all hover:bg-gray-300 dark:hover:bg-gray-800'}
|
||||
{const renderedOption = renderOption(option)}
|
||||
{const buttonStyle = renderedOption.disabled ? '' : 'transition-all hover:bg-gray-300 dark:hover:bg-gray-800'}
|
||||
<button
|
||||
type="button"
|
||||
class="grid grid-cols-[36px_1fr] place-items-center p-2 disabled:opacity-40 {buttonStyle}"
|
||||
|
||||
@@ -70,9 +70,9 @@
|
||||
<legend class="sr-only">{$t('rating')}</legend>
|
||||
<div class="flex flex-row" data-testid="star-container">
|
||||
{#each { length: count } as _, index (index)}
|
||||
{@const value = index + 1}
|
||||
{@const filled = hoverRating === null ? (ratingSelection ?? 0) >= value : hoverRating >= value}
|
||||
{@const starId = `${id}-${value}`}
|
||||
{const value = index + 1}
|
||||
{const filled = $derived(hoverRating === null ? (ratingSelection ?? 0) >= value : hoverRating >= value)}
|
||||
{const starId = `${id}-${value}`}
|
||||
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
||||
<label
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
<section class="flex flex-wrap gap-1 pt-2">
|
||||
{#each selectedIds as tagId (tagId)}
|
||||
{@const tag = tagMap[tagId]}
|
||||
{const tag = $derived(tagMap[tagId])}
|
||||
{#if tag}
|
||||
<TagPill label={tag.value} onRemove={() => handleRemove(tagId)} />
|
||||
{/if}
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
</script>
|
||||
|
||||
{#snippet row(id: string, label: string, userId: string, onPick: () => Promise<void>)}
|
||||
{@const user = getUser(userId)}
|
||||
{const user = $derived(getUser(userId))}
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<Label id="{id}-label" for={id}>{label}</Label>
|
||||
<Button
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
{:else if filteredPeople.length > 0}
|
||||
<div class="grid grid-cols-3 gap-4 p-2">
|
||||
{#each filteredPeople as person (person.id)}
|
||||
{@const isSelected = selectedPeople.some((p) => p.id === person.id)}
|
||||
{const isSelected = $derived(selectedPeople.some((p) => p.id === person.id))}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => togglePerson(person)}
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
<Label size="small" color="primary" for="version-history">{$t('version_history')}</Label>
|
||||
<ul id="version-history" class="list-none">
|
||||
{#each versions.slice(0, 5) as item (item.id)}
|
||||
{@const createdAt = DateTime.fromISO(item.createdAt)}
|
||||
{const createdAt = DateTime.fromISO(item.createdAt)}
|
||||
<li>
|
||||
<span
|
||||
class="pb-2 text-xs immich-form-label"
|
||||
|
||||
+1
-1
@@ -390,7 +390,7 @@
|
||||
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t, album)}
|
||||
{const Actions = $derived(getAssetBulkActions($t, album))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
<ArchiveAction
|
||||
unarchive
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<!-- Multiselection mode app bar -->
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
<FavoriteAction removeFavorite onFavorite={(assetIds) => timelineManager.removeAssets(assetIds)} />
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<div class="fixed inset-s-0 top-0 w-full">
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
<IconButton
|
||||
|
||||
@@ -115,8 +115,8 @@
|
||||
</aside>
|
||||
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{@const StackActions = getStackBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
{const StackActions = $derived(getStackBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
|
||||
<Portal target="body">
|
||||
|
||||
+1
-1
@@ -277,7 +277,7 @@
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<div class="dark sticky top-0 z-1">
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
|
||||
+1
-1
@@ -476,7 +476,7 @@
|
||||
<header>
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<div class="flex flex-wrap gap-1 p-2 pb-8 md:px-8">
|
||||
<PeopleInfiniteScroll {people} hasNextPage={nextPage !== null} {loadNextPage}>
|
||||
{#snippet children({ person })}
|
||||
{@const hidden = overrides.get(person.id) ?? person.isHidden}
|
||||
{const hidden = $derived(overrides.get(person.id) ?? person.isHidden)}
|
||||
<button
|
||||
type="button"
|
||||
class="group relative size-full"
|
||||
|
||||
@@ -123,8 +123,8 @@
|
||||
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{@const StackActions = getStackBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
{const StackActions = $derived(getStackBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
{#if !isCollapsed}
|
||||
<div class="flex flex-row flex-wrap gap-4">
|
||||
{#each places as item (item.id)}
|
||||
{@const city = item.exifInfo?.city}
|
||||
{const city = item.exifInfo?.city}
|
||||
<a class="relative" href={Route.search({ city })} draggable="false">
|
||||
<div
|
||||
class="flex w-[calc((100vw-(72px+5rem))/2)] max-w-39 justify-center overflow-hidden rounded-xl brightness-75 filter"
|
||||
|
||||
@@ -98,8 +98,8 @@
|
||||
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{@const StackActions = getStackBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
{const StackActions = $derived(getStackBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
<section id="search-chips" class="mx-auto mt-24 w-full max-w-7xl px-4 sm:px-8 lg:px-12">
|
||||
<div class="flex w-full flex-wrap place-content-center place-items-center gap-2.5 sm:gap-3">
|
||||
{#each searchTermKeys as searchKey (searchKey)}
|
||||
{@const value = terms[searchKey]}
|
||||
{const value = terms[searchKey]}
|
||||
<div
|
||||
class="inline-flex max-w-full items-center rounded-full bg-primary/10 py-1 ps-1 pe-1 text-xs text-primary ring-1 ring-primary/15 transition-shadow hover:ring-primary/25 dark:bg-immich-dark-primary/15 dark:text-immich-dark-primary dark:ring-immich-dark-primary/20 dark:hover:ring-immich-dark-primary/30"
|
||||
>
|
||||
@@ -344,7 +344,7 @@
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<div class="fixed inset-s-0 top-0 z-2 w-full">
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
{#if assetMultiSelectManager.selectionActive}
|
||||
<div class="fixed inset-s-0 top-0 w-full">
|
||||
<AssetSelectControlBar>
|
||||
{@const Actions = getAssetBulkActions($t)}
|
||||
{const Actions = $derived(getAssetBulkActions($t))}
|
||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
|
||||
<ActionButton action={Actions.CreateSharedLink} />
|
||||
<SelectAllAssets {timelineManager} assetInteraction={assetMultiSelectManager} />
|
||||
|
||||
@@ -251,10 +251,12 @@
|
||||
<Card class="mt-4">
|
||||
<CardBody>
|
||||
{#each users as user, index (user.id)}
|
||||
{@const { ManageAccess } = getPeopleUserActions($t, [
|
||||
user,
|
||||
...users.filter(({ id }) => id !== authManager.user.id && id !== user.id),
|
||||
])}
|
||||
{const { ManageAccess } = $derived(
|
||||
getPeopleUserActions($t, [
|
||||
user,
|
||||
...users.filter(({ id }) => id !== authManager.user.id && id !== user.id),
|
||||
]),
|
||||
)}
|
||||
<div class="flex items-center justify-between gap-4" class:mt-4={index > 0}>
|
||||
<div class="flex items-center gap-4">
|
||||
<UserAvatar {user} size="md" />
|
||||
@@ -300,7 +302,7 @@
|
||||
{/each}
|
||||
|
||||
{#each sentRequests as request, index (request.id)}
|
||||
{@const user = candidates[request.userId]}
|
||||
{const user = $derived(candidates[request.userId])}
|
||||
<div
|
||||
class="flex items-center justify-between gap-4"
|
||||
class:mt-4={index > 0 || receivedRequests.length > 0}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
<TableBody>
|
||||
{#each keys as key (key.id)}
|
||||
{@const { Update, Rotate, Delete } = getApiKeyActions($t, key)}
|
||||
{const { Update, Rotate, Delete } = $derived(getApiKeyActions($t, key))}
|
||||
<TableRow>
|
||||
<TableCell>{key.name}</TableCell>
|
||||
<TableCell>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
<TableBody>
|
||||
{#each passkeys as passkey (passkey.id)}
|
||||
{@const { Update, Delete } = getPasskeyActions($t, passkey)}
|
||||
{const { Update, Delete } = $derived(getPasskeyActions($t, passkey))}
|
||||
<TableRow>
|
||||
<TableCell>{passkey.name ?? $t('passkeys', { values: { count: 1 } })}</TableCell>
|
||||
<TableCell>{new Date(passkey.createdAt).toLocaleDateString($locale, dateFormats.settings)}</TableCell>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
{:else}
|
||||
<div class="my-6 flex flex-col gap-3">
|
||||
{#each workflows as workflow (workflow.id)}
|
||||
{@const { ToggleEnabled, Duplicate, Logs, Edit, Delete } = getWorkflowActions($t, workflow)}
|
||||
{const { ToggleEnabled, Duplicate, Logs, Edit, Delete } = $derived(getWorkflowActions($t, workflow))}
|
||||
|
||||
<Card class="group shadow-none transition-colors hover:border-primary">
|
||||
<CardHeader>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<Link href={Route.viewUser(owner)}>{owner.name}</Link>
|
||||
</TableCell>
|
||||
{#if stats}
|
||||
{@const [diskUsage, diskUsageUnit] = getBytesWithUnit(stats.usage, 0)}
|
||||
{const [diskUsage, diskUsageUnit] = $derived(getBytesWithUnit(stats.usage, 0))}
|
||||
<TableCell class={libraryTableClasses.column3}>
|
||||
{stats.photos.toLocaleString($locale)}
|
||||
</TableCell>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<table class="w-full">
|
||||
<tbody>
|
||||
{#each library.importPaths as folder (folder)}
|
||||
{@const { Edit, Delete } = getLibraryFolderActions($t, library, folder)}
|
||||
{const { Edit, Delete } = $derived(getLibraryFolderActions($t, library, folder))}
|
||||
<tr class="h-12">
|
||||
<td>
|
||||
<Code>{folder}</Code>
|
||||
@@ -83,7 +83,7 @@
|
||||
<table class="w-full">
|
||||
<tbody>
|
||||
{#each library.exclusionPatterns as exclusionPattern (exclusionPattern)}
|
||||
{@const { Edit, Delete } = getLibraryExclusionPatternActions($t, library, exclusionPattern)}
|
||||
{const { Edit, Delete } = $derived(getLibraryExclusionPatternActions($t, library, exclusionPattern))}
|
||||
<tr class="h-12">
|
||||
<td>
|
||||
<Code>{exclusionPattern}</Code>
|
||||
|
||||
@@ -86,8 +86,8 @@
|
||||
{/if}
|
||||
|
||||
{#if description}
|
||||
{@const SvelteComponent = description}
|
||||
<div class="text-sm dark:text-white">
|
||||
{const SvelteComponent = $derived(description)}
|
||||
<SvelteComponent />
|
||||
</div>
|
||||
{/if}
|
||||
@@ -139,10 +139,8 @@
|
||||
</QueueCardButton>
|
||||
{/if}
|
||||
{#if queue.isPaused}
|
||||
{@const size = waitingCount > 0 ? '24' : '48'}
|
||||
<QueueCardButton color="light-gray" onClick={() => onCommand({ command: QueueCommand.Resume, force: false })}>
|
||||
<!-- size property is not reactive, so have to use width and height -->
|
||||
<Icon icon={mdiFastForward} {size} />
|
||||
<Icon icon={mdiFastForward} size={waitingCount > 0 ? '24' : '48'} />
|
||||
<span>{$t('resume')}</span>
|
||||
</QueueCardButton>
|
||||
{:else}
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
<div class="mt-10 flex flex-col gap-7">
|
||||
{#each queueList as [queueName, props] (queueName)}
|
||||
{@const queue = queues.find(({ name }) => name === queueName)}
|
||||
{const queue = $derived(queues.find(({ name }) => name === queueName))}
|
||||
{#if queue}
|
||||
<QueueCard {queue} onCommand={(command) => handleCommand(queueName, command)} {...props} />
|
||||
{/if}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
<div class="relative flex text-center font-mono text-2xl font-medium">
|
||||
{#if stats}
|
||||
{@const storageUsageWithUnit = getStorageUsageWithUnit(stats.usage)}
|
||||
{const storageUsageWithUnit = $derived(getStorageUsageWithUnit(stats.usage))}
|
||||
<span class="text-light-300">{zeros(storageUsageWithUnit[0])}</span><span class="text-primary"
|
||||
>{storageUsageWithUnit[0]}</span
|
||||
>
|
||||
@@ -130,7 +130,7 @@
|
||||
{#each users as user (user.id)}
|
||||
<TableRow>
|
||||
<TableCell class="w-1/4">{user.name}</TableCell>
|
||||
{@const userStats = getUserStats(user.id)}
|
||||
{const userStats = $derived(getUserStats(user.id))}
|
||||
{#if userStats}
|
||||
<TableCell class="w-1/4">
|
||||
{userStats.photos.toLocaleString($locale)} (<FormatBytes bytes={userStats.usagePhotos} />)</TableCell
|
||||
|
||||
Reference in New Issue
Block a user