From cc20b282f4d6ae5804f45f4ac75ada2309aa5aa9 Mon Sep 17 00:00:00 2001 From: midzelis Date: Sun, 28 Sep 2025 00:51:41 +0000 Subject: [PATCH] feat: search results page (without keyboard actions) fix: missing responsive calculation in UserPageLayout --- .../layouts/user-page-layout.svelte | 2 +- .../components/search/SearchResults.svelte | 91 +++++ .../search/SearchResultsAssetViewer.svelte | 76 +++++ .../components/timeline/Photostream.svelte | 31 +- .../timeline/PhotostreamWithScrubber.svelte | 2 +- web/src/lib/elements/Skeleton.svelte | 13 +- .../PhotostreamManager.svelte.ts | 29 ++ .../PhotostreamSegment.svelte.ts | 9 +- .../SearchResultsManager.svelte.ts | 110 ++++++ .../SearchResultsSegment.svelte.ts | 122 +++++++ .../timeline-manager/month-group.svelte.ts | 2 +- .../timeline-manager/viewer-asset.svelte.ts | 16 +- .../[[assetId=id]]/+page.svelte | 315 ++++++------------ 13 files changed, 567 insertions(+), 251 deletions(-) create mode 100644 web/src/lib/components/search/SearchResults.svelte create mode 100644 web/src/lib/components/search/SearchResultsAssetViewer.svelte create mode 100644 web/src/lib/managers/searchresults-manager/SearchResultsManager.svelte.ts create mode 100644 web/src/lib/managers/searchresults-manager/SearchResultsSegment.svelte.ts diff --git a/web/src/lib/components/layouts/user-page-layout.svelte b/web/src/lib/components/layouts/user-page-layout.svelte index 70e17792e0..7f40bf7a6d 100644 --- a/web/src/lib/components/layouts/user-page-layout.svelte +++ b/web/src/lib/components/layouts/user-page-layout.svelte @@ -49,7 +49,7 @@
diff --git a/web/src/lib/components/search/SearchResults.svelte b/web/src/lib/components/search/SearchResults.svelte new file mode 100644 index 0000000000..3a93d8ba2b --- /dev/null +++ b/web/src/lib/components/search/SearchResults.svelte @@ -0,0 +1,91 @@ + + + + {#snippet assetViewer({ onViewerClose })} + + {/snippet} + + {@render children?.()} + + {#snippet skeleton({ segment })} + + {/snippet} + + {#snippet segment({ segment, onScrollCompensationMonthInDOM })} + + {#snippet content({ onAssetOpen, onAssetSelect, onAssetHover })} + + {#snippet thumbnail({ asset, position })} + {@const isAssetSelectionCandidate = assetInteraction.hasSelectionCandidate(asset.id)} + {@const isAssetSelected = assetInteraction.hasSelectedAsset(asset.id)} + onAssetOpen(asset)} + onSelect={() => onAssetSelect(asset)} + onMouseEvent={() => onAssetHover(asset)} + selected={isAssetSelected} + selectionCandidate={isAssetSelectionCandidate} + thumbnailWidth={position.width} + thumbnailHeight={position.height} + /> + {/snippet} + + {/snippet} + + {/snippet} + + diff --git a/web/src/lib/components/search/SearchResultsAssetViewer.svelte b/web/src/lib/components/search/SearchResultsAssetViewer.svelte new file mode 100644 index 0000000000..28fa477efb --- /dev/null +++ b/web/src/lib/components/search/SearchResultsAssetViewer.svelte @@ -0,0 +1,76 @@ + + +{#await import('../asset-viewer/asset-viewer.svelte') then { default: AssetViewer }} + +{/await} diff --git a/web/src/lib/components/timeline/Photostream.svelte b/web/src/lib/components/timeline/Photostream.svelte index c5777df308..a29138db61 100644 --- a/web/src/lib/components/timeline/Photostream.svelte +++ b/web/src/lib/components/timeline/Photostream.svelte @@ -23,6 +23,7 @@ [ { segment: PhotostreamSegment; + stylePaddingHorizontalPx: number; }, ] >; @@ -37,7 +38,6 @@ alwaysShowScrollbar?: boolean; showSkeleton?: boolean; isShowDeleteConfirmation?: boolean; - styleMarginRightOverride?: string; header?: Snippet<[scrollToFunction: (top: number) => void]>; children?: Snippet; @@ -53,8 +53,9 @@ rowHeight: number; headerHeight: number; }; - styleMarginContentHorizontal?: string; - styleMarginTop?: string; + stylePaddingHorizontalPx?: number; + styleMarginTopPx?: number; + styleMarginRightPx?: number; } let { @@ -64,9 +65,9 @@ timelineManager = $bindable(), showSkeleton = $bindable(true), showScrollbar, - styleMarginRightOverride, - styleMarginContentHorizontal = '0px', - styleMarginTop = '0px', + styleMarginRightPx = 0, + stylePaddingHorizontalPx = 0, + styleMarginTopPx = 0, alwaysShowScrollbar, isShowDeleteConfirmation = $bindable(false), @@ -221,23 +222,26 @@ { 'm-0': isEmpty }, { 'ms-0': !isEmpty }, ]} - style:height={`calc(100% - ${styleMarginTop})`} - style:margin-top={styleMarginTop} - style:margin-right={styleMarginRightOverride} + style:height={`calc(100% - ${styleMarginTopPx}px)`} + style:margin-top={styleMarginTopPx + 'px'} + style:margin-right={styleMarginRightPx + 'px'} + style:padding-left={stylePaddingHorizontalPx + 'px'} + style:padding-right={stylePaddingHorizontalPx + 'px'} style:scrollbar-width={showScrollbar ? 'thin' : 'none'} tabindex="-1" bind:clientHeight={timelineManager.viewportHeight} + bind:clientWidth={ + null, (v: number) => ((timelineManager.viewportWidth = v - stylePaddingHorizontalPx * 2), updateSlidingWindow()) + } bind:this={element} onscroll={() => (handleTimelineScroll(), updateSlidingWindow(), updateIsScrolling())} >
((timelineManager.viewportWidth = v), updateSlidingWindow())} >
- {#each timelineManager.months as monthGroup (monthGroup.id)} {@const shouldDisplay = monthGroup.intersecting && monthGroup.isLoaded} {@const absoluteHeight = monthGroup.top} @@ -266,7 +269,7 @@ style:width="100%" > {#if !shouldDisplay} - {@render skeleton({ segment: monthGroup })} + {@render skeleton({ segment: monthGroup, stylePaddingHorizontalPx })} {:else} {@render segment({ segment: monthGroup, diff --git a/web/src/lib/components/timeline/PhotostreamWithScrubber.svelte b/web/src/lib/components/timeline/PhotostreamWithScrubber.svelte index c9de357c47..9bfd797c04 100644 --- a/web/src/lib/components/timeline/PhotostreamWithScrubber.svelte +++ b/web/src/lib/components/timeline/PhotostreamWithScrubber.svelte @@ -172,7 +172,7 @@ {timelineManager} {showSkeleton} {isShowDeleteConfirmation} - styleMarginRightOverride={scrubberWidth + 'px'} + styleMarginRightPx={scrubberWidth} {handleTimelineScroll} {segment} {skeleton} diff --git a/web/src/lib/elements/Skeleton.svelte b/web/src/lib/elements/Skeleton.svelte index 8ee05f4e61..ccaf2628bd 100644 --- a/web/src/lib/elements/Skeleton.svelte +++ b/web/src/lib/elements/Skeleton.svelte @@ -2,12 +2,13 @@ interface Props { height: number; title?: string; + stylePaddingHorizontalPx?: number; } - let { height = 0, title }: Props = $props(); + let { height = 0, title, stylePaddingHorizontalPx = 0 }: Props = $props(); -
+ {#if title}
{/if}
-
+