This commit is contained in:
Maurus Decimus
2026-07-31 15:52:36 +02:00
parent 189e270785
commit 8cab61a9c5
13 changed files with 156 additions and 72 deletions
+53
View File
@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
import {
findFirstAccessibleLinkInLayout,
findFirstVisibleLinkInLayout,
isLinkAccessible,
type CanGet,
type HasPermission,
} from '@/lib/layout';
import type { Layout, Schema } from '@/types/schema';
const STORAGE_KEY = 'stalwart-last-visited';
function readAll(): Record<string, unknown> {
try {
const raw = localStorage.getItem(STORAGE_KEY);
const parsed: unknown = raw ? JSON.parse(raw) : null;
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : {};
} catch {
return {};
}
}
export function rememberLastVisited(section: string, viewName: string): void {
try {
const all = readAll();
if (all[section] === viewName) return;
localStorage.setItem(STORAGE_KEY, JSON.stringify({ ...all, [section]: viewName }));
} catch {
return;
}
}
export function sectionLandingLink(
schema: Schema,
layout: Layout,
edition: string,
canGet: CanGet,
hasPerm?: HasPermission,
): string | null {
const last = readAll()[layout.name];
if (typeof last === 'string' && isLinkAccessible(schema, last, edition, canGet, hasPerm)) {
return last;
}
return (
findFirstAccessibleLinkInLayout(schema, layout, edition, canGet, hasPerm) ??
findFirstVisibleLinkInLayout(schema, layout, edition, canGet, hasPerm)
);
}
+40
View File
@@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
import { getApiBaseUrl } from '@/services/api';
export type LogoState = { status: 'loading' } | { status: 'custom'; url: string } | { status: 'default' };
let state: LogoState = { status: 'loading' };
let started = false;
const listeners = new Set<() => void>();
export function getLogoState(): LogoState {
return state;
}
export function subscribeToLogo(listener: () => void): () => void {
listeners.add(listener);
return () => {
listeners.delete(listener);
};
}
export function loadLogoOnce(): void {
if (started) return;
started = true;
fetch(`${getApiBaseUrl()}/logo`)
.then(async (response) => {
const contentType = response.headers.get('content-type') ?? '';
if (!response.ok || !contentType.startsWith('image/')) return null;
return URL.createObjectURL(await response.blob());
})
.catch(() => null)
.then((url) => {
state = url ? { status: 'custom', url } : { status: 'default' };
listeners.forEach((notify) => notify());
});
}