refactor: asset viewer (#25059)

This commit is contained in:
Jason Rasmussen 2026-01-05 16:02:01 -05:00 committed by GitHub
parent 9d4a12dfd4
commit 984f06ac40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 104 additions and 108 deletions

View file

@ -1,23 +1,22 @@
<script lang="ts"> <script lang="ts">
import { shortcut } from '$lib/actions/shortcut'; import { shortcut } from '$lib/actions/shortcut';
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { IconButton } from '@immich/ui'; import { IconButton } from '@immich/ui';
import { mdiInformationOutline } from '@mdi/js'; import { mdiInformationOutline } from '@mdi/js';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
interface Props { const onAction = () => {
onShowDetail: () => void; assetViewerManager.toggleDetailPanel();
} };
let { onShowDetail }: Props = $props();
</script> </script>
<svelte:document use:shortcut={{ shortcut: { key: 'i' }, onShortcut: onShowDetail }} /> <svelte:document use:shortcut={{ shortcut: { key: 'i' }, onShortcut: onAction }} />
<IconButton <IconButton
color="secondary" color="secondary"
shape="round" shape="round"
variant="ghost" variant="ghost"
icon={mdiInformationOutline} icon={mdiInformationOutline}
onclick={onShowDetail} onclick={onAction}
aria-label={$t('info')} aria-label={$t('info')}
/> />

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { locale } from '$lib/stores/preferences.store'; import { locale } from '$lib/stores/preferences.store';
import type { ActivityResponseDto } from '@immich/sdk'; import type { ActivityResponseDto } from '@immich/sdk';
import { Icon } from '@immich/ui'; import { Icon } from '@immich/ui';
@ -9,11 +10,10 @@
numberOfComments: number | undefined; numberOfComments: number | undefined;
numberOfLikes: number | undefined; numberOfLikes: number | undefined;
disabled: boolean; disabled: boolean;
onOpenActivityTab: () => void;
onFavorite: () => void; onFavorite: () => void;
} }
let { isLiked, numberOfComments, numberOfLikes, disabled, onOpenActivityTab, onFavorite }: Props = $props(); let { isLiked, numberOfComments, numberOfLikes, disabled, onFavorite }: Props = $props();
</script> </script>
<div class="w-full flex p-4 items-center justify-center rounded-full gap-5 bg-subtle border bg-opacity-60"> <div class="w-full flex p-4 items-center justify-center rounded-full gap-5 bg-subtle border bg-opacity-60">
@ -25,7 +25,7 @@
{/if} {/if}
</div> </div>
</button> </button>
<button type="button" onclick={onOpenActivityTab}> <button type="button" onclick={() => assetViewerManager.toggleActivityPanel()}>
<div class="flex gap-2 items-center justify-center"> <div class="flex gap-2 items-center justify-center">
<Icon icon={mdiCommentOutline} class="scale-x-[-1]" size="24" /> <Icon icon={mdiCommentOutline} class="scale-x-[-1]" size="24" />
{#if numberOfComments} {#if numberOfComments}

View file

@ -5,6 +5,7 @@
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import { AppRoute, timeBeforeShowLoadingSpinner } from '$lib/constants'; import { AppRoute, timeBeforeShowLoadingSpinner } from '$lib/constants';
import { activityManager } from '$lib/managers/activity-manager.svelte'; import { activityManager } from '$lib/managers/activity-manager.svelte';
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { locale } from '$lib/stores/preferences.store'; import { locale } from '$lib/stores/preferences.store';
import { getAssetThumbnailUrl } from '$lib/utils'; import { getAssetThumbnailUrl } from '$lib/utils';
import { getAssetType } from '$lib/utils/asset-utils'; import { getAssetType } from '$lib/utils/asset-utils';
@ -44,10 +45,9 @@
assetType?: AssetTypeEnum | undefined; assetType?: AssetTypeEnum | undefined;
albumOwnerId: string; albumOwnerId: string;
disabled: boolean; disabled: boolean;
onClose: () => void;
} }
let { user, assetId = undefined, albumId, assetType = undefined, albumOwnerId, disabled, onClose }: Props = $props(); let { user, assetId = undefined, albumId, assetType = undefined, albumOwnerId, disabled }: Props = $props();
let innerHeight: number = $state(0); let innerHeight: number = $state(0);
let activityHeight: number = $state(0); let activityHeight: number = $state(0);
@ -117,7 +117,7 @@
shape="round" shape="round"
variant="ghost" variant="ghost"
color="secondary" color="secondary"
onclick={onClose} onclick={() => assetViewerManager.closeActivityPanel()}
icon={mdiClose} icon={mdiClose}
aria-label={$t('close')} aria-label={$t('close')}
/> />
@ -243,38 +243,34 @@
<div> <div>
<UserAvatar {user} size="md" noTitle /> <UserAvatar {user} size="md" noTitle />
</div> </div>
<form class="flex w-full max-h-56 gap-1" {onsubmit}> <form class="flex w-full items-center max-h-56 gap-1" {onsubmit}>
<div class="flex w-full items-center gap-4"> <Textarea
<Textarea {disabled}
{disabled} bind:value={message}
bind:value={message} rows={1}
rows={1} grow
grow placeholder={disabled ? $t('comments_are_disabled') : $t('say_something')}
placeholder={disabled ? $t('comments_are_disabled') : $t('say_something')} {@attach fromAction(shortcut, () => ({
{@attach fromAction(shortcut, () => ({ shortcut: { key: 'Enter' },
shortcut: { key: 'Enter' }, onShortcut: () => handleSendComment(),
onShortcut: () => handleSendComment(), }))}
}))} class="{disabled
class="h-4.5 {disabled ? 'cursor-not-allowed'
? 'cursor-not-allowed' : ''} ring-0! w-full max-h-56 pe-2 items-center overflow-y-auto leading-4 outline-none resize-none bg-gray-200 dark:bg-gray-200"
: ''} w-full max-h-56 pe-2 items-center overflow-y-auto leading-4 outline-none resize-none bg-gray-200 dark:bg-gray-200" />
></Textarea>
</div>
{#if isSendingMessage} {#if isSendingMessage}
<div class="flex items-end place-items-center pb-2 ms-0"> <div class="flex place-items-center pb-2 ms-0">
<div class="flex w-full place-items-center"> <div class="flex w-full place-items-center">
<LoadingSpinner /> <LoadingSpinner size="large" />
</div> </div>
</div> </div>
{:else if message} {:else if message}
<div class="flex items-end w-fit ms-0"> <div class="flex items-center w-fit ms-0 light">
<IconButton <IconButton
shape="round" shape="round"
aria-label={$t('send_message')} aria-label={$t('send_message')}
size="small"
variant="ghost" variant="ghost"
icon={mdiSend} icon={mdiSend}
class="dark:text-immich-dark-gray"
onclick={() => handleSendComment()} onclick={() => handleSendComment()}
/> />
</div> </div>

View file

@ -10,7 +10,6 @@ describe('AssetViewerNavBar component', () => {
const additionalProps = { const additionalProps = {
showCopyButton: false, showCopyButton: false,
showZoomButton: false, showZoomButton: false,
showDetailButton: false,
showDownloadButton: false, showDownloadButton: false,
showMotionPlayButton: false, showMotionPlayButton: false,
showShareButton: false, showShareButton: false,
@ -19,7 +18,6 @@ describe('AssetViewerNavBar component', () => {
onAction: () => {}, onAction: () => {},
onRunJob: () => {}, onRunJob: () => {},
onPlaySlideshow: () => {}, onPlaySlideshow: () => {},
onShowDetail: () => {},
onClose: () => {}, onClose: () => {},
playOriginalVideo: false, playOriginalVideo: false,
setPlayOriginalVideo: () => Promise.resolve(), setPlayOriginalVideo: () => Promise.resolve(),

View file

@ -24,6 +24,7 @@
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte'; import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import { AppRoute } from '$lib/constants'; import { AppRoute } from '$lib/constants';
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
import { getAssetActions, handleReplaceAsset } from '$lib/services/asset.service'; import { getAssetActions, handleReplaceAsset } from '$lib/services/asset.service';
import { photoViewerImgElement } from '$lib/stores/assets-store.svelte'; import { photoViewerImgElement } from '$lib/stores/assets-store.svelte';
@ -68,7 +69,6 @@
person?: PersonResponseDto | null; person?: PersonResponseDto | null;
stack?: StackResponseDto | null; stack?: StackResponseDto | null;
showCloseButton?: boolean; showCloseButton?: boolean;
showDetailButton: boolean;
showSlideshow?: boolean; showSlideshow?: boolean;
onZoomImage: () => void; onZoomImage: () => void;
onCopyImage?: () => Promise<void>; onCopyImage?: () => Promise<void>;
@ -77,7 +77,6 @@
onUndoDelete?: OnUndoDelete; onUndoDelete?: OnUndoDelete;
onRunJob: (name: AssetJobName) => void; onRunJob: (name: AssetJobName) => void;
onPlaySlideshow: () => void; onPlaySlideshow: () => void;
onShowDetail: () => void;
// export let showEditorHandler: () => void; // export let showEditorHandler: () => void;
onClose: () => void; onClose: () => void;
motionPhoto?: Snippet; motionPhoto?: Snippet;
@ -91,7 +90,6 @@
person = null, person = null,
stack = null, stack = null,
showCloseButton = true, showCloseButton = true,
showDetailButton,
showSlideshow = false, showSlideshow = false,
onZoomImage, onZoomImage,
onCopyImage, onCopyImage,
@ -100,7 +98,6 @@
onUndoDelete = undefined, onUndoDelete = undefined,
onRunJob, onRunJob,
onPlaySlideshow, onPlaySlideshow,
onShowDetail,
onClose, onClose,
motionPhoto, motionPhoto,
playOriginalVideo = false, playOriginalVideo = false,
@ -143,7 +140,7 @@
shape="round" shape="round"
color="danger" color="danger"
icon={mdiAlertOutline} icon={mdiAlertOutline}
onclick={onShowDetail} onclick={() => assetViewerManager.toggleDetailPanel()}
aria-label={$t('asset_offline')} aria-label={$t('asset_offline')}
/> />
{/if} {/if}
@ -176,8 +173,8 @@
<DownloadAction asset={toTimelineAsset(asset)} /> <DownloadAction asset={toTimelineAsset(asset)} />
{/if} {/if}
{#if showDetailButton} {#if asset.hasMetadata}
<ShowDetailAction {onShowDetail} /> <ShowDetailAction />
{/if} {/if}
{#if isOwner} {#if isOwner}

View file

@ -9,12 +9,13 @@
import OnEvents from '$lib/components/OnEvents.svelte'; import OnEvents from '$lib/components/OnEvents.svelte';
import { AppRoute, AssetAction, ProjectionType } from '$lib/constants'; import { AppRoute, AssetAction, ProjectionType } from '$lib/constants';
import { activityManager } from '$lib/managers/activity-manager.svelte'; import { activityManager } from '$lib/managers/activity-manager.svelte';
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { authManager } from '$lib/managers/auth-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
import { closeEditorCofirm } from '$lib/stores/asset-editor.store'; import { closeEditorCofirm } from '$lib/stores/asset-editor.store';
import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { ocrManager } from '$lib/stores/ocr.svelte'; import { ocrManager } from '$lib/stores/ocr.svelte';
import { alwaysLoadOriginalVideo, isShowDetail } from '$lib/stores/preferences.store'; import { alwaysLoadOriginalVideo } from '$lib/stores/preferences.store';
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store'; import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
import { user } from '$lib/stores/user.store'; import { user } from '$lib/stores/user.store';
import { websocketEvents } from '$lib/stores/websocket'; import { websocketEvents } from '$lib/stores/websocket';
@ -105,11 +106,7 @@
let appearsInAlbums: AlbumResponseDto[] = $state([]); let appearsInAlbums: AlbumResponseDto[] = $state([]);
let shouldPlayMotionPhoto = $state(false); let shouldPlayMotionPhoto = $state(false);
let sharedLink = getSharedLink(); let sharedLink = getSharedLink();
let enableDetailPanel = asset.hasMetadata;
let slideshowStateUnsubscribe: () => void;
let shuffleSlideshowUnsubscribe: () => void;
let previewStackedAsset: AssetResponseDto | undefined = $state(); let previewStackedAsset: AssetResponseDto | undefined = $state();
let isShowActivity = $state(false);
let isShowEditor = $state(false); let isShowEditor = $state(false);
let fullscreenElement = $state<Element>(); let fullscreenElement = $state<Element>();
let unsubscribes: (() => void)[] = []; let unsubscribes: (() => void)[] = [];
@ -163,39 +160,29 @@
unsubscribes.push( unsubscribes.push(
websocketEvents.on('on_upload_success', (asset) => onAssetUpdate({ event: 'upload', asset })), websocketEvents.on('on_upload_success', (asset) => onAssetUpdate({ event: 'upload', asset })),
websocketEvents.on('on_asset_update', (asset) => onAssetUpdate({ event: 'update', asset })), websocketEvents.on('on_asset_update', (asset) => onAssetUpdate({ event: 'update', asset })),
slideshowState.subscribe((value) => {
if (value === SlideshowState.PlaySlideshow) {
slideshowHistory.reset();
slideshowHistory.queue(toTimelineAsset(asset));
handlePromiseError(handlePlaySlideshow());
} else if (value === SlideshowState.StopSlideshow) {
handlePromiseError(handleStopSlideshow());
}
}),
slideshowNavigation.subscribe((value) => {
if (value === SlideshowNavigation.Shuffle) {
slideshowHistory.reset();
slideshowHistory.queue(toTimelineAsset(asset));
}
}),
); );
slideshowStateUnsubscribe = slideshowState.subscribe((value) => {
if (value === SlideshowState.PlaySlideshow) {
slideshowHistory.reset();
slideshowHistory.queue(toTimelineAsset(asset));
handlePromiseError(handlePlaySlideshow());
} else if (value === SlideshowState.StopSlideshow) {
handlePromiseError(handleStopSlideshow());
}
});
shuffleSlideshowUnsubscribe = slideshowNavigation.subscribe((value) => {
if (value === SlideshowNavigation.Shuffle) {
slideshowHistory.reset();
slideshowHistory.queue(toTimelineAsset(asset));
}
});
if (!sharedLink) { if (!sharedLink) {
await handleGetAllAlbums(); await handleGetAllAlbums();
} }
}); });
onDestroy(() => { onDestroy(() => {
if (slideshowStateUnsubscribe) {
slideshowStateUnsubscribe();
}
if (shuffleSlideshowUnsubscribe) {
shuffleSlideshowUnsubscribe();
}
for (const unsubscribe of unsubscribes) { for (const unsubscribe of unsubscribes) {
unsubscribe(); unsubscribe();
} }
@ -215,18 +202,6 @@
} }
}; };
const handleOpenActivity = () => {
if ($isShowDetail) {
$isShowDetail = false;
}
isShowActivity = !isShowActivity;
};
const toggleDetailPanel = () => {
isShowActivity = false;
$isShowDetail = !$isShowDetail;
};
const closeViewer = () => { const closeViewer = () => {
onClose(asset); onClose(asset);
}; };
@ -389,7 +364,7 @@
}); });
$effect(() => { $effect(() => {
if (album && !album.isActivityEnabled && activityManager.commentCount === 0) { if (album && !album.isActivityEnabled && activityManager.commentCount === 0) {
isShowActivity = false; assetViewerManager.closeActivityPanel();
} }
}); });
$effect(() => { $effect(() => {
@ -427,7 +402,6 @@
{person} {person}
{stack} {stack}
{showCloseButton} {showCloseButton}
showDetailButton={enableDetailPanel}
showSlideshow={true} showSlideshow={true}
onZoomImage={zoomToggle} onZoomImage={zoomToggle}
onCopyImage={copyImage} onCopyImage={copyImage}
@ -436,7 +410,6 @@
{onUndoDelete} {onUndoDelete}
onRunJob={handleRunJob} onRunJob={handleRunJob}
onPlaySlideshow={() => ($slideshowState = SlideshowState.PlaySlideshow)} onPlaySlideshow={() => ($slideshowState = SlideshowState.PlaySlideshow)}
onShowDetail={toggleDetailPanel}
onClose={closeViewer} onClose={closeViewer}
{playOriginalVideo} {playOriginalVideo}
{setPlayOriginalVideo} {setPlayOriginalVideo}
@ -555,7 +528,6 @@
numberOfComments={activityManager.commentCount} numberOfComments={activityManager.commentCount}
numberOfLikes={activityManager.likeCount} numberOfLikes={activityManager.likeCount}
onFavorite={handleFavorite} onFavorite={handleFavorite}
onOpenActivityTab={handleOpenActivity}
/> />
</div> </div>
{/if} {/if}
@ -575,14 +547,14 @@
</div> </div>
{/if} {/if}
{#if enableDetailPanel && $slideshowState === SlideshowState.None && $isShowDetail && !isShowEditor} {#if asset.hasMetadata && $slideshowState === SlideshowState.None && assetViewerManager.isShowDetailPanel && !isShowEditor}
<div <div
transition:fly={{ duration: 150 }} transition:fly={{ duration: 150 }}
id="detail-panel" id="detail-panel"
class="row-start-1 row-span-4 w-[360px] overflow-y-auto transition-all dark:border-l dark:border-s-immich-dark-gray bg-light" class="row-start-1 row-span-4 w-[360px] overflow-y-auto transition-all dark:border-l dark:border-s-immich-dark-gray bg-light"
translate="yes" translate="yes"
> >
<DetailPanel {asset} currentAlbum={album} albums={appearsInAlbums} onClose={() => ($isShowDetail = false)} /> <DetailPanel {asset} currentAlbum={album} albums={appearsInAlbums} />
</div> </div>
{/if} {/if}
@ -633,7 +605,7 @@
</div> </div>
{/if} {/if}
{#if isShared && album && isShowActivity && $user} {#if isShared && album && assetViewerManager.isShowActivityPanel && $user}
<div <div
transition:fly={{ duration: 150 }} transition:fly={{ duration: 150 }}
id="activity-panel" id="activity-panel"
@ -647,7 +619,6 @@
albumOwnerId={album.ownerId} albumOwnerId={album.ownerId}
albumId={album.id} albumId={album.id}
assetId={asset.id} assetId={asset.id}
onClose={() => (isShowActivity = false)}
/> />
</div> </div>
{/if} {/if}

View file

@ -6,6 +6,7 @@
import DetailPanelRating from '$lib/components/asset-viewer/detail-panel-star-rating.svelte'; import DetailPanelRating from '$lib/components/asset-viewer/detail-panel-star-rating.svelte';
import DetailPanelTags from '$lib/components/asset-viewer/detail-panel-tags.svelte'; import DetailPanelTags from '$lib/components/asset-viewer/detail-panel-tags.svelte';
import { AppRoute, QueryParameter, timeToLoadTheMap } from '$lib/constants'; import { AppRoute, QueryParameter, timeToLoadTheMap } from '$lib/constants';
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { authManager } from '$lib/managers/auth-manager.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte';
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
import AssetChangeDateModal from '$lib/modals/AssetChangeDateModal.svelte'; import AssetChangeDateModal from '$lib/modals/AssetChangeDateModal.svelte';
@ -45,10 +46,9 @@
asset: AssetResponseDto; asset: AssetResponseDto;
albums?: AlbumResponseDto[]; albums?: AlbumResponseDto[];
currentAlbum?: AlbumResponseDto | null; currentAlbum?: AlbumResponseDto | null;
onClose: () => void;
} }
let { asset, albums = [], currentAlbum = null, onClose }: Props = $props(); let { asset, albums = [], currentAlbum = null }: Props = $props();
let showAssetPath = $state(false); let showAssetPath = $state(false);
let showEditFaces = $state(false); let showEditFaces = $state(false);
@ -127,7 +127,7 @@
<IconButton <IconButton
icon={mdiClose} icon={mdiClose}
aria-label={$t('close')} aria-label={$t('close')}
onclick={onClose} onclick={() => assetViewerManager.closeDetailPanel()}
shape="round" shape="round"
color="secondary" color="secondary"
variant="ghost" variant="ghost"

View file

@ -0,0 +1,43 @@
import { PersistedLocalStorage } from '$lib/utils/persisted';
const isShowDetailPanel = new PersistedLocalStorage<boolean>('asset-viewer-state', false);
export class AssetViewerManager {
#isShowActivityPanel = $state(false);
get isShowActivityPanel() {
return this.#isShowActivityPanel;
}
private set isShowActivityPanel(value: boolean) {
this.#isShowActivityPanel = value;
}
get isShowDetailPanel() {
return isShowDetailPanel.current;
}
private set isShowDetailPanel(value: boolean) {
isShowDetailPanel.current = value;
}
toggleActivityPanel() {
this.closeDetailPanel();
this.isShowActivityPanel = !this.isShowActivityPanel;
}
closeActivityPanel() {
this.isShowActivityPanel = false;
}
toggleDetailPanel() {
this.closeActivityPanel();
this.isShowDetailPanel = !this.isShowDetailPanel;
}
closeDetailPanel() {
this.isShowDetailPanel = false;
}
}
export const assetViewerManager = new AssetViewerManager();

View file

@ -59,8 +59,6 @@ export const mapSettings = persistedObject<MapSettings>('map-settings', defaultM
export const videoViewerVolume = persisted<number>('video-viewer-volume', 1, {}); export const videoViewerVolume = persisted<number>('video-viewer-volume', 1, {});
export const videoViewerMuted = persisted<boolean>('video-viewer-muted', false, {}); export const videoViewerMuted = persisted<boolean>('video-viewer-muted', false, {});
export const isShowDetail = persisted<boolean>('info-opened', false, {});
export interface AlbumViewSettings { export interface AlbumViewSettings {
view: string; view: string;
filter: string; filter: string;

View file

@ -30,6 +30,7 @@
import Timeline from '$lib/components/timeline/Timeline.svelte'; import Timeline from '$lib/components/timeline/Timeline.svelte';
import { AlbumPageViewMode, AppRoute } from '$lib/constants'; import { AlbumPageViewMode, AppRoute } from '$lib/constants';
import { activityManager } from '$lib/managers/activity-manager.svelte'; import { activityManager } from '$lib/managers/activity-manager.svelte';
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte'; import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
@ -100,7 +101,6 @@
let backUrl: string = $state(AppRoute.ALBUMS); let backUrl: string = $state(AppRoute.ALBUMS);
let viewMode: AlbumPageViewMode = $state(AlbumPageViewMode.VIEW); let viewMode: AlbumPageViewMode = $state(AlbumPageViewMode.VIEW);
let isCreatingSharedAlbum = $state(false); let isCreatingSharedAlbum = $state(false);
let isShowActivity = $state(false);
let albumOrder: AssetOrder | undefined = $state(data.album.order); let albumOrder: AssetOrder | undefined = $state(data.album.order);
let timelineManager = $state<TimelineManager>() as TimelineManager; let timelineManager = $state<TimelineManager>() as TimelineManager;
@ -138,10 +138,6 @@
} }
}; };
const handleOpenAndCloseActivityTab = () => {
isShowActivity = !isShowActivity;
};
const handleStartSlideshow = async () => { const handleStartSlideshow = async () => {
const asset = const asset =
$slideshowNavigation === SlideshowNavigation.Shuffle $slideshowNavigation === SlideshowNavigation.Shuffle
@ -302,7 +298,7 @@
$effect(() => { $effect(() => {
if (!album.isActivityEnabled && activityManager.commentCount === 0) { if (!album.isActivityEnabled && activityManager.commentCount === 0) {
isShowActivity = false; assetViewerManager.closeActivityPanel();
} }
}); });
@ -537,7 +533,6 @@
numberOfComments={activityManager.commentCount} numberOfComments={activityManager.commentCount}
numberOfLikes={undefined} numberOfLikes={undefined}
onFavorite={handleFavorite} onFavorite={handleFavorite}
onOpenActivityTab={handleOpenAndCloseActivityTab}
/> />
</div> </div>
{/if} {/if}
@ -724,7 +719,7 @@
{/if} {/if}
{/if} {/if}
</div> </div>
{#if album.albumUsers.length > 0 && album && isShowActivity && $user && !$showAssetViewer} {#if album.albumUsers.length > 0 && album && assetViewerManager.isShowActivityPanel && $user && !$showAssetViewer}
<div class="flex"> <div class="flex">
<div <div
transition:fly={{ duration: 150 }} transition:fly={{ duration: 150 }}
@ -737,7 +732,6 @@
disabled={!album.isActivityEnabled} disabled={!album.isActivityEnabled}
albumOwnerId={album.ownerId} albumOwnerId={album.ownerId}
albumId={album.id} albumId={album.id}
onClose={handleOpenAndCloseActivityTab}
/> />
</div> </div>
</div> </div>