UI enhancement
This commit is contained in:
parent
45e3898acb
commit
23239c5cb6
5 changed files with 225 additions and 129 deletions
|
|
@ -2,6 +2,41 @@ import colorMap from "../data/az_2_letter_color_map.json";
|
|||
|
||||
const FALLBACK_COLOR = "#5c5763";
|
||||
|
||||
const PERSONAL_DOMAINS = new Set([
|
||||
"gmail.com",
|
||||
"googlemail.com",
|
||||
"yahoo.com",
|
||||
"hotmail.com",
|
||||
"outlook.com",
|
||||
"live.com",
|
||||
"icloud.com",
|
||||
"me.com",
|
||||
"proton.me",
|
||||
"protonmail.com",
|
||||
"aol.com",
|
||||
]);
|
||||
|
||||
const BRAND_MATCHERS = [
|
||||
{ tokens: ["google", "google cloud"], domain: "google.com" },
|
||||
{ tokens: ["github"], domain: "github.com" },
|
||||
{ tokens: ["twilio"], domain: "twilio.com" },
|
||||
{ tokens: ["meta", "facebook", "instagram"], domain: "meta.com" },
|
||||
{ tokens: ["microsoft", "azure", "office 365"], domain: "microsoft.com" },
|
||||
{ tokens: ["amazon", "aws"], domain: "amazon.com" },
|
||||
{ tokens: ["apple"], domain: "apple.com" },
|
||||
{ tokens: ["stripe"], domain: "stripe.com" },
|
||||
{ tokens: ["slack"], domain: "slack.com" },
|
||||
{ tokens: ["notion"], domain: "notion.so" },
|
||||
{ tokens: ["linkedin"], domain: "linkedin.com" },
|
||||
{ tokens: ["dropbox"], domain: "dropbox.com" },
|
||||
{ tokens: ["zoom"], domain: "zoom.us" },
|
||||
{ tokens: ["atlassian", "jira"], domain: "atlassian.com" },
|
||||
];
|
||||
|
||||
function faviconUrl(domain) {
|
||||
return `https://www.google.com/s2/favicons?domain=${domain}&sz=64`;
|
||||
}
|
||||
|
||||
export function addressText(sender) {
|
||||
if (typeof sender === "string") return sender;
|
||||
return sender?.email || sender?.address || "";
|
||||
|
|
@ -17,7 +52,6 @@ export function senderDisplayName(email) {
|
|||
return displayName?.trim() || address.split("@")[0] || "Unknown sender";
|
||||
}
|
||||
|
||||
/** Two-letter key for color lookup: first + last word, or first two chars. */
|
||||
export function initialsFromName(name) {
|
||||
const cleaned = String(name || "")
|
||||
.trim()
|
||||
|
|
@ -46,18 +80,39 @@ export function colorForInitials(initials) {
|
|||
return colorMap[key] || FALLBACK_COLOR;
|
||||
}
|
||||
|
||||
/** Registered-user avatar URL hook — wire when profile photos exist. */
|
||||
export function senderAvatarUrl(email) {
|
||||
return email.sender_avatar_url || email.sender?.avatar_url || null;
|
||||
}
|
||||
|
||||
export function brandLogoUrl(email) {
|
||||
const address = addressText(email.sender || email.from).toLowerCase();
|
||||
const name = senderDisplayName(email).toLowerCase();
|
||||
const emailDomain = address.split("@")[1] || "";
|
||||
const haystack = `${name} ${address} ${emailDomain}`;
|
||||
|
||||
for (const brand of BRAND_MATCHERS) {
|
||||
if (brand.tokens.some((token) => haystack.includes(token))) {
|
||||
return faviconUrl(brand.domain);
|
||||
}
|
||||
}
|
||||
|
||||
if (emailDomain && !PERSONAL_DOMAINS.has(emailDomain)) {
|
||||
return faviconUrl(emailDomain);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function senderAvatar(email) {
|
||||
const name = senderDisplayName(email);
|
||||
const initials = initialsFromName(name);
|
||||
const profileUrl = senderAvatarUrl(email);
|
||||
const brandUrl = profileUrl ? null : brandLogoUrl(email);
|
||||
return {
|
||||
name,
|
||||
initials,
|
||||
color: colorForInitials(initials),
|
||||
imageUrl: senderAvatarUrl(email),
|
||||
imageUrl: profileUrl,
|
||||
brandUrl,
|
||||
isBrand: Boolean(brandUrl),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue