refactor(web): convert timeline layout options to derived state

- Replace createLayoutOptions() method with derived layoutOptions property for better reactivity. 
- Remove duplicate refreshLayout() implementation 
- Simplify setLayoutOptions() by removing unnecessary change tracking.
This commit is contained in:
midzelis 2025-09-28 01:45:23 +00:00
parent 674def4088
commit 575eecfd97
4 changed files with 13 additions and 28 deletions

View file

@ -230,7 +230,7 @@
<div <div
class="month-group" class="month-group"
style:margin-bottom={timelineManager.createLayoutOptions().spacing + 'px'} style:margin-bottom={timelineManager.layoutOptions.spacing + 'px'}
style:position="absolute" style:position="absolute"
style:transform={`translate3d(0,${absoluteHeight}px,0)`} style:transform={`translate3d(0,${absoluteHeight}px,0)`}
style:height={`${monthGroup.height}px`} style:height={`${monthGroup.height}px`}

View file

@ -35,6 +35,13 @@ export abstract class PhotostreamManager {
bottom: this.#scrollTop + this.viewportHeight, bottom: this.#scrollTop + this.viewportHeight,
})); }));
layoutOptions = $derived({
spacing: 2,
heightTolerance: 0.15,
rowHeight: this.rowHeight,
rowWidth: Math.floor(this.viewportWidth),
});
protected initTask = new CancellableTask( protected initTask = new CancellableTask(
() => (this.isInitialized = true), () => (this.isInitialized = true),
() => (this.isInitialized = false), () => (this.isInitialized = false),
@ -58,13 +65,9 @@ export abstract class PhotostreamManager {
abstract get months(): PhotostreamSegment[]; abstract get months(): PhotostreamSegment[];
setLayoutOptions({ headerHeight = 48, rowHeight = 235, gap = 12 }: TimelineManagerLayoutOptions) { setLayoutOptions({ headerHeight = 48, rowHeight = 235, gap = 12 }: TimelineManagerLayoutOptions) {
let changed = false; this.#setHeaderHeight(headerHeight);
changed ||= this.#setHeaderHeight(headerHeight); this.#setGap(gap);
changed ||= this.#setGap(gap); this.#setRowHeight(rowHeight);
changed ||= this.#setRowHeight(rowHeight);
if (changed) {
this.refreshLayout();
}
} }
#setHeaderHeight(value: number) { #setHeaderHeight(value: number) {
@ -208,17 +211,6 @@ export abstract class PhotostreamManager {
this.updateIntersections(); this.updateIntersections();
} }
createLayoutOptions() {
const viewportWidth = this.viewportWidth;
return {
spacing: 2,
heightTolerance: 0.15,
rowHeight: this.#rowHeight,
rowWidth: Math.floor(viewportWidth),
};
}
async loadSegment(identifier: SegmentIdentifier, options?: { cancelable: boolean }): Promise<void> { async loadSegment(identifier: SegmentIdentifier, options?: { cancelable: boolean }): Promise<void> {
let cancelable = true; let cancelable = true;
if (options) { if (options) {
@ -253,13 +245,6 @@ export abstract class PhotostreamManager {
return Promise.resolve(void 0); return Promise.resolve(void 0);
} }
refreshLayout() {
for (const month of this.months) {
updateGeometry(this, month, { invalidateHeight: true });
}
this.updateIntersections();
}
getMaxScrollPercent() { getMaxScrollPercent() {
const totalHeight = this.timelineHeight + this.bottomSectionHeight + this.topSectionHeight; const totalHeight = this.timelineHeight + this.bottomSectionHeight + this.topSectionHeight;
return (totalHeight - this.viewportHeight) / totalHeight; return (totalHeight - this.viewportHeight) / totalHeight;

View file

@ -75,7 +75,7 @@ export class SearchResultsSegment extends PhotostreamSegment {
layout(): void { layout(): void {
const timelineAssets = this.#viewerAssets.map((viewerAsset) => viewerAsset.asset); const timelineAssets = this.#viewerAssets.map((viewerAsset) => viewerAsset.asset);
const layoutOptions = this.timelineManager.createLayoutOptions(); const layoutOptions = this.timelineManager.layoutOptions;
const geometry = getJustifiedLayoutFromAssets(timelineAssets, layoutOptions); const geometry = getJustifiedLayoutFromAssets(timelineAssets, layoutOptions);
this.height = timelineAssets.length === 0 ? 0 : geometry.containerHeight + this.timelineManager.headerHeight; this.height = timelineAssets.length === 0 ? 0 : geometry.containerHeight + this.timelineManager.headerHeight;

View file

@ -34,7 +34,7 @@ export function layoutMonthGroup(timelineManager: TimelineManager, month: MonthG
let dayGroupRow = 0; let dayGroupRow = 0;
let dayGroupCol = 0; let dayGroupCol = 0;
const options = timelineManager.createLayoutOptions(); const options = timelineManager.layoutOptions;
for (const dayGroup of month.dayGroups) { for (const dayGroup of month.dayGroups) {
dayGroup.layout(options, noDefer); dayGroup.layout(options, noDefer);