Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
99 changes: 99 additions & 0 deletions app.css
Original file line number Diff line number Diff line change
Expand Up @@ -4659,3 +4659,102 @@ footer a:hover { color: var(--accent-2); }
.ds-desc { padding: 0 1rem .6rem; }
.ds-cta { margin: .2rem 1rem 1rem; }
}

/* ── EMAILMESSAGE (email client reading pane) ── */
.card.email-pane {
background: var(--card);
border-radius: var(--radius);
}
.card.email-pane .hd.hidden { display: none; }

.em-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: .8rem;
padding: 1.5rem 1.5rem .8rem;
}
.em-subject {
font-size: 1.2rem;
font-weight: 700;
color: var(--ink);
line-height: 1.3;
flex: 1;
}
.em-date {
font-size: .78rem;
color: var(--muted);
white-space: nowrap;
padding-top: .15rem;
}

.em-participant {
display: flex;
align-items: center;
gap: .6rem;
padding: .35rem 1.5rem;
}
.em-avatar {
width: 34px;
height: 34px;
border-radius: 50%;
background: var(--accent);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: .85rem;
font-weight: 700;
flex-shrink: 0;
}
.em-avatar-to {
background: var(--muted);
}
.em-participant-info {
display: flex;
gap: .4rem;
align-items: baseline;
}
.em-participant-role {
font-size: .68rem;
color: var(--muted-2);
font-weight: 600;
text-transform: uppercase;
letter-spacing: .05em;
}
.em-participant-name {
font-size: .88rem;
font-weight: 600;
color: var(--ink);
}

.em-divider {
height: 1px;
background: var(--line);
margin: .6rem 1.5rem;
}

.em-body {
font-size: .88rem;
line-height: 1.65;
color: var(--ink-2);
padding: 0 1.5rem .8rem;
}

.em-excerpt {
font-size: .82rem;
line-height: 1.55;
color: var(--muted);
padding: .6rem 1.5rem;
border-top: 1px solid var(--line-2);
margin: 0 1.5rem;
font-style: italic;
}

@media (max-width: 480px) {
.em-header { padding: 1.2rem 1rem .6rem; }
.em-subject { font-size: 1.05rem; }
.em-participant { padding: .3rem 1rem; }
.em-body { padding: 0 1rem .6rem; }
.em-excerpt { padding: .5rem 1rem; margin: 0 1rem; }
}
83 changes: 83 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2506,6 +2506,89 @@
handled.add("hasMenuSection"); handled.add("provider"); handled.add("url");
}

// ── EMAILMESSAGE (email client reading pane) ──
if (cfg.type === "EmailMessage") {
const card = document.querySelector(".card");
if (card) card.classList.add("email-pane");

// Hide normal header
const hd = document.querySelector(".hd");
if (hd) hd.classList.add("hidden");

// Remove generic hero
const heroMount = document.getElementById("hero-mount");
if (heroMount) heroMount.querySelector('.hero')?.remove();

// ── Subject line big at top, date right-aligned ──
const header = document.createElement("div"); header.className = "em-header";
const subject = data[cfg.titleProp];
if (subject) {
const subjEl = document.createElement("div"); subjEl.className = "em-subject";
subjEl.textContent = subject;
header.appendChild(subjEl);
}
const dateSent = data["dateSent"];
if (dateSent) {
const d = formatDate(dateSent);
const dateEl = document.createElement("div"); dateEl.className = "em-date";
dateEl.textContent = d || dateSent;
header.appendChild(dateEl);
}
view.appendChild(header);

// ── From row with avatar initial circle ──
const sender = data["sender"];
const senderName = (typeof sender === "object" && sender !== null) ? (sender.name || "") : (sender || "");
if (senderName) {
const row = document.createElement("div"); row.className = "em-participant";
const avatar = document.createElement("div"); avatar.className = "em-avatar";
avatar.textContent = senderName.charAt(0).toUpperCase();
const info = document.createElement("div"); info.className = "em-participant-info";
info.innerHTML = "<div class=\"em-participant-role\">From</div><div class=\"em-participant-name\">" + senderName + "</div>";
row.appendChild(avatar);
row.appendChild(info);
view.appendChild(row);
}

// ── To row ──
const toRecipient = data["toRecipient"];
const toName = (typeof toRecipient === "object" && toRecipient !== null) ? (toRecipient.name || "") : (toRecipient || "");
if (toName) {
const row = document.createElement("div"); row.className = "em-participant";
const avatar = document.createElement("div"); avatar.className = "em-avatar em-avatar-to";
avatar.textContent = toName.charAt(0).toUpperCase();
const info = document.createElement("div"); info.className = "em-participant-info";
info.innerHTML = "<div class=\"em-participant-role\">To</div><div class=\"em-participant-name\">" + toName + "</div>";
row.appendChild(avatar);
row.appendChild(info);
view.appendChild(row);
}

// ── Divider ──
const divider = document.createElement("div"); divider.className = "em-divider";
view.appendChild(divider);

// ── Email body (description) ──
const desc = data["description"];
if (desc) {
const body = document.createElement("div"); body.className = "em-body";
body.textContent = desc;
view.appendChild(body);
}

// Excerpt as preview text
const text = data["text"];
if (text) {
const excerpt = document.createElement("div"); excerpt.className = "em-excerpt";
excerpt.textContent = text;
view.appendChild(excerpt);
}

handled.add("name"); handled.add("image"); handled.add("description");
handled.add("sender"); handled.add("toRecipient"); handled.add("dateSent");
handled.add("text");
}

// ── DATASET (open-data portal card) ──
if (cfg.type === "Dataset") {
const card = document.querySelector(".card");
Expand Down
Loading