ultisuite-client/lib/mail-url.ts

152 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** Routage URL sous `/mail` : dossier, onglet boîte de réception, page, message ouvert. */
import {
cloneDefaultLabelRows,
tabbedInboxLabelRows,
} from "@/lib/sidebar-nav-data"
export const DEFAULT_MAIL_FOLDER = "inbox"
export const DEFAULT_INBOX_TAB = "primary"
/** Onglet boîte : tous les messages inbox sans filtre libellé catégorie. */
export const INBOX_ALL_TAB = "all"
/** Onglets sans pastille « nouveaux » ni ligne expéditeurs quand inactifs. */
export function inboxTabShowsInactiveMeta(tabId: string): boolean {
const tab = normalizeInboxTabSegment(tabId)
return tab !== DEFAULT_INBOX_TAB && tab !== INBOX_ALL_TAB
}
/** Segments dURL historiques → ids libellés actuels. */
const LEGACY_INBOX_TAB_SEGMENT: Record<string, string> = {
updates: "mises-a-jour",
notifications: "newsletters",
social: "reseaux-sociaux",
purchases: "achats",
travel: "deplacements",
}
export function normalizeInboxTabSegment(tab: string): string {
return LEGACY_INBOX_TAB_SEGMENT[tab] ?? tab
}
function defaultInboxTabIdSet(): Set<string> {
const s = new Set<string>([DEFAULT_INBOX_TAB, INBOX_ALL_TAB])
for (const r of tabbedInboxLabelRows(cloneDefaultLabelRows())) {
s.add(r.id)
}
return s
}
/** Onglets boîte de réception reconnus dans lURL (ids courants + segments legacy). */
export const INBOX_CATEGORY_TAB_IDS = (() => {
const s = defaultInboxTabIdSet()
for (const legacy of Object.keys(LEGACY_INBOX_TAB_SEGMENT)) {
s.add(legacy)
}
return s
})()
export type MailRouteState = {
folderId: string
/** Onglet catégorie ; pour `folderId !== inbox`, valeur ignorée par le filtre mais peut rester `primary`. */
inboxTab: string
page: number
mailId: string | null
}
const DEFAULT_STATE: MailRouteState = {
folderId: DEFAULT_MAIL_FOLDER,
inboxTab: DEFAULT_INBOX_TAB,
page: 1,
mailId: null,
}
function decodeSegment(s: string): string {
try {
return decodeURIComponent(s)
} catch {
return s
}
}
/**
* Parse le tableau de segments Next (sans le préfixe `mail`).
* Ex. `['inbox','promotions','page','2','message','1']`
*/
export function parseMailSegments(
segments: string[] | undefined | null
): MailRouteState {
const raw = segments?.filter((x) => x.length > 0) ?? []
if (raw.length === 0) return { ...DEFAULT_STATE }
const parts = [...raw]
let mailId: string | null = null
let page = 1
if (parts.length >= 2 && parts[parts.length - 2] === "message") {
mailId = decodeSegment(parts[parts.length - 1]!)
parts.length -= 2
}
if (parts.length >= 2 && parts[parts.length - 2] === "page") {
const n = parseInt(parts[parts.length - 1]!, 10)
page = Number.isFinite(n) && n >= 1 ? n : 1
parts.length -= 2
}
if (parts.length === 0) {
return { ...DEFAULT_STATE, mailId, page }
}
const folderId = parts[0]!
if (folderId === "inbox") {
if (parts.length >= 2) {
const tab = parts[1]!
if (INBOX_CATEGORY_TAB_IDS.has(tab)) {
const inboxTab = normalizeInboxTabSegment(tab)
const valid = defaultInboxTabIdSet()
return {
folderId,
inboxTab: valid.has(inboxTab) ? inboxTab : DEFAULT_INBOX_TAB,
page,
mailId,
}
}
return { folderId, inboxTab: DEFAULT_INBOX_TAB, page, mailId }
}
return { folderId, inboxTab: DEFAULT_INBOX_TAB, page, mailId }
}
return {
folderId,
inboxTab: DEFAULT_INBOX_TAB,
page,
mailId,
}
}
function encodePathSegment(s: string): string {
return encodeURIComponent(s)
}
export function buildMailPath(r: MailRouteState): string {
const segs: string[] = ["mail", encodeURIComponent(r.folderId)]
if (r.folderId === "inbox") {
const tab = normalizeInboxTabSegment(r.inboxTab || DEFAULT_INBOX_TAB)
if (tab !== DEFAULT_INBOX_TAB) {
segs.push(tab)
}
}
if (r.page > 1) {
segs.push("page", String(r.page))
}
if (r.mailId) {
segs.push("message", encodePathSegment(r.mailId))
}
return `/${segs.join("/")}`
}