Compare commits

...

8 Commits

Author SHA1 Message Date
CJPeckover
6e0005acfd - add toggle to show/hide asset owner names 2025-08-25 19:55:25 -04:00
CJPeckover
55a196bfa0 Merge branch 'immich-main' into feat/shared-album-owner-labels 2025-08-25 18:27:51 -04:00
CJPeckover
d0b49846dc format 2025-08-23 01:12:37 -04:00
CJPeckover
8896b2dbf5 fix lint 2025-08-23 01:11:10 -04:00
CJPeckover
251e644b2a - cleanup albumUsers creation
- use font-light for the user's name
2025-08-23 01:09:51 -04:00
CJPeckover
a02635f9a5 cleanup 2025-08-23 00:57:50 -04:00
CJPeckover
104f3dfcc3 - change owner to their name in white text instead of the avatar 2025-08-23 00:54:50 -04:00
CJPeckover
b7e3b48a44 - pass available album users along to the thumbnail through the asset-date-group
- show a small user-avatar in bottom right of thumbnail
2025-08-22 17:29:03 -04:00
4 changed files with 48 additions and 3 deletions

View File

@@ -5,7 +5,7 @@
import { getAssetPlaybackUrl, getAssetThumbnailUrl } from '$lib/utils';
import { timeToSeconds } from '$lib/utils/date-time';
import { getAltText } from '$lib/utils/thumbnail-util';
import { AssetMediaSize, AssetVisibility } from '@immich/sdk';
import { AssetMediaSize, AssetVisibility, type UserResponseDto } from '@immich/sdk';
import {
mdiArchiveArrowDownOutline,
mdiCameraBurst,
@@ -45,6 +45,7 @@
imageClass?: ClassValue;
brokenAssetClass?: ClassValue;
dimmed?: boolean;
albumUsers?: UserResponseDto[];
onClick?: (asset: TimelineAsset) => void;
onSelect?: (asset: TimelineAsset) => void;
onMouseEvent?: (event: { isMouseOver: boolean; selectedGroupIndex: number }) => void;
@@ -63,6 +64,7 @@
readonly = false,
showArchiveIcon = false,
showStackedIcon = true,
albumUsers = [],
onClick = undefined,
onSelect = undefined,
onMouseEvent = undefined,
@@ -84,6 +86,8 @@
let width = $derived(thumbnailSize || thumbnailWidth || 235);
let height = $derived(thumbnailSize || thumbnailHeight || 235);
let assetOwner = $derived(albumUsers?.find((user) => user.id === asset.ownerId) ?? null);
const onIconClickedHandler = (e?: MouseEvent) => {
e?.stopPropagation();
e?.preventDefault();
@@ -267,6 +271,12 @@
</div>
{/if}
{#if !!assetOwner}
<div class="absolute bottom-0 end-1">
<span class="text-white font-light text-sm">{assetOwner.name}</span>
</div>
{/if}
{#if !authManager.isSharedLink && showArchiveIcon && asset.visibility === AssetVisibility.Archive}
<div class={['absolute start-2', asset.isFavorite ? 'bottom-10' : 'bottom-2']}>
<Icon path={mdiArchiveArrowDownOutline} size="24" class="text-white" />

View File

@@ -9,6 +9,7 @@
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
import { uploadAssetsStore } from '$lib/stores/upload';
import { navigate } from '$lib/utils/navigation';
import type { UserResponseDto } from '@immich/sdk';
import { mdiCheckCircle, mdiCircleOutline } from '@mdi/js';
@@ -25,7 +26,7 @@
monthGroup: MonthGroup;
timelineManager: TimelineManager;
assetInteraction: AssetInteraction;
albumUsers?: UserResponseDto[];
onSelect: ({ title, assets }: { title: string; assets: TimelineAsset[] }) => void;
onSelectAssets: (asset: TimelineAsset) => void;
onSelectAssetCandidates: (asset: TimelineAsset | null) => void;
@@ -40,6 +41,7 @@
monthGroup = $bindable(),
assetInteraction,
timelineManager,
albumUsers = [],
onSelect,
onSelectAssets,
onSelectAssetCandidates,
@@ -189,6 +191,7 @@
showStackedIcon={withStacked}
{showArchiveIcon}
{asset}
{albumUsers}
{groupIndex}
onClick={(asset) => onClick(timelineManager, dayGroup.getAssets(), dayGroup.groupTitle, asset)}
onSelect={(asset) => assetSelectHandler(timelineManager, asset, dayGroup.getAssets(), dayGroup.groupTitle)}

View File

@@ -30,7 +30,13 @@
import { archiveAssets, cancelMultiselect, selectAllAssets, stackAssets } from '$lib/utils/asset-utils';
import { navigate } from '$lib/utils/navigation';
import { getTimes, toTimelineAsset, type ScrubberListener, type TimelineYearMonth } from '$lib/utils/timeline-util';
import { AssetVisibility, getAssetInfo, type AlbumResponseDto, type PersonResponseDto } from '@immich/sdk';
import {
AssetVisibility,
getAssetInfo,
type AlbumResponseDto,
type PersonResponseDto,
type UserResponseDto,
} from '@immich/sdk';
import { modalManager } from '@immich/ui';
import { DateTime } from 'luxon';
import { onMount, type Snippet } from 'svelte';
@@ -59,6 +65,7 @@
showArchiveIcon?: boolean;
isShared?: boolean;
album?: AlbumResponseDto | null;
albumUsers?: UserResponseDto[];
person?: PersonResponseDto | null;
isShowDeleteConfirmation?: boolean;
onSelect?: (asset: TimelineAsset) => void;
@@ -78,6 +85,7 @@
showArchiveIcon = false,
isShared = false,
album = null,
albumUsers = [],
person = null,
isShowDeleteConfirmation = $bindable(false),
onSelect = () => {},
@@ -88,6 +96,12 @@
let { isViewing: showAssetViewer, asset: viewingAsset, preloadAssets, gridScrollTarget, mutex } = assetViewingStore;
// const albumUsers = $derived(
// album?.shared && album.albumUsers.some(({ role }) => role === AlbumUserRole.Editor)
// ? [album.owner, ...album.albumUsers.map(({ user }) => user)]
// : [],
// );
let element: HTMLElement | undefined = $state();
let timelineElement: HTMLElement | undefined = $state();
@@ -936,6 +950,7 @@
{isSelectionMode}
{singleSelect}
{monthGroup}
{albumUsers}
onSelect={({ title, assets }) => handleGroupSelect(timelineManager, title, assets)}
onSelectAssetCandidates={handleSelectAssetCandidates}
onSelectAssets={handleSelectAssets}

View File

@@ -71,6 +71,7 @@
} from '@immich/sdk';
import { Button, IconButton, modalManager } from '@immich/ui';
import {
mdiAccountEyeOutline,
mdiArrowLeft,
mdiCogOutline,
mdiDeleteOutline,
@@ -104,6 +105,7 @@
let isCreatingSharedAlbum = $state(false);
let isShowActivity = $state(false);
let albumOrder: AssetOrder | undefined = $state(data.album.order);
let showAlbumUsers = $state(false);
const assetInteraction = new AssetInteraction();
const timelineInteraction = new AssetInteraction();
@@ -321,6 +323,11 @@
let album = $derived(data.album);
let albumId = $derived(album.id);
const albumUsers = $derived(
showAlbumUsers && album?.shared && album.albumUsers.some(({ role }) => role === AlbumUserRole.Editor)
? [album.owner, ...album.albumUsers.map(({ user }) => user)]
: [],
);
$effect(() => {
if (!album.isActivityEnabled && activityManager.commentCount === 0) {
@@ -445,6 +452,7 @@
<AssetGrid
enableRouting={viewMode === AlbumPageViewMode.SELECT_ASSETS ? false : true}
{album}
{albumUsers}
{timelineManager}
assetInteraction={currentAssetIntersection}
{isShared}
@@ -615,6 +623,15 @@
{#snippet trailing()}
<CastButton />
<IconButton
variant="ghost"
shape="round"
color="secondary"
aria-label="view asset owners"
icon={mdiAccountEyeOutline}
onclick={() => (showAlbumUsers = !showAlbumUsers)}
/>
{#if isEditor}
<IconButton
variant="ghost"