mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 16:14:07 +00:00
fix: keep the mail list where it was when coming back to the Pro mail tab
This commit is contained in:
@@ -41,6 +41,7 @@ import { toast } from "@/stores/toast-store";
|
||||
import { confirmMailRemoval } from "@/lib/mail-removal-confirm";
|
||||
import { markSelectionReadWithUndo, runBatchEmailAction, setSelectionTagWithUndo, toastWithUndo, undoLabels, undoMoveAction } from "@/lib/email-action-toast";
|
||||
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||
import { measureVisibleRow } from "@/lib/virtual-row-measure";
|
||||
import { TagDisplayContext, useMeasuredTagDisplay } from "@/hooks/use-tag-display";
|
||||
import { SearchChips } from "@/components/search/search-chips";
|
||||
import { isFilterEmpty, DEFAULT_SEARCH_FILTERS } from "@/lib/jmap/search-utils";
|
||||
@@ -493,8 +494,7 @@ export function EmailList({
|
||||
// Keep sub-pixel row heights. The default measurer rounds them, so a
|
||||
// row could start up to half a pixel inside the one above it and paint
|
||||
// over that row's divider (at 125% or 150% display scaling).
|
||||
measureElement: (element, entry) =>
|
||||
entry?.borderBoxSize?.[0]?.blockSize ?? element.getBoundingClientRect().height,
|
||||
measureElement: measureVisibleRow,
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { Virtualizer } from '@tanstack/react-virtual';
|
||||
import { measureVisibleRow } from '@/lib/virtual-row-measure';
|
||||
|
||||
const instance = {
|
||||
measurementsCache: [{ size: 120 }, { size: 80 }],
|
||||
indexFromElement: () => 1,
|
||||
} as unknown as Virtualizer<HTMLDivElement, HTMLElement>;
|
||||
|
||||
const entry = (blockSize: number) => ({ borderBoxSize: [{ blockSize, inlineSize: 300 }] }) as unknown as ResizeObserverEntry;
|
||||
const row = document.createElement('div');
|
||||
|
||||
describe('measureVisibleRow', () => {
|
||||
it('takes the measured height, sub-pixels included', () => {
|
||||
expect(measureVisibleRow(row, entry(96.5), instance)).toBe(96.5);
|
||||
});
|
||||
|
||||
it('keeps the known height of a row in a hidden list', () => {
|
||||
expect(measureVisibleRow(row, entry(0), instance)).toBe(80);
|
||||
});
|
||||
|
||||
it('reports 0 for a hidden row it knows nothing about', () => {
|
||||
const empty = { measurementsCache: [], indexFromElement: () => 0 } as unknown as Virtualizer<HTMLDivElement, HTMLElement>;
|
||||
expect(measureVisibleRow(row, entry(0), empty)).toBe(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { Virtualizer } from '@tanstack/react-virtual';
|
||||
|
||||
/**
|
||||
* A virtualizer's measureElement with sub-pixel row heights that ignores a row
|
||||
* measuring 0 because its list is hidden. A Pro tab in the background is
|
||||
* display:none and its rows report no height: taken at face value the list
|
||||
* collapses, and coming back it grows row by row and scrolls away from where
|
||||
* it was. No visible row is 0 high, so the known size stands then.
|
||||
*/
|
||||
export function measureVisibleRow<TItem extends Element>(
|
||||
element: TItem,
|
||||
entry: ResizeObserverEntry | undefined,
|
||||
instance: Virtualizer<HTMLDivElement, TItem>,
|
||||
): number {
|
||||
const size = entry?.borderBoxSize?.[0]?.blockSize ?? element.getBoundingClientRect().height;
|
||||
if (size > 0) return size;
|
||||
return instance.measurementsCache[instance.indexFromElement(element)]?.size ?? size;
|
||||
}
|
||||
Reference in New Issue
Block a user