Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
99f5a85
Give status tiles a tooltip label, add the mail glyphs, and leave tex…
heliocosta-dev Oct 16, 2026
f37aa26
Share the email events strip's node, connector and placeholder
heliocosta-dev Oct 16, 2026
c9a3408
Draw received email events on the sent strip's nodes
heliocosta-dev Oct 16, 2026
185fdae
Hold the received email's events strip and every auth badge while it …
heliocosta-dev Oct 16, 2026
2652c8e
Lay Emails list rows on one line through a shared lead cell
heliocosta-dev Oct 16, 2026
83a8624
Put every Inboxes row on one line behind a tile naming its kind
heliocosta-dev Oct 16, 2026
45f1090
Show each received email's screening state in All received
heliocosta-dev Oct 16, 2026
8f48f3c
Share the mail clients' quote markers from core's quotes module
heliocosta-dev Oct 16, 2026
438202c
Prepare received HTML for a frame that measures it and shows its links
heliocosta-dev Oct 16, 2026
d63bcb1
Render received HTML in the thread pane, in a frame sized to its content
heliocosta-dev Oct 16, 2026
6fb6852
Keep the label palette, label cap and Trash retention in a client-saf…
heliocosta-dev Oct 16, 2026
25a4eee
Let the dashboard's labels.create take a color
heliocosta-dev Oct 16, 2026
2b8ea4e
Ring read threads, close the open one with an X or Esc, and add Not s…
heliocosta-dev Oct 16, 2026
bba1c24
Pick a label's color when creating it, and rename, recolor or delete …
heliocosta-dev Oct 16, 2026
e26a7a5
Keep Esc on the reply editor's toolbar from closing the thread
heliocosta-dev Oct 16, 2026
3b9e480
Merge branch 'ui/lists' into feat/inbox-ui-polish
heliocosta-dev Oct 16, 2026
41d5f06
Merge branch 'ui/events' into feat/inbox-ui-polish
heliocosta-dev Oct 16, 2026
d72220b
Merge branch 'ui/threads' into feat/inbox-ui-polish
heliocosta-dev Oct 16, 2026
7a774ab
Merge branch 'ui/mail' into feat/inbox-ui-polish
heliocosta-dev Oct 16, 2026
3b56e59
Let Esc close the thread while focus is inside the message
heliocosta-dev Oct 16, 2026
bf0aa27
Read a From value's address from where it ends
heliocosta-dev Oct 16, 2026
603ba6c
Build the message frame from what it will parse, and fold only traili…
heliocosta-dev Oct 16, 2026
3f3efdf
Inline a received message's cid: images for the thread pane
heliocosta-dev Oct 16, 2026
a003a70
Keep the Inboxes list's addresses and catch-all link at laptop widths
heliocosta-dev Oct 16, 2026
a05e5a2
Keep focus and unsaved drafts when the thread pane changes or closes
heliocosta-dev Oct 16, 2026
0bd0b71
Name the label editor's controls in the app's tooltips and to screen …
heliocosta-dev Oct 16, 2026
f363832
Share the label name cap and the preview canvas color
heliocosta-dev Oct 16, 2026
f118b06
Open the received email's events strip on its newest step
heliocosta-dev Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 53 additions & 7 deletions apps/web/messages/en/inboxes.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,35 @@
"labelSearch": "Search or create a label…",
"createLabel": "Create label “{name}”",
"removeLabel": "Remove {label}",
"read": "Read",
"notSpam": "Not spam",
"restore": "Restore",
"trashRetention": "Threads in Trash are deleted {days, plural, one {# day} other {# days}} after they're moved here.",
"labels": {
"edit": "Edit label",
"editHint": "Press the right arrow to edit this label",
"back": "Back",
"name": "Name",
"color": "Color",
"custom": "Custom color",
"delete": "Delete label",
"deleteConfirm": "Delete “{name}”? It's removed from every thread.",
"taken": "A label with this name already exists.",
"limit": "An inbox can have up to {max} labels. Delete one to add another.",
"colors": {
"cyan": "Cyan",
"teal": "Teal",
"green": "Green",
"lime": "Lime",
"yellow": "Yellow",
"orange": "Orange",
"indigo": "Indigo",
"purple": "Purple",
"pink": "Pink",
"brown": "Brown",
"gray": "Gray"
}
},
"unread": "Unread",
"unreadAgent": "Your agent hasn't marked it read yet",
"markRead": "Mark as read",
Expand Down Expand Up @@ -59,7 +88,9 @@
"activity": "Activity"
},
"type": {
"catchAll": "Catch-all"
"catchAll": "Catch-all",
"agent": "Agent inbox",
"human": "People inbox"
},
"col": {
"inbox": "Inbox",
Expand Down Expand Up @@ -87,7 +118,9 @@
"full": "You've reached the inbox limit of your plan. Upgrade to create more."
},
"catchAll": {
"row": "Addresses without an inbox · <link>turn off on the domain</link>"
"row": "Addresses with no inbox",
"turnOff": "Turn off on the domain",
"turnOffLink": "turn off"
},
"create": {
"title": "Create inbox",
Expand Down Expand Up @@ -153,6 +186,15 @@
"quarantined": "Held in quarantine: your agent can't see it until someone releases it.",
"hiddenText": "Hidden text removed"
},
"mail": {
"title": "Message from {name}",
"imagesHidden": "Remote images are hidden to protect your privacy.",
"showImages": "Show images",
"alwaysFor": "Always for {domain}",
"opensInNewTab": "Opens in a new tab",
"showQuoted": "Show quoted text",
"hideQuoted": "Hide quoted text"
},
"draft": {
"title": "Draft · waiting for approval",
"created": "created {time}",
Expand Down Expand Up @@ -222,7 +264,9 @@
"downloadsBlocked": "Downloads are blocked: this email carries malware.",
"chip": {
"code": "code",
"link": "link"
"link": "link",
"codeTip": "Contains a verification code",
"linkTip": "Contains a sign-in link"
},
"gray": {
"dmarcPassNone": "DMARC gray: the message passed DMARC, but the sender's domain publishes p=none, so receivers aren't asked to block mail that fails.",
Expand All @@ -238,6 +282,7 @@
"received": {
"title": "All received",
"hint": "Every email your domains received, including addresses without an inbox.",
"hintShort": "Every email your domains received",
"search": "Search sender, inbox or subject…",
"loadError": "Couldn't load received emails.",
"empty": "No received emails yet.",
Expand All @@ -252,6 +297,7 @@
},
"badge": {
"quarantined": "Quarantined",
"screening": "Screening",
"spam": "Spam",
"virus": "Virus"
},
Expand All @@ -265,7 +311,8 @@
"suspicious": "Suspicious",
"quarantined": "Quarantined",
"spam": "Spam",
"virus": "Virus"
"virus": "Virus",
"screening": "Being screened"
},
"range": {
"h24": "Last 24 hours",
Expand Down Expand Up @@ -296,7 +343,6 @@
"code": "Code",
"link": "Sign-in link",
"linkElsewhere": "The link points to a domain other than the sender's.",
"scores": "Risk (0–100): injection {injection} · phishing {phishing}",
"receivedFor": "Received for",
"messageId": "Message-ID",
"envelopeFrom": "Envelope from",
Expand All @@ -315,9 +361,9 @@
"received": "Received",
"scanned": "Scanned",
"screened": "Screened",
"delivered": "Delivered to {inbox}",
"quarantined": "Quarantined",
"released": "Released by {who}",
"released": "Released",
"releasedBy": "by {who}",
"replied": "Replied",
"forwarded": "Forwarded",
"webhook": "Webhook"
Expand Down
60 changes: 53 additions & 7 deletions apps/web/messages/pt-BR/inboxes.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,35 @@
"labelSearch": "Buscar ou criar etiqueta…",
"createLabel": "Criar etiqueta “{name}”",
"removeLabel": "Remover {label}",
"read": "Lida",
"notSpam": "Não é spam",
"restore": "Restaurar",
"trashRetention": "As conversas na Lixeira são excluídas {days, plural, one {# dia} other {# dias}} depois de chegarem aqui.",
"labels": {
"edit": "Editar etiqueta",
"editHint": "Aperte a seta para a direita para editar esta etiqueta",
"back": "Voltar",
"name": "Nome",
"color": "Cor",
"custom": "Cor personalizada",
"delete": "Excluir etiqueta",
"deleteConfirm": "Excluir “{name}”? Ela sai de todas as conversas.",
"taken": "Já existe uma etiqueta com esse nome.",
"limit": "Uma caixa pode ter até {max} etiquetas. Exclua uma para criar outra.",
"colors": {
"cyan": "Ciano",
"teal": "Verde-água",
"green": "Verde",
"lime": "Verde-limão",
"yellow": "Amarelo",
"orange": "Laranja",
"indigo": "Índigo",
"purple": "Roxo",
"pink": "Rosa",
"brown": "Marrom",
"gray": "Cinza"
}
},
"unread": "Não lida",
"unreadAgent": "O agente ainda não marcou como lida",
"markRead": "Marcar como lida",
Expand Down Expand Up @@ -59,7 +88,9 @@
"activity": "Atividade"
},
"type": {
"catchAll": "Pega-tudo"
"catchAll": "Pega-tudo",
"agent": "Caixa de agente",
"human": "Caixa de pessoas"
},
"col": {
"inbox": "Caixa",
Expand Down Expand Up @@ -87,7 +118,9 @@
"full": "Você chegou ao limite de caixas do seu plano. Faça upgrade para criar mais."
},
"catchAll": {
"row": "Endereços sem caixa de entrada · <link>desligar no domínio</link>"
"row": "Endereços sem caixa",
"turnOff": "Desligar no domínio",
"turnOffLink": "desligar"
},
"create": {
"title": "Criar caixa de entrada",
Expand Down Expand Up @@ -153,6 +186,15 @@
"quarantined": "Retido em quarentena: o agente só vê depois que alguém liberar.",
"hiddenText": "Texto oculto removido"
},
"mail": {
"title": "Mensagem de {name}",
"imagesHidden": "Imagens externas ficam ocultas para proteger sua privacidade.",
"showImages": "Mostrar imagens",
"alwaysFor": "Sempre mostrar de {domain}",
"opensInNewTab": "Abre em uma nova aba",
"showQuoted": "Mostrar texto citado",
"hideQuoted": "Ocultar texto citado"
},
"draft": {
"title": "Rascunho · aguardando aprovação",
"created": "criado {time}",
Expand Down Expand Up @@ -222,7 +264,9 @@
"downloadsBlocked": "Downloads bloqueados: este e-mail tem malware.",
"chip": {
"code": "código",
"link": "link"
"link": "link",
"codeTip": "Contém um código de verificação",
"linkTip": "Contém um link de acesso"
},
"gray": {
"dmarcPassNone": "DMARC cinza: a mensagem passou no DMARC, mas o domínio do remetente usa p=none, então os servidores não são orientados a bloquear e-mails que falham.",
Expand All @@ -238,6 +282,7 @@
"received": {
"title": "Todos os recebidos",
"hint": "Todos os e-mails que seus domínios receberam, inclusive em endereços sem caixa de entrada.",
"hintShort": "Tudo o que chegou nos seus domínios",
"search": "Buscar remetente, caixa ou assunto…",
"loadError": "Não foi possível carregar os e-mails recebidos.",
"empty": "Nenhum e-mail recebido ainda.",
Expand All @@ -252,6 +297,7 @@
},
"badge": {
"quarantined": "Em quarentena",
"screening": "Em análise",
"spam": "Spam",
"virus": "Vírus"
},
Expand All @@ -265,7 +311,8 @@
"suspicious": "Suspeito",
"quarantined": "Em quarentena",
"spam": "Spam",
"virus": "Vírus"
"virus": "Vírus",
"screening": "Em análise"
},
"range": {
"h24": "Últimas 24 horas",
Expand Down Expand Up @@ -296,7 +343,6 @@
"code": "Código",
"link": "Link de acesso",
"linkElsewhere": "O link aponta para um domínio diferente do remetente.",
"scores": "Risco (0–100): injeção {injection} · phishing {phishing}",
"receivedFor": "Recebido por",
"messageId": "Message-ID",
"envelopeFrom": "Remetente do envelope",
Expand All @@ -315,9 +361,9 @@
"received": "Recebido",
"scanned": "Verificado",
"screened": "Analisado",
"delivered": "Entregue em {inbox}",
"quarantined": "Em quarentena",
"released": "Liberado por {who}",
"released": "Liberado",
"releasedBy": "por {who}",
"replied": "Respondido",
"forwarded": "Encaminhado",
"webhook": "Webhook"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"
import { createPortal } from "react-dom";
import { useAnchoredPanel } from "@/components/anchored-panel";
import { PlusGlyph } from "@/components/icons/nav-icons";
import { FOCUSABLE } from "@/components/modal";
import { Select, type SelectOption } from "@/components/select";
import { FOCUSABLE } from "@/lib/keyboard";
import {
BASE_FIELDS,
type BuilderRow,
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/(dashboard)/broadcasts/parts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useMemo } from "react";
import { DotParts } from "@/components/dot-parts";
import { PreviewSchemePills } from "@/components/preview-scheme-pills";
import type { TONE_COLOR } from "@/components/status-tile";
import { emulateEmailScheme } from "@/lib/email-preview";
import { emulateEmailScheme, PREVIEW_CANVAS } from "@/lib/email-preview";
import {
formatDayTime,
formatFinishAbout,
Expand Down Expand Up @@ -470,7 +470,7 @@ export function ContentPreview({
width: "100%",
height: 560,
border: 0,
background: scheme === "dark" ? "#111113" : "#ffffff",
background: PREVIEW_CANVAS[scheme],
}}
/>
</div>
Expand Down
Loading
Loading