diff --git a/lib/controllers/timeline.js b/lib/controllers/timeline.js index d22fa52..be13143 100644 --- a/lib/controllers/timeline.js +++ b/lib/controllers/timeline.js @@ -6,7 +6,7 @@ import { IndiekitError } from "@indiekit/error"; import { proxyItemImages } from "../media/proxy.js"; -import { getChannel } from "../storage/channels.js"; +import { getChannel, getChannelById } from "../storage/channels.js"; import { getTimelineItems, markItemsRead, @@ -72,8 +72,16 @@ export async function action(request, response) { validateChannel(channel); - // Verify channel exists - const channelDocument = await getChannel(application, channel, userId); + // Verify channel exists — try by UID first, fall back to ObjectId + // (timeline view may send ObjectId string for items from orphan channels) + let channelDocument = await getChannel(application, channel, userId); + if (!channelDocument) { + try { + channelDocument = await getChannelById(application, channel); + } catch { + // Invalid ObjectId format — channel string is not a valid ObjectId + } + } if (!channelDocument) { throw new IndiekitError("Channel not found", { status: 404, diff --git a/views/partials/item-card.njk b/views/partials/item-card.njk index f21c1bd..f5ae360 100644 --- a/views/partials/item-card.njk +++ b/views/partials/item-card.njk @@ -203,6 +203,7 @@ data-action="mark-read" data-item-id="{{ item._id }}" {% if item._channelUid %}data-channel-uid="{{ item._channelUid }}"{% endif %} + {% if item._channelId %}data-channel-id="{{ item._channelId }}"{% endif %} title="Mark as read"> {{ icon("checkboxChecked") }} Mark read diff --git a/views/timeline.njk b/views/timeline.njk index 4b0a83a..2fc4cf7 100644 --- a/views/timeline.njk +++ b/views/timeline.njk @@ -108,7 +108,8 @@ const itemId = button.dataset.itemId; const channelUid = button.dataset.channelUid; - if (!itemId || !channelUid) return; + const channelId = button.dataset.channelId; + if (!itemId || (!channelUid && !channelId)) return; button.disabled = true; @@ -116,7 +117,7 @@ const formData = new URLSearchParams(); formData.append('action', 'timeline'); formData.append('method', 'mark_read'); - formData.append('channel', channelUid); + formData.append('channel', channelUid || channelId); formData.append('entry', itemId); const response = await fetch(microsubApiUrl, {