mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
chore!: migrate album owner to album_user (#27467)
Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com> Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||
import { getContextMenuPositionFromEvent, type ContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import { getShortDateRange } from '$lib/utils/date-time';
|
||||
import type { AlbumResponseDto } from '@immich/sdk';
|
||||
import { type AlbumResponseDto } from '@immich/sdk';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiDotsVertical } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
@@ -85,12 +85,13 @@
|
||||
{/if}
|
||||
|
||||
{#if showOwner}
|
||||
{#if authManager.user.id === album.ownerId}
|
||||
{@const owner = album.albumUsers[0].user}
|
||||
{#if owner.id === authManager.user.id}
|
||||
<p>{$t('owned')}</p>
|
||||
{:else if album.owner}
|
||||
<p>{$t('shared_by_user', { values: { user: album.owner.name } })}</p>
|
||||
{:else}
|
||||
<p>{$t('shared')}</p>
|
||||
<p>
|
||||
{$t('shared_by_user', { values: { user: owner.name } })}
|
||||
</p>
|
||||
{/if}
|
||||
{:else if album.shared}
|
||||
<p>{$t('shared')}</p>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import { getSelectedAlbumGroupOption, sortAlbums, stringToSortOrder, type AlbumGroup } from '$lib/utils/album-utils';
|
||||
import type { ContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import { normalizeSearchString } from '$lib/utils/string-utils';
|
||||
import { type AlbumResponseDto, type SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { AlbumUserRole, type AlbumResponseDto, type SharedLinkResponseDto } from '@immich/sdk';
|
||||
import { modalManager } from '@immich/ui';
|
||||
import { mdiDeleteOutline, mdiDownload, mdiRenameOutline, mdiShareVariantOutline } from '@mdi/js';
|
||||
import { groupBy } from 'lodash-es';
|
||||
@@ -98,24 +98,26 @@
|
||||
/** Group by owner */
|
||||
[AlbumGroupBy.Owner]: (order, albums): AlbumGroup[] => {
|
||||
const currentUserId = authManager.user.id;
|
||||
const groupedByOwnerIds = groupBy(albums, 'ownerId');
|
||||
const groupedByOwnerIds = groupBy(albums, (album) => album.albumUsers[0].user.id);
|
||||
|
||||
const sortSign = order === SortOrder.Desc ? -1 : 1;
|
||||
const sortedByOwnerNames = Object.entries(groupedByOwnerIds).sort(([ownerA, albumsA], [ownerB, albumsB]) => {
|
||||
const sortedByOwnerNames = Object.entries(groupedByOwnerIds).sort(([ownerIdA, albumsA], [ownerIdB, albumsB]) => {
|
||||
// We make sure owned albums stay either at the beginning or the end
|
||||
// of the list
|
||||
if (ownerA === currentUserId) {
|
||||
if (ownerIdA === currentUserId) {
|
||||
return -sortSign;
|
||||
} else if (ownerB === currentUserId) {
|
||||
} else if (ownerIdB === currentUserId) {
|
||||
return sortSign;
|
||||
} else {
|
||||
return albumsA[0].owner.name.localeCompare(albumsB[0].owner.name, $locale) * sortSign;
|
||||
const ownerA = albumsA[0].albumUsers[0].user;
|
||||
const ownerB = albumsB[0].albumUsers[0].user;
|
||||
return ownerA.name.localeCompare(ownerB.name, $locale) * sortSign;
|
||||
}
|
||||
});
|
||||
|
||||
return sortedByOwnerNames.map(([ownerId, albums]) => ({
|
||||
id: ownerId,
|
||||
name: ownerId === currentUserId ? $t('my_albums') : albums[0].owner.name,
|
||||
name: ownerId === currentUserId ? $t('my_albums') : albums[0].albumUsers[0].user.name,
|
||||
albums,
|
||||
}));
|
||||
},
|
||||
@@ -130,7 +132,10 @@
|
||||
return sharedAlbums;
|
||||
}
|
||||
default: {
|
||||
const nonOwnedAlbums = sharedAlbums.filter((album) => album.ownerId !== authManager.user.id);
|
||||
const nonOwnedAlbums = sharedAlbums.filter(
|
||||
(album) =>
|
||||
album.albumUsers.find(({ user: { id } }) => id === authManager.user.id)?.role !== AlbumUserRole.Owner,
|
||||
);
|
||||
return nonOwnedAlbums.length > 0 ? ownedAlbums.concat(nonOwnedAlbums) : ownedAlbums;
|
||||
}
|
||||
}
|
||||
@@ -167,7 +172,9 @@
|
||||
albumGroupIds = groupedAlbums.map(({ id }) => id);
|
||||
});
|
||||
|
||||
let showFullContextMenu = $derived(allowEdit && selectedAlbum && selectedAlbum.ownerId === authManager.user.id);
|
||||
let showFullContextMenu = $derived(
|
||||
allowEdit && selectedAlbum && selectedAlbum.albumUsers[0].user.id === authManager.user.id,
|
||||
);
|
||||
|
||||
onMount(async () => {
|
||||
if (allowEdit) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { Route } from '$lib/route';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import type { ContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import type { AlbumResponseDto } from '@immich/sdk';
|
||||
import { AlbumUserRole, type AlbumResponseDto } from '@immich/sdk';
|
||||
import { Icon } from '@immich/ui';
|
||||
import { mdiShareVariantOutline } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
@@ -43,9 +43,11 @@
|
||||
icon={mdiShareVariantOutline}
|
||||
size="16"
|
||||
class="inline ms-1 opacity-70"
|
||||
title={album.ownerId === authManager.user.id
|
||||
title={album.albumUsers.find(({ user: { id } }) => id === authManager.user.id)?.role === AlbumUserRole.Owner
|
||||
? $t('shared_by_you')
|
||||
: $t('shared_by_user', { values: { user: album.owner.name } })}
|
||||
: $t('shared_by_user', {
|
||||
values: { user: album.albumUsers[0].user.name },
|
||||
})}
|
||||
/>
|
||||
{/if}
|
||||
</td>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
import { getAssetType } from '$lib/utils/asset-utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { isTenMinutesApart } from '$lib/utils/timesince';
|
||||
import { ReactionType, type ActivityResponseDto, type AssetTypeEnum } from '@immich/sdk';
|
||||
import { ReactionType, type ActivityResponseDto, type AlbumUserResponseDto, type AssetTypeEnum } from '@immich/sdk';
|
||||
import { Icon, IconButton, LoadingSpinner, Textarea, toastManager } from '@immich/ui';
|
||||
import { mdiClose, mdiDeleteOutline, mdiDotsVertical, mdiSend, mdiThumbUp } from '@mdi/js';
|
||||
import * as luxon from 'luxon';
|
||||
@@ -43,11 +43,11 @@
|
||||
assetId?: string | undefined;
|
||||
albumId: string;
|
||||
assetType?: AssetTypeEnum | undefined;
|
||||
albumOwnerId: string;
|
||||
albumUsers: AlbumUserResponseDto[];
|
||||
disabled: boolean;
|
||||
}
|
||||
|
||||
let { assetId = undefined, albumId, assetType = undefined, albumOwnerId, disabled }: Props = $props();
|
||||
let { assetId = undefined, albumId, assetType = undefined, albumUsers, disabled }: Props = $props();
|
||||
|
||||
let innerHeight: number = $state(0);
|
||||
let activityHeight: number = $state(0);
|
||||
@@ -56,6 +56,7 @@
|
||||
let previousAssetId: string | undefined = $state(assetId);
|
||||
let message = $state('');
|
||||
let isSendingMessage = $state(false);
|
||||
const isAlbumOwner = $derived(albumUsers[0].user.id === authManager.user.id);
|
||||
|
||||
const timeOptions: Intl.DateTimeFormatOptions = {
|
||||
year: 'numeric',
|
||||
@@ -147,7 +148,7 @@
|
||||
/>
|
||||
</a>
|
||||
{/if}
|
||||
{#if reaction.user.id === authManager.user.id || albumOwnerId === authManager.user.id}
|
||||
{#if reaction.user.id === authManager.user.id || isAlbumOwner}
|
||||
<div class="me-4">
|
||||
<ButtonContextMenu
|
||||
icon={mdiDotsVertical}
|
||||
@@ -200,7 +201,7 @@
|
||||
/>
|
||||
</a>
|
||||
{/if}
|
||||
{#if reaction.user.id === authManager.user.id || albumOwnerId === authManager.user.id}
|
||||
{#if reaction.user.id === authManager.user.id || isAlbumOwner}
|
||||
<div class="me-4">
|
||||
<ButtonContextMenu
|
||||
icon={mdiDotsVertical}
|
||||
|
||||
@@ -638,7 +638,7 @@
|
||||
<ActivityViewer
|
||||
disabled={!album.isActivityEnabled}
|
||||
assetType={asset.type}
|
||||
albumOwnerId={album.ownerId}
|
||||
albumUsers={album.albumUsers}
|
||||
albumId={album.id}
|
||||
assetId={asset.id}
|
||||
/>
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
}: Props = $props();
|
||||
|
||||
const isOwner = $derived(authManager.authenticated && asset.ownerId === authManager.user.id);
|
||||
const isAlbumOwner = $derived(authManager.authenticated && album?.ownerId === authManager.user.id);
|
||||
const isAlbumOwner = $derived(authManager.authenticated && album?.albumUsers[0].user.id === authManager.user.id);
|
||||
const isLocked = $derived(asset.visibility === AssetVisibility.Locked);
|
||||
const smartSearchEnabled = $derived(featureFlagsManager.value.smartSearch);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user