mirror of
https://github.com/svemagie/indiekit-endpoint-microsub.git
synced 2026-04-02 15:35:00 +02:00
feat: add bookmark to timeline, mark-read to item view
- Add bookmark button to item-card.njk (timeline view) - Add mark-read button to item.njk (full item view) - Add JavaScript handler for mark-read on item page - Pass channel info to item template for mark-read API call Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -314,9 +314,17 @@ export async function item(request, response) {
|
||||
return response.status(404).render("404");
|
||||
}
|
||||
|
||||
// Get the channel for this item (needed for mark-read)
|
||||
let channel = null;
|
||||
if (itemDocument.channelId) {
|
||||
const channelsCollection = application.collections.get("microsub_channels");
|
||||
channel = await channelsCollection.findOne({ _id: itemDocument.channelId });
|
||||
}
|
||||
|
||||
response.render("item", {
|
||||
title: itemDocument.name || "Item",
|
||||
item: itemDocument,
|
||||
channel,
|
||||
baseUrl: request.baseUrl,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rmdes/indiekit-endpoint-microsub",
|
||||
"version": "1.0.18",
|
||||
"version": "1.0.19",
|
||||
"description": "Microsub endpoint for Indiekit. Enables subscribing to feeds and reading content using the Microsub protocol.",
|
||||
"keywords": [
|
||||
"indiekit",
|
||||
|
||||
@@ -146,6 +146,61 @@
|
||||
<a href="{{ baseUrl }}/compose?bookmark={{ item.url | urlencode }}" class="button button--secondary button--small">
|
||||
{{ icon("bookmark") }} {{ __("microsub.item.bookmark") }}
|
||||
</a>
|
||||
{% if not item._is_read %}
|
||||
<button type="button"
|
||||
class="button button--secondary button--small item__mark-read"
|
||||
data-item-id="{{ item._id }}"
|
||||
data-channel="{{ channel.uid }}">
|
||||
{{ icon("checkboxChecked") }} {{ __("microsub.timeline.markRead") }}
|
||||
</button>
|
||||
{% endif %}
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
<script type="module">
|
||||
// Handle mark-read button
|
||||
const markReadBtn = document.querySelector('.item__mark-read');
|
||||
if (markReadBtn) {
|
||||
markReadBtn.addEventListener('click', async () => {
|
||||
const itemId = markReadBtn.dataset.itemId;
|
||||
const channelUid = markReadBtn.dataset.channel;
|
||||
const microsubApiUrl = '{{ baseUrl }}'.replace(/\/reader.*$/, '');
|
||||
|
||||
markReadBtn.disabled = true;
|
||||
markReadBtn.textContent = 'Marking...';
|
||||
|
||||
try {
|
||||
const formData = new URLSearchParams();
|
||||
formData.append('action', 'timeline');
|
||||
formData.append('method', 'mark_read');
|
||||
formData.append('channel', channelUid);
|
||||
formData.append('entry', itemId);
|
||||
|
||||
const response = await fetch(microsubApiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: formData.toString(),
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
markReadBtn.textContent = 'Marked as read';
|
||||
markReadBtn.classList.add('button--success');
|
||||
setTimeout(() => {
|
||||
markReadBtn.remove();
|
||||
}, 1500);
|
||||
} else {
|
||||
markReadBtn.textContent = 'Failed';
|
||||
markReadBtn.disabled = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
markReadBtn.textContent = 'Error';
|
||||
markReadBtn.disabled = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -165,6 +165,10 @@
|
||||
{{ icon("repost") }}
|
||||
<span class="visually-hidden">Repost</span>
|
||||
</a>
|
||||
<a href="{{ baseUrl }}/compose?bookmark={{ item.url | urlencode }}" class="item-actions__button" title="Bookmark">
|
||||
{{ icon("bookmark") }}
|
||||
<span class="visually-hidden">Bookmark</span>
|
||||
</a>
|
||||
{% if not item._is_read %}
|
||||
<button type="button"
|
||||
class="item-actions__button item-actions__mark-read"
|
||||
|
||||
Reference in New Issue
Block a user