mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 00:12:39 +00:00
fix: keep the account and other query parameters of a mail link Lite replays after a 404 #1352
This commit is contained in:
@@ -157,7 +157,7 @@ import {
|
||||
import { consumePendingDeepLink, subscribePendingDeepLink } from "@/lib/deep-link-handoff";
|
||||
import { useProInterfaceActive } from "@/components/pro/pro-interface-redirect";
|
||||
import type { QuoteHeader } from "@/lib/plugin-types";
|
||||
import { useLiteLinkSegments } from "@/hooks/use-lite-link-segments";
|
||||
import { initialLinkSearch, useLiteLinkSegments } from "@/hooks/use-lite-link-segments";
|
||||
|
||||
export interface MailAppProps {
|
||||
/**
|
||||
@@ -1893,7 +1893,7 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
// actually opened with on first client render.
|
||||
const initialSearchRef = useRef<string | null>(null);
|
||||
if (initialSearchRef.current === null && typeof window !== "undefined") {
|
||||
initialSearchRef.current = window.location.search;
|
||||
initialSearchRef.current = initialLinkSearch('mail');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -14,9 +14,41 @@ vi.mock('@/lib/lite', async (importOriginal) => {
|
||||
};
|
||||
});
|
||||
|
||||
import { useLiteLinkSegments } from '@/hooks/use-lite-link-segments';
|
||||
import { initialLinkSearch, useLiteLinkSegments } from '@/hooks/use-lite-link-segments';
|
||||
import { LITE_PENDING_PATH_KEY } from '@/lib/lite';
|
||||
|
||||
// Mail reads the query it was opened with on its first render, while the
|
||||
// address bar still shows the surface root the 404 shim jumped to (#1352).
|
||||
describe('initialLinkSearch', () => {
|
||||
beforeEach(() => sessionStorage.clear());
|
||||
|
||||
it('takes the query of a parked deep link in the first render', () => {
|
||||
liteState.IS_LITE = true;
|
||||
window.history.replaceState({}, '', '/en/mail/');
|
||||
sessionStorage.setItem(LITE_PENDING_PATH_KEY, '/en/mail/message/m1/?account=bob%40example.org#x');
|
||||
|
||||
const seen: string[] = [];
|
||||
renderHook(() => {
|
||||
useLiteLinkSegments('mail', []);
|
||||
seen.push(initialLinkSearch('mail'));
|
||||
});
|
||||
|
||||
expect(seen[0]).toBe('?account=bob%40example.org');
|
||||
// The restored URL carries it from then on.
|
||||
expect(window.location.search).toBe('?account=bob%40example.org');
|
||||
});
|
||||
|
||||
it('reads the address bar otherwise', () => {
|
||||
liteState.IS_LITE = true;
|
||||
window.history.replaceState({}, '', '/en/mail/message/m1?account=a');
|
||||
sessionStorage.setItem(LITE_PENDING_PATH_KEY, '/en/calendar/week/2026-09-17?view=1');
|
||||
expect(initialLinkSearch('mail')).toBe('?account=a');
|
||||
liteState.IS_LITE = false;
|
||||
sessionStorage.setItem(LITE_PENDING_PATH_KEY, '/en/mail/message/m2?account=b');
|
||||
expect(initialLinkSearch('mail')).toBe('?account=a');
|
||||
});
|
||||
});
|
||||
|
||||
describe('useLiteLinkSegments', () => {
|
||||
beforeEach(() => {
|
||||
sessionStorage.clear();
|
||||
|
||||
@@ -53,3 +53,16 @@ export function useLiteLinkSegments(surface: AppSurface, linkSegments?: string[]
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* The query a surface was opened with, for a caller that reads it during its
|
||||
* first render: until the effect above restores a parked deep link, the
|
||||
* address bar shows the surface root without the link's query (#1352).
|
||||
*/
|
||||
export function initialLinkSearch(surface: AppSurface): string {
|
||||
const pending = IS_LITE ? peekPendingLitePath(surface, getPathPrefix()) : null;
|
||||
if (pending === null) return window.location.search;
|
||||
const query = pending.split('#')[0];
|
||||
const start = query.indexOf('?');
|
||||
return start === -1 ? '' : query.slice(start);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user