An account using a unique address per service, on a server with an alias domain, ends up with every local part twice over and a From picker nobody can use -- while only ever sending from a handful (#73). Identities can now be hidden from that picker, from Identities & signatures. Hiding is presentation only: the identity still exists, still receives, and stays listed and editable, the way an unsubscribed folder is still a folder. That framing is mbunkus's own, and it is the right one -- this is a UI preference, not a change to the account. Three things it refuses to do, because a sender picker with nothing usable in it is worse than a cluttered one: - it will not hide the identity a draft is already using, which would leave the select with no matching option and move the From line under the writer - it will not hide the default, which is what a new draft starts on; the button is disabled there and says why - if every identity is somehow hidden -- reachable only through settings sync, since the UI will not do it -- they are all offered again The setting syncs, so the picker looks the same on every device, which follows from DEVICE_KEYS being a list of exceptions rather than a list of what travels. Verified against the mock with four identities and one hidden: the picker offers the other three, the hidden address is gone from composing, the default's hide button is disabled, and the row says the identity still receives.
37 lines
1.5 KiB
TypeScript
37 lines
1.5 KiB
TypeScript
/**
|
|
* Which identities the compose picker offers.
|
|
*
|
|
* Someone using a unique address per service, on a server with an alias domain,
|
|
* ends up with every local part twice and a picker they cannot use — while only
|
|
* ever sending from a handful (#73). Hiding is presentation only: the identity
|
|
* still exists, still receives, and is still listed in Settings, the same way an
|
|
* unsubscribed folder is still a folder.
|
|
*
|
|
* Three things it will not do, because a sender picker that cannot offer a
|
|
* sender is worse than a cluttered one:
|
|
*
|
|
* - hide the identity a draft is already using, which would leave the select
|
|
* with no matching option and reset the From line under the writer
|
|
* - hide the default identity, which is what a new draft starts on
|
|
* - hide everything; if every identity is hidden it shows them all instead
|
|
*/
|
|
import type { Identity } from "@/jmap/types";
|
|
|
|
export function visibleIdentities<T extends Pick<Identity, "id">>(
|
|
identities: T[],
|
|
hidden: readonly string[],
|
|
keep: Array<string | null | undefined> = [],
|
|
): T[] {
|
|
if (!hidden.length) return identities;
|
|
const hide = new Set(hidden);
|
|
for (const k of keep) if (k) hide.delete(k);
|
|
const shown = identities.filter((i) => !hide.has(i.id));
|
|
// Everything hidden: show the lot rather than an empty picker.
|
|
return shown.length ? shown : identities;
|
|
}
|
|
|
|
/** Whether hiding this one would be refused, so the UI can say so. */
|
|
export function isAlwaysVisible(id: string, keep: Array<string | null | undefined>): boolean {
|
|
return keep.some((k) => k === id);
|
|
}
|