UI enhancement

This commit is contained in:
debu-2 2026-10-03 22:28:20 +05:30
parent 45e3898acb
commit 23239c5cb6
5 changed files with 225 additions and 129 deletions

View file

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