81 lines
1.9 KiB
TypeScript
81 lines
1.9 KiB
TypeScript
import type { Email } from "@/lib/email-data"
|
|
import type { InboxSortMode } from "@/lib/mail-settings/types"
|
|
import { isListRowRead } from "@/lib/mail-thread"
|
|
|
|
export type MailSortContext = {
|
|
readOverrides: Record<string, boolean>
|
|
starredIds: string[]
|
|
importantIds: string[]
|
|
}
|
|
|
|
export type MailSortOptions = {
|
|
conversationMode: boolean
|
|
byId: Map<string, Email>
|
|
}
|
|
|
|
function mailTimestamp(email: Email): number {
|
|
const t = new Date(email.date).getTime()
|
|
return Number.isFinite(t) ? t : 0
|
|
}
|
|
|
|
function compareByDateDesc(a: Email, b: Email): number {
|
|
return mailTimestamp(b) - mailTimestamp(a)
|
|
}
|
|
|
|
function isUnread(
|
|
email: Email,
|
|
ctx: MailSortContext,
|
|
opts: MailSortOptions
|
|
): boolean {
|
|
return !isListRowRead(
|
|
email,
|
|
ctx.readOverrides,
|
|
opts.byId,
|
|
opts.conversationMode
|
|
)
|
|
}
|
|
|
|
function isStarred(email: Email, ctx: MailSortContext): boolean {
|
|
const storeId = email.threadHeadId ?? email.id
|
|
return ctx.starredIds.includes(storeId) || email.starred
|
|
}
|
|
|
|
function isImportant(email: Email, ctx: MailSortContext): boolean {
|
|
const storeId = email.threadHeadId ?? email.id
|
|
return ctx.importantIds.includes(storeId) || email.important
|
|
}
|
|
|
|
export function sortEmailsForInbox(
|
|
rows: Email[],
|
|
mode: InboxSortMode,
|
|
ctx: MailSortContext,
|
|
opts: MailSortOptions
|
|
): Email[] {
|
|
const sorted = [...rows]
|
|
if (mode === "default") {
|
|
sorted.sort(compareByDateDesc)
|
|
return sorted
|
|
}
|
|
|
|
sorted.sort((a, b) => {
|
|
let primary = 0
|
|
switch (mode) {
|
|
case "important":
|
|
primary =
|
|
Number(isImportant(b, ctx)) - Number(isImportant(a, ctx))
|
|
break
|
|
case "unread":
|
|
primary = Number(isUnread(b, ctx, opts)) - Number(isUnread(a, ctx, opts))
|
|
break
|
|
case "starred":
|
|
primary = Number(isStarred(b, ctx)) - Number(isStarred(a, ctx))
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
if (primary !== 0) return primary
|
|
return compareByDateDesc(a, b)
|
|
})
|
|
return sorted
|
|
}
|