Styling
This commit is contained in:
113
history.css
113
history.css
@@ -1,12 +1,12 @@
|
|||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Arial, sans-serif;
|
font-family: Inter, "Segoe UI", Arial, sans-serif;
|
||||||
background: #0e1117;
|
background: #070909;
|
||||||
color: #e6edf7;
|
color: #e7f0e9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-page {
|
.history-page {
|
||||||
max-width: 960px;
|
max-width: 1000px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
color: #aeb7cc;
|
color: #8ea292;
|
||||||
}
|
}
|
||||||
|
|
||||||
#historyList {
|
#historyList {
|
||||||
@@ -25,43 +25,98 @@ p {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-item {
|
.history-item {
|
||||||
border: 1px solid #2a2f40;
|
border: 1px solid #1d2620;
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
padding: 12px;
|
padding: 10px;
|
||||||
background: #151a26;
|
background: #0d1210;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-head {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-info {
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-cover-image {
|
.history-cover-image {
|
||||||
width: 48px;
|
width: 44px;
|
||||||
height: 48px;
|
height: 44px;
|
||||||
border-radius: 6px;
|
border-radius: 7px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
display: block;
|
border: 1px solid #243027;
|
||||||
margin-bottom: 10px;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-url {
|
.history-title {
|
||||||
margin: 0 0 8px;
|
margin: 0;
|
||||||
word-break: break-all;
|
color: #eff8f1;
|
||||||
color: #d2d9ea;
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
word-break: break-word;
|
||||||
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-meta {
|
.history-subtitle {
|
||||||
margin: 0 0 10px;
|
margin: 3px 0 0;
|
||||||
color: #98a5c0;
|
color: #94a89a;
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
.history-badges {
|
||||||
border: 1px solid #2f66ff;
|
margin-top: 8px;
|
||||||
background: #2f66ff;
|
display: flex;
|
||||||
color: #fff;
|
gap: 6px;
|
||||||
border-radius: 6px;
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
border: 1px solid #2d4f35;
|
||||||
|
background: #142219;
|
||||||
|
color: #bde6c6;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 10px;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-tags {
|
||||||
|
margin: 4px 0 0;
|
||||||
|
color: #b3c9b8;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.3;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-icon-btn {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border: 1px solid #2f9e5a;
|
||||||
|
background: #1b7f45;
|
||||||
|
color: #f1fff4;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 6px 10px;
|
flex-shrink: 0;
|
||||||
|
transition: background 120ms ease, transform 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-icon-btn:hover {
|
||||||
|
background: #249452;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-icon-btn:active {
|
||||||
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
<main class="history-page">
|
<main class="history-page">
|
||||||
<header>
|
<header>
|
||||||
<h1>S3 Audio Capture History</h1>
|
<h1>S3 Audio Capture History</h1>
|
||||||
<p>All captured Splice S3 URLs.</p>
|
|
||||||
</header>
|
</header>
|
||||||
<p id="status">Loading history...</p>
|
<p id="status">Loading history...</p>
|
||||||
<ul id="historyList"></ul>
|
<ul id="historyList"></ul>
|
||||||
|
|||||||
106
history.js
106
history.js
@@ -3,51 +3,101 @@
|
|||||||
const statusEl = document.getElementById("status");
|
const statusEl = document.getElementById("status");
|
||||||
const listEl = document.getElementById("historyList");
|
const listEl = document.getElementById("historyList");
|
||||||
|
|
||||||
function formatDate(ms) {
|
|
||||||
try {
|
|
||||||
return new Date(ms).toLocaleString();
|
|
||||||
} catch (error) {
|
|
||||||
return "unknown time";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatMeta(entry) {
|
function formatMeta(entry) {
|
||||||
const packName = entry && entry.packName ? entry.packName : "n/a";
|
const packName = entry && entry.packName ? entry.packName : "n/a";
|
||||||
const key = entry && entry.key ? entry.key : "n/a";
|
const key = entry && entry.key ? entry.key : "n/a";
|
||||||
const bpm = entry && entry.bpm ? entry.bpm : "n/a";
|
const bpm = entry && entry.bpm ? entry.bpm : "n/a";
|
||||||
const tags = entry && Array.isArray(entry.tags) && entry.tags.length ? entry.tags.join(", ") : "n/a";
|
return { packName, key, bpm };
|
||||||
return `Pack: ${packName} | Key: ${key} | BPM: ${bpm} | Tags: ${tags}`;
|
}
|
||||||
|
|
||||||
|
function formatTags(entry) {
|
||||||
|
if (!entry || !Array.isArray(entry.tags) || !entry.tags.length) {
|
||||||
|
return "No tags";
|
||||||
|
}
|
||||||
|
return entry.tags.join(" • ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDownloadIcon() {
|
||||||
|
const ns = "http://www.w3.org/2000/svg";
|
||||||
|
const svg = document.createElementNS(ns, "svg");
|
||||||
|
svg.setAttribute("viewBox", "0 0 24 24");
|
||||||
|
svg.setAttribute("width", "22");
|
||||||
|
svg.setAttribute("height", "22");
|
||||||
|
svg.setAttribute("aria-hidden", "true");
|
||||||
|
|
||||||
|
const arrow = document.createElementNS(ns, "path");
|
||||||
|
arrow.setAttribute("d", "M12 4v10m0 0l4-4m-4 4l-4-4");
|
||||||
|
arrow.setAttribute("fill", "none");
|
||||||
|
arrow.setAttribute("stroke", "currentColor");
|
||||||
|
arrow.setAttribute("stroke-width", "2");
|
||||||
|
arrow.setAttribute("stroke-linecap", "round");
|
||||||
|
arrow.setAttribute("stroke-linejoin", "round");
|
||||||
|
|
||||||
|
const tray = document.createElementNS(ns, "path");
|
||||||
|
tray.setAttribute("d", "M4 18v1a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-1");
|
||||||
|
tray.setAttribute("fill", "none");
|
||||||
|
tray.setAttribute("stroke", "currentColor");
|
||||||
|
tray.setAttribute("stroke-width", "2");
|
||||||
|
tray.setAttribute("stroke-linecap", "round");
|
||||||
|
tray.setAttribute("stroke-linejoin", "round");
|
||||||
|
|
||||||
|
svg.appendChild(arrow);
|
||||||
|
svg.appendChild(tray);
|
||||||
|
return svg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildItem(entry) {
|
function buildItem(entry) {
|
||||||
const li = document.createElement("li");
|
const li = document.createElement("li");
|
||||||
li.className = "history-item";
|
li.className = "history-item";
|
||||||
|
const meta = formatMeta(entry);
|
||||||
|
|
||||||
|
const head = document.createElement("div");
|
||||||
|
head.className = "history-head";
|
||||||
|
|
||||||
if (entry.coverImageUrl) {
|
|
||||||
const cover = document.createElement("img");
|
const cover = document.createElement("img");
|
||||||
cover.className = "history-cover-image";
|
cover.className = "history-cover-image";
|
||||||
cover.src = entry.coverImageUrl;
|
cover.src = entry.coverImageUrl || "icons/icon-48.png";
|
||||||
cover.alt = "Cover art";
|
cover.alt = "Cover art";
|
||||||
cover.loading = "lazy";
|
cover.loading = "lazy";
|
||||||
li.appendChild(cover);
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = document.createElement("p");
|
const info = document.createElement("div");
|
||||||
url.className = "history-url";
|
info.className = "history-info";
|
||||||
url.textContent = entry.fileName || entry.sampleId || "(unknown filename)";
|
|
||||||
|
|
||||||
const meta = document.createElement("p");
|
const title = document.createElement("p");
|
||||||
meta.className = "history-meta";
|
title.className = "history-title";
|
||||||
|
title.textContent = entry.fileName || entry.sampleId || "(unknown filename)";
|
||||||
|
|
||||||
|
const subtitle = document.createElement("p");
|
||||||
|
subtitle.className = "history-subtitle";
|
||||||
const mode = entry.mode === "full" || entry.fullUrl ? "full candidate" : "preview fallback";
|
const mode = entry.mode === "full" || entry.fullUrl ? "full candidate" : "preview fallback";
|
||||||
meta.textContent = `Captured: ${formatDate(entry.capturedAt)} | Mode: ${mode} | Source: ${entry.source || "unknown"} | ID: ${entry.sampleId || "n/a"}`;
|
subtitle.textContent = `${meta.packName} • ${mode}`;
|
||||||
|
|
||||||
const details = document.createElement("p");
|
const badges = document.createElement("div");
|
||||||
details.className = "history-meta";
|
badges.className = "history-badges";
|
||||||
details.textContent = formatMeta(entry);
|
const keyBadge = document.createElement("span");
|
||||||
|
keyBadge.className = "badge";
|
||||||
|
keyBadge.textContent = `Key ${meta.key}`;
|
||||||
|
const bpmBadge = document.createElement("span");
|
||||||
|
bpmBadge.className = "badge";
|
||||||
|
bpmBadge.textContent = `BPM ${meta.bpm}`;
|
||||||
|
badges.appendChild(keyBadge);
|
||||||
|
badges.appendChild(bpmBadge);
|
||||||
|
|
||||||
|
const tags = document.createElement("p");
|
||||||
|
tags.className = "history-tags";
|
||||||
|
tags.textContent = formatTags(entry);
|
||||||
|
|
||||||
|
info.appendChild(title);
|
||||||
|
info.appendChild(subtitle);
|
||||||
|
info.appendChild(badges);
|
||||||
|
info.appendChild(tags);
|
||||||
|
|
||||||
const download = document.createElement("button");
|
const download = document.createElement("button");
|
||||||
download.type = "button";
|
download.type = "button";
|
||||||
download.textContent = "Download";
|
download.className = "download-icon-btn";
|
||||||
|
download.setAttribute("aria-label", "Download sample");
|
||||||
|
download.setAttribute("title", "Download sample");
|
||||||
|
download.appendChild(createDownloadIcon());
|
||||||
download.addEventListener("click", async () => {
|
download.addEventListener("click", async () => {
|
||||||
const result = await browser.runtime.sendMessage({
|
const result = await browser.runtime.sendMessage({
|
||||||
type: "DOWNLOAD_ENTRY",
|
type: "DOWNLOAD_ENTRY",
|
||||||
@@ -60,10 +110,10 @@ function buildItem(entry) {
|
|||||||
statusEl.textContent = result.mode === "full" ? "Downloaded full file URL." : "Downloaded decoded preview fallback.";
|
statusEl.textContent = result.mode === "full" ? "Downloaded full file URL." : "Downloaded decoded preview fallback.";
|
||||||
});
|
});
|
||||||
|
|
||||||
li.appendChild(url);
|
head.appendChild(cover);
|
||||||
li.appendChild(meta);
|
head.appendChild(info);
|
||||||
li.appendChild(details);
|
head.appendChild(download);
|
||||||
li.appendChild(download);
|
li.appendChild(head);
|
||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
140
popup.css
140
popup.css
@@ -1,14 +1,14 @@
|
|||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Arial, sans-serif;
|
font-family: Inter, "Segoe UI", Arial, sans-serif;
|
||||||
background: #111319;
|
background: #070909;
|
||||||
color: #e9ecf1;
|
color: #e7f0e9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
width: 380px;
|
width: 420px;
|
||||||
max-height: 520px;
|
max-height: 560px;
|
||||||
padding: 12px;
|
padding: 14px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,32 +16,37 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 8px;
|
gap: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-header h1 {
|
.popup-header h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
#openHistoryBtn {
|
||||||
border: 1px solid #2f66ff;
|
border: 1px solid #263329;
|
||||||
background: #2f66ff;
|
background: #101513;
|
||||||
color: white;
|
color: #b7cbbd;
|
||||||
border-radius: 6px;
|
border-radius: 999px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 6px 9px;
|
padding: 6px 10px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
transition: all 120ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.secondary {
|
#openHistoryBtn:hover {
|
||||||
border-color: #445;
|
border-color: #3c5342;
|
||||||
background: #1e2230;
|
color: #e3f3e7;
|
||||||
|
background: #151d18;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
margin: 12px 0;
|
margin: 8px 0 12px;
|
||||||
color: #adb6cb;
|
color: #829589;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,33 +56,98 @@ button.secondary {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url-item {
|
.url-item {
|
||||||
border: 1px solid #2a2f40;
|
border: 1px solid #1d2620;
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
background: #171b26;
|
background: #0d1210;
|
||||||
padding: 8px;
|
padding: 10px;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-head {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-info {
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover-image {
|
.cover-image {
|
||||||
width: 36px;
|
width: 44px;
|
||||||
height: 36px;
|
height: 44px;
|
||||||
border-radius: 4px;
|
border-radius: 7px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
display: block;
|
flex-shrink: 0;
|
||||||
margin-bottom: 8px;
|
border: 1px solid #243027;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url-text {
|
.item-title {
|
||||||
margin: 0 0 8px;
|
margin: 0;
|
||||||
|
color: #eff8f1;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-sub {
|
||||||
|
margin: 3px 0 0;
|
||||||
|
color: #94a89a;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
word-break: break-all;
|
|
||||||
color: #c6d0e5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
.item-tags {
|
||||||
display: flex;
|
margin: 4px 0 0;
|
||||||
gap: 8px;
|
color: #b3c9b8;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.3;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-badges {
|
||||||
|
margin-top: 8px;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
border: 1px solid #2d4f35;
|
||||||
|
background: #142219;
|
||||||
|
color: #bde6c6;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 10px;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-icon-btn {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border: 1px solid #2f9e5a;
|
||||||
|
background: #1b7f45;
|
||||||
|
color: #f1fff4;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
transition: background 120ms ease, transform 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-icon-btn:hover {
|
||||||
|
background: #249452;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-icon-btn:active {
|
||||||
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
|
|||||||
115
popup.js
115
popup.js
@@ -16,41 +16,101 @@ function formatMeta(entry) {
|
|||||||
const packName = entry && entry.packName ? entry.packName : "n/a";
|
const packName = entry && entry.packName ? entry.packName : "n/a";
|
||||||
const key = entry && entry.key ? entry.key : "n/a";
|
const key = entry && entry.key ? entry.key : "n/a";
|
||||||
const bpm = entry && entry.bpm ? entry.bpm : "n/a";
|
const bpm = entry && entry.bpm ? entry.bpm : "n/a";
|
||||||
const tags = entry && Array.isArray(entry.tags) && entry.tags.length ? entry.tags.join(", ") : "n/a";
|
return { packName, key, bpm };
|
||||||
return `Pack: ${packName} | Key: ${key} | BPM: ${bpm} | Tags: ${tags}`;
|
}
|
||||||
|
|
||||||
|
function formatTags(entry) {
|
||||||
|
if (!entry || !Array.isArray(entry.tags) || !entry.tags.length) {
|
||||||
|
return "No tags";
|
||||||
|
}
|
||||||
|
const maxTags = 5;
|
||||||
|
const tags = entry.tags.slice(0, maxTags);
|
||||||
|
const suffix = entry.tags.length > maxTags ? ` +${entry.tags.length - maxTags}` : "";
|
||||||
|
return tags.join(" • ") + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDownloadIcon() {
|
||||||
|
const ns = "http://www.w3.org/2000/svg";
|
||||||
|
const svg = document.createElementNS(ns, "svg");
|
||||||
|
svg.setAttribute("viewBox", "0 0 24 24");
|
||||||
|
svg.setAttribute("width", "22");
|
||||||
|
svg.setAttribute("height", "22");
|
||||||
|
svg.setAttribute("aria-hidden", "true");
|
||||||
|
|
||||||
|
const arrow = document.createElementNS(ns, "path");
|
||||||
|
arrow.setAttribute("d", "M12 4v10m0 0l4-4m-4 4l-4-4");
|
||||||
|
arrow.setAttribute("fill", "none");
|
||||||
|
arrow.setAttribute("stroke", "currentColor");
|
||||||
|
arrow.setAttribute("stroke-width", "2");
|
||||||
|
arrow.setAttribute("stroke-linecap", "round");
|
||||||
|
arrow.setAttribute("stroke-linejoin", "round");
|
||||||
|
|
||||||
|
const tray = document.createElementNS(ns, "path");
|
||||||
|
tray.setAttribute("d", "M4 18v1a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-1");
|
||||||
|
tray.setAttribute("fill", "none");
|
||||||
|
tray.setAttribute("stroke", "currentColor");
|
||||||
|
tray.setAttribute("stroke-width", "2");
|
||||||
|
tray.setAttribute("stroke-linecap", "round");
|
||||||
|
tray.setAttribute("stroke-linejoin", "round");
|
||||||
|
|
||||||
|
svg.appendChild(arrow);
|
||||||
|
svg.appendChild(tray);
|
||||||
|
return svg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildRow(entry) {
|
function buildRow(entry) {
|
||||||
const li = document.createElement("li");
|
const li = document.createElement("li");
|
||||||
li.className = "url-item";
|
li.className = "url-item";
|
||||||
|
const meta = formatMeta(entry);
|
||||||
|
|
||||||
|
const head = document.createElement("div");
|
||||||
|
head.className = "item-head";
|
||||||
|
|
||||||
if (entry.coverImageUrl) {
|
|
||||||
const cover = document.createElement("img");
|
const cover = document.createElement("img");
|
||||||
cover.className = "cover-image";
|
cover.className = "cover-image";
|
||||||
cover.src = entry.coverImageUrl;
|
cover.src = entry.coverImageUrl || "icons/icon-48.png";
|
||||||
cover.alt = "Cover art";
|
cover.alt = "Cover art";
|
||||||
cover.loading = "lazy";
|
cover.loading = "lazy";
|
||||||
li.appendChild(cover);
|
|
||||||
}
|
|
||||||
|
|
||||||
const p = document.createElement("p");
|
const info = document.createElement("div");
|
||||||
p.className = "url-text";
|
info.className = "item-info";
|
||||||
p.textContent = entry.fileName || entry.sampleId || "(unknown filename)";
|
|
||||||
|
|
||||||
const status = document.createElement("p");
|
const title = document.createElement("p");
|
||||||
status.className = "status";
|
title.className = "item-title";
|
||||||
status.textContent = `Source: ${entry.source || "unknown"} | Mode: ${entryLabel(entry)} | ID: ${entry.sampleId || "n/a"}`;
|
title.textContent = entry.fileName || entry.sampleId || "(unknown filename)";
|
||||||
|
|
||||||
const meta = document.createElement("p");
|
const sub = document.createElement("p");
|
||||||
meta.className = "status";
|
sub.className = "item-sub";
|
||||||
meta.textContent = formatMeta(entry);
|
sub.textContent = `${meta.packName} • ${entryLabel(entry)}`;
|
||||||
|
|
||||||
const actions = document.createElement("div");
|
const tags = document.createElement("p");
|
||||||
actions.className = "actions";
|
tags.className = "item-tags";
|
||||||
|
tags.textContent = formatTags(entry);
|
||||||
|
|
||||||
|
const badges = document.createElement("div");
|
||||||
|
badges.className = "item-badges";
|
||||||
|
|
||||||
|
const keyBadge = document.createElement("span");
|
||||||
|
keyBadge.className = "badge";
|
||||||
|
keyBadge.textContent = `Key ${meta.key}`;
|
||||||
|
|
||||||
|
const bpmBadge = document.createElement("span");
|
||||||
|
bpmBadge.className = "badge";
|
||||||
|
bpmBadge.textContent = `BPM ${meta.bpm}`;
|
||||||
|
|
||||||
|
badges.appendChild(keyBadge);
|
||||||
|
badges.appendChild(bpmBadge);
|
||||||
|
info.appendChild(title);
|
||||||
|
info.appendChild(sub);
|
||||||
|
info.appendChild(tags);
|
||||||
|
info.appendChild(badges);
|
||||||
|
|
||||||
const download = document.createElement("button");
|
const download = document.createElement("button");
|
||||||
download.type = "button";
|
download.type = "button";
|
||||||
download.textContent = "Download";
|
download.className = "download-icon-btn";
|
||||||
|
download.setAttribute("aria-label", "Download sample");
|
||||||
|
download.setAttribute("title", "Download sample");
|
||||||
|
download.appendChild(createDownloadIcon());
|
||||||
download.addEventListener("click", async () => {
|
download.addEventListener("click", async () => {
|
||||||
const result = await browser.runtime.sendMessage({ type: "DOWNLOAD_ENTRY", entry });
|
const result = await browser.runtime.sendMessage({ type: "DOWNLOAD_ENTRY", entry });
|
||||||
if (!result || !result.ok) {
|
if (!result || !result.ok) {
|
||||||
@@ -60,21 +120,10 @@ function buildRow(entry) {
|
|||||||
setStatus(result.mode === "full" ? "Downloaded full file URL." : "Downloaded decoded preview fallback.");
|
setStatus(result.mode === "full" ? "Downloaded full file URL." : "Downloaded decoded preview fallback.");
|
||||||
});
|
});
|
||||||
|
|
||||||
const copy = document.createElement("button");
|
head.appendChild(cover);
|
||||||
copy.type = "button";
|
head.appendChild(info);
|
||||||
copy.className = "secondary";
|
head.appendChild(download);
|
||||||
copy.textContent = "Copy URL";
|
li.appendChild(head);
|
||||||
copy.addEventListener("click", async () => {
|
|
||||||
const url = entry.fullUrl || entry.previewUrl || "";
|
|
||||||
await navigator.clipboard.writeText(url);
|
|
||||||
});
|
|
||||||
|
|
||||||
actions.appendChild(download);
|
|
||||||
actions.appendChild(copy);
|
|
||||||
li.appendChild(p);
|
|
||||||
li.appendChild(status);
|
|
||||||
li.appendChild(meta);
|
|
||||||
li.appendChild(actions);
|
|
||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user