fix: wire mark-as-read in timeline view
Items in the cross-channel timeline now carry per-item channel UID so the mark-read API call can target the correct channel. Adds the same dismiss animation used in the channel view.
This commit is contained in:
@@ -1184,10 +1184,10 @@ export async function timeline(request, response) {
|
|||||||
// Get channels with colors for filtering UI and item decoration
|
// Get channels with colors for filtering UI and item decoration
|
||||||
const channelList = await getChannelsWithColors(application, userId);
|
const channelList = await getChannelsWithColors(application, userId);
|
||||||
|
|
||||||
// Build channel lookup map (ObjectId string -> { name, color })
|
// Build channel lookup map (ObjectId string -> { name, color, uid })
|
||||||
const channelMap = new Map();
|
const channelMap = new Map();
|
||||||
for (const ch of channelList) {
|
for (const ch of channelList) {
|
||||||
channelMap.set(ch._id.toString(), { name: ch.name, color: ch.color });
|
channelMap.set(ch._id.toString(), { name: ch.name, color: ch.color, uid: ch.uid });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse excluded channel IDs from query params
|
// Parse excluded channel IDs from query params
|
||||||
@@ -1223,6 +1223,7 @@ export async function timeline(request, response) {
|
|||||||
if (info) {
|
if (info) {
|
||||||
item._channelName = info.name;
|
item._channelName = info.name;
|
||||||
item._channelColor = info.color;
|
item._channelColor = info.color;
|
||||||
|
item._channelUid = info.uid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,6 +202,7 @@
|
|||||||
class="item-actions__button item-actions__mark-read"
|
class="item-actions__button item-actions__mark-read"
|
||||||
data-action="mark-read"
|
data-action="mark-read"
|
||||||
data-item-id="{{ item._id }}"
|
data-item-id="{{ item._id }}"
|
||||||
|
{% if item._channelUid %}data-channel-uid="{{ item._channelUid }}"{% endif %}
|
||||||
title="Mark as read">
|
title="Mark as read">
|
||||||
{{ icon("checkboxChecked") }}
|
{{ icon("checkboxChecked") }}
|
||||||
<span class="visually-hidden">Mark read</span>
|
<span class="visually-hidden">Mark read</span>
|
||||||
|
|||||||
@@ -95,6 +95,61 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Handle individual mark-read buttons
|
||||||
|
const microsubApiUrl = '{{ baseUrl }}'.replace(/\/reader$/, '');
|
||||||
|
|
||||||
|
timeline.addEventListener('click', async (e) => {
|
||||||
|
const button = e.target.closest('.item-actions__mark-read');
|
||||||
|
if (!button) return;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const itemId = button.dataset.itemId;
|
||||||
|
const channelUid = button.dataset.channelUid;
|
||||||
|
if (!itemId || !channelUid) return;
|
||||||
|
|
||||||
|
button.disabled = true;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
const card = button.closest('.item-card');
|
||||||
|
if (card) {
|
||||||
|
card.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
|
||||||
|
card.style.opacity = '0';
|
||||||
|
card.style.transform = 'translateX(-20px)';
|
||||||
|
setTimeout(() => {
|
||||||
|
const wrapper = card.closest('.timeline-view__item');
|
||||||
|
if (wrapper) wrapper.remove();
|
||||||
|
else card.remove();
|
||||||
|
if (timeline.querySelectorAll('.item-card').length === 0) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Failed to mark item as read');
|
||||||
|
button.disabled = false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error marking item as read:', error);
|
||||||
|
button.disabled = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user