AkurAI Build
Menu

Public repository / 44bac58a05a32fe23c63b2b1f4bec30b0428c016

AkurAI-Mail / src/lib/webmail/MessageReader.svelte

Latest change 44bac58a05a32fe23c63b2b1f4bec30b0428c016 - AKURAI-MAIL-5 split webmail view components by Ólafur Búi Ólafsson

<script lang="ts">
  import { Archive, ArrowLeft, Download, FileText, Forward, Paperclip, Reply, ReplyAll, ShieldAlert, Star, Trash2 } from "lucide-svelte";
  let { selected, selectedDate, current, reply, forward, post, onBack, downloadAttachment, onDelete } = $props();
</script>

<section class="reader-column" aria-label="Message reader">
  {#if selected}
    <div class="reader-toolbar" role="toolbar" aria-label="Message actions"><button class="icon-button mobile-back" aria-label="Back to messages" title="Back to messages" onclick={onBack}><ArrowLeft size={18} /></button><button class="toolbar-button" onclick={() => reply(false)}><Reply size={17} /> <span>Reply</span></button><button class="toolbar-button" onclick={() => reply(true)}><ReplyAll size={17} /> <span>Reply all</span></button><button class="toolbar-button" onclick={forward}><Forward size={17} /> <span>Forward</span></button><span class="toolbar-divider"></span><button class="icon-button" aria-label={selected.flagged ? "Remove star" : "Add star"} title={selected.flagged ? "Remove star" : "Add star"} onclick={() => post({ action: "message", id: selected.id, messageAction: selected.flagged ? "unstar" : "star" })}><Star size={18} fill={selected.flagged ? "currentColor" : "none"} /></button><button class="icon-button" aria-label="Archive message" title="Archive message" onclick={() => post({ action: "message", id: selected.id, messageAction: "archive" })}><Archive size={18} /></button><button class="icon-button" aria-label="Mark as spam" title="Mark as spam" onclick={() => post({ action: "message", id: selected.id, messageAction: "spam" })}><ShieldAlert size={18} /></button><button class="icon-button destructive" aria-label="Delete message" title="Delete message" onclick={onDelete}><Trash2 size={18} /></button></div>
    <article class="reader-card"><header class="reader-head"><div class="reader-title"><h1>{selected.subject || "(no subject)"}</h1><p>{selectedDate ? selectedDate.toLocaleString() : selected.date}</p></div><dl><div><dt>From</dt><dd>{selected.from || "(unknown)"}</dd></div><div><dt>To</dt><dd>{selected.to || current}</dd></div></dl></header>{#if selected.spamReasons?.length}<div class="warning"><ShieldAlert size={18} /><span><strong>Spam signals</strong>{selected.spamReasons.join(", ")}</span></div>{/if}<div class="message-body">{@html selected.bodyHtml}</div>{#if selected.attachments?.length}<section class="attachments" aria-label="Attachments"><strong><Paperclip size={17} /> Attachments</strong><div>{#each selected.attachments as file}<button class="attachment" onclick={() => downloadAttachment(file)}><FileText size={18} /><span><b>{file.filename}</b><small>{Math.ceil(file.size / 1024)} KB</small></span><Download size={17} /></button>{/each}</div></section>{/if}</article>
  {:else}<div class="reader-empty"><div class="empty-icon"><Star size={25} strokeWidth={1.5} /></div><strong>Choose a conversation</strong><p>Select a message to read it here. Your inbox stays visible while you work.</p></div>{/if}
</section>