diff --git a/css/style.css b/css/style.css
index cdabeb25..65cdbe6c 100644
--- a/css/style.css
+++ b/css/style.css
@@ -360,12 +360,6 @@ header img {
border-color: #991b1b;
}
-.watch-history-card__menus {
- display: flex;
- align-items: center;
- gap: 0.5rem;
-}
-
@media (max-width: 1024px) {
.watch-history-card__meta {
flex: 1 1 18rem;
@@ -1129,6 +1123,22 @@ button:not(.icon-button):focus {
display: flex;
}
+.watch-history-status {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.status-spinner--inline {
+ animation: spin 1s linear infinite;
+ border: 0.125rem solid rgba(96, 165, 250, 0.35);
+ border-radius: 9999px;
+ border-top-color: #60a5fa;
+ display: inline-block;
+ height: 1rem;
+ width: 1rem;
+}
+
.status-banner {
align-items: center;
background-color: rgba(31, 41, 55, 0.9);
diff --git a/js/historyView.js b/js/historyView.js
index 4c6f5af7..13fa4ff5 100644
--- a/js/historyView.js
+++ b/js/historyView.js
@@ -234,105 +234,6 @@ function renderWatchHistoryGrid(videos, containerOrElement) {
}
}
- let hasOlder = false;
- if (canEdit && video.videoRootId && window.app?.hasOlderVersion) {
- hasOlder = window.app.hasOlderVersion(video, fullAllEventsArray);
- }
-
- const revertButton = hasOlder
- ? `
-
- `
- : "";
-
- const gearMenu = canEdit
- ? `
-
-
-
-
-
- ${revertButton}
-
-
-
-
- `
- : "";
-
- const moreMenu = `
-
-
-
-
-
-
-
-
-
-
-
- `;
-
- const cardControls = `
-
- `;
-
const safeTitle = window.app?.escapeHTML(video.title) || "Untitled";
const safeThumb = window.app?.escapeHTML(video.thumbnail) || "";
const playbackUrl = typeof video.url === "string" ? video.url : "";
@@ -432,7 +333,6 @@ function renderWatchHistoryGrid(videos, containerOrElement) {
>
Remove
- ${cardControls}
@@ -480,66 +380,6 @@ function renderWatchHistoryGrid(videos, containerOrElement) {
const lazyEls = container.querySelectorAll("[data-lazy]");
lazyEls.forEach((el) => window.app?.mediaLoader.observe(el));
- window.app?.attachMoreMenuHandlers?.(container);
-
- const gearButtons = container.querySelectorAll("[data-settings-dropdown]");
- gearButtons.forEach((btn) => {
- btn.addEventListener("click", (ev) => {
- ev.stopPropagation();
- const idx = btn.getAttribute("data-settings-dropdown");
- const dropdown = document.getElementById(`settingsDropdown-${idx}`);
- if (dropdown) dropdown.classList.toggle("hidden");
- });
- });
-
- const editButtons = container.querySelectorAll("[data-edit-index]");
- editButtons.forEach((btn) => {
- btn.addEventListener("click", (ev) => {
- ev.stopPropagation();
- const idxAttr = btn.getAttribute("data-edit-index");
- const idx = Number.parseInt(idxAttr, 10);
- const dropdown = document.getElementById(`settingsDropdown-${idxAttr}`);
- if (dropdown) dropdown.classList.add("hidden");
- const eventId = btn.getAttribute("data-edit-event-id") || "";
- window.app?.handleEditVideo({
- eventId,
- index: Number.isNaN(idx) ? null : idx,
- });
- });
- });
-
- const revertButtons = container.querySelectorAll("[data-revert-index]");
- revertButtons.forEach((btn) => {
- btn.addEventListener("click", (ev) => {
- ev.stopPropagation();
- const idxAttr = btn.getAttribute("data-revert-index");
- const idx = Number.parseInt(idxAttr, 10);
- const dropdown = document.getElementById(`settingsDropdown-${idxAttr}`);
- if (dropdown) dropdown.classList.add("hidden");
- const eventId = btn.getAttribute("data-revert-event-id") || "";
- window.app?.handleRevertVideo({
- eventId,
- index: Number.isNaN(idx) ? null : idx,
- });
- });
- });
-
- const deleteAllButtons = container.querySelectorAll("[data-delete-all-index]");
- deleteAllButtons.forEach((btn) => {
- btn.addEventListener("click", (ev) => {
- ev.stopPropagation();
- const idxAttr = btn.getAttribute("data-delete-all-index");
- const idx = Number.parseInt(idxAttr, 10);
- const dd = document.getElementById(`settingsDropdown-${idxAttr}`);
- if (dd) dd.classList.add("hidden");
- const eventId = btn.getAttribute("data-delete-all-event-id") || "";
- window.app?.handleFullDeleteVideo({
- eventId,
- index: Number.isNaN(idx) ? null : idx,
- });
- });
- });
-
const authorPics = container.querySelectorAll(".author-pic");
const authorNames = container.querySelectorAll(".author-name");
const creatorButtons = container.querySelectorAll(
@@ -790,10 +630,18 @@ export function createWatchHistoryRenderer(config = {}) {
const nextMessage = typeof message === "string" ? message.trim() : "";
if (nextMessage) {
- statusEl.textContent = nextMessage;
+ if (nextMessage === WATCH_HISTORY_LOADING_STATUS) {
+ statusEl.innerHTML =
+ '' +
+ WATCH_HISTORY_LOADING_STATUS +
+ "";
+ } else {
+ statusEl.textContent = nextMessage;
+ }
statusEl.classList.remove("hidden");
} else {
statusEl.textContent = "";
+ statusEl.innerHTML = "";
statusEl.classList.add("hidden");
}
};
@@ -945,6 +793,45 @@ export function createWatchHistoryRenderer(config = {}) {
return;
}
+ const showRemoveSpinner = (button) => {
+ if (!button || !button.dataset) {
+ return;
+ }
+
+ if (button.dataset.originalHtml === undefined) {
+ button.dataset.originalHtml = button.innerHTML;
+ }
+
+ if (button.dataset.originalAriaLabel === undefined) {
+ button.dataset.originalAriaLabel = button.getAttribute("aria-label") || "";
+ }
+
+ button.innerHTML =
+ '';
+ button.setAttribute("aria-label", "Removing from watch history");
+ };
+
+ const restoreRemoveButton = (button) => {
+ if (!button || !button.dataset) {
+ return;
+ }
+
+ const originalHtml = button.dataset.originalHtml;
+ if (typeof originalHtml === "string") {
+ button.innerHTML = originalHtml;
+ }
+
+ const originalAria = button.dataset.originalAriaLabel || "";
+ if (originalAria) {
+ button.setAttribute("aria-label", originalAria);
+ } else {
+ button.removeAttribute("aria-label");
+ }
+
+ delete button.dataset.originalHtml;
+ delete button.dataset.originalAriaLabel;
+ };
+
const handler = async (event) => {
const removeTrigger = event.target.closest(
"[data-history-remove-key]"
@@ -971,6 +858,7 @@ export function createWatchHistoryRenderer(config = {}) {
removeTrigger.disabled = true;
removeTrigger.setAttribute("aria-busy", "true");
+ showRemoveSpinner(removeTrigger);
try {
const result = await nostrClient.removeWatchHistoryItem(targetKey);
@@ -1008,7 +896,10 @@ export function createWatchHistoryRenderer(config = {}) {
"Failed to remove this video from watch history."
);
} finally {
- removeTrigger.removeAttribute("aria-busy");
+ if (removeTrigger.isConnected) {
+ restoreRemoveButton(removeTrigger);
+ removeTrigger.removeAttribute("aria-busy");
+ }
}
return;