// Left rail — the day's items, filter chips, hover statusbar for one-click
// status changes. Status glyphs: ★ featured, ● used, ◌ context, ⊘ hidden.
function Rail({ items, allCount, inPost, filter, setFilter, selectedItem, setSelectedItem, setItemStatus, deleteItem, moveItemToYesterday }) {
const filters = [
{ k: "all", l: "All" },
{ k: "in-post", l: "In post" },
{ k: "context", l: "Context" },
{ k: "hidden", l: "Hidden" },
];
return (
);
}
function ItemRow({ item, selected, onSelect, setStatus, onDelete, onMoveYesterday }) {
const meta = (() => {
const t = item.captured_at ? new Date(item.captured_at * 1000) : null;
if (!t) return "--:--";
return t.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", hour12: false });
})();
const summary = item.caption || item.description || item.transcript || item.text_body || item.filename || "";
const onDragStart = (e) => {
// Note: we only know MIME-y types when inspecting on drop; set both so
// either key works across browsers.
e.dataTransfer.setData("application/x-postcard-item", item.id);
e.dataTransfer.setData("text/x-postcard-item", item.id);
e.dataTransfer.setData("text/plain", `item:${item.id}`);
e.dataTransfer.effectAllowed = "copy";
};
return (
{KIND_LABEL[item.kind] || "OBJ"}
{item.kind === "photo" || item.kind === "video" ? (
})
{ e.target.style.display = "none"; }} />
) : (
{item.kind === "voice" && "▶"}
{item.kind === "audio" && "♪"}
{item.kind === "text" && "¶"}
)}
{STATUS_GLYPH[item.status]}
{meta}
{item.kind}
{item.filename && {item.filename}}
{summary}
e.stopPropagation()}>
{STATUS_ORDER.map((s) => (
))}
{selected &&
}
);
}
function ItemPreview({ item, onDelete, onMoveYesterday }) {
return (
e.stopPropagation()}>
{item.kind === "photo" && (
})
)}
{item.kind === "video" && (
)}
{(item.kind === "voice" || item.kind === "audio") && (
)}
{item.kind === "text" && item.text_body && (
{item.text_body}
)}
{item.caption && (
caption
{item.caption}
)}
{item.transcript && (item.kind === "voice" || item.kind === "audio") && (
transcript
{item.transcript}
)}
{item.description && item.kind === "photo" && (
ai
{item.description}
)}
);
}
Object.assign(window, { Rail });