Files
ihasmail/web/src/lib/identityVisibility.ts
T
jcoffey-dev 133036a6c5 Hide identities from the compose picker
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.
2026-08-26 15:36:35 -07:00

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);
}