mirror of
https://github.com/svemagie/indiekit-endpoint-youtube.git
synced 2026-04-02 15:54:59 +02:00
feat: add reset button to delete all likes data
POST /likes/reset deletes all YouTube like posts from the posts collection, clears the youtubeLikesSeen set, and removes the baseline and sync metadata. Next sync will re-baseline. Button is tucked inside a <details> disclosure to prevent accidental clicks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1
index.js
1
index.js
@@ -95,6 +95,7 @@ export default class YouTubeEndpoint {
|
||||
protectedRouter.get("/likes/connect", likesController.connect);
|
||||
protectedRouter.post("/likes/disconnect", likesController.disconnect);
|
||||
protectedRouter.post("/likes/sync", likesController.sync);
|
||||
protectedRouter.post("/likes/reset", likesController.reset);
|
||||
|
||||
return protectedRouter;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ export const likesController = {
|
||||
}
|
||||
|
||||
// Flash messages from query params
|
||||
const { error: qError, connected, disconnected, synced, skipped } = request.query;
|
||||
const { error: qError, connected, disconnected, synced, skipped, reset } = request.query;
|
||||
let success = null;
|
||||
let notice = null;
|
||||
if (connected) success = response.locals.__("youtube.likes.flash.connected");
|
||||
@@ -75,6 +75,9 @@ export const likesController = {
|
||||
const sk = parseInt(skipped, 10) || 0;
|
||||
success = response.locals.__("youtube.likes.flash.synced", { synced: s, skipped: sk });
|
||||
}
|
||||
if (reset !== undefined) {
|
||||
notice = response.locals.__("youtube.likes.flash.reset", { count: parseInt(reset, 10) || 0 });
|
||||
}
|
||||
|
||||
response.render("youtube-likes", {
|
||||
title: response.locals.__("youtube.likes.title"),
|
||||
@@ -221,6 +224,49 @@ export const likesController = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* POST /likes/reset — delete all like posts, seen set, and baseline
|
||||
*/
|
||||
async reset(request, response) {
|
||||
try {
|
||||
const db = request.app.locals.application.getYoutubeDb?.();
|
||||
if (!db) {
|
||||
return response.status(503).json({ error: "Database not available" });
|
||||
}
|
||||
|
||||
const postsCollection = request.app.locals.application.collections?.get("posts");
|
||||
|
||||
let deletedPosts = 0;
|
||||
if (postsCollection) {
|
||||
const result = await postsCollection.deleteMany({
|
||||
"properties.post-type": "like",
|
||||
"properties.youtube-video-id": { $exists: true },
|
||||
});
|
||||
deletedPosts = result.deletedCount || 0;
|
||||
}
|
||||
|
||||
const seenResult = await db.collection("youtubeLikesSeen").deleteMany({});
|
||||
const deletedSeen = seenResult.deletedCount || 0;
|
||||
|
||||
await db.collection("youtubeMeta").deleteOne({ key: "likes_baseline" });
|
||||
await db.collection("youtubeMeta").deleteOne({ key: "likes_sync" });
|
||||
|
||||
console.log(`[YouTube] Reset: deleted ${deletedPosts} posts, ${deletedSeen} seen entries, cleared baseline`);
|
||||
|
||||
if (request.accepts("json")) {
|
||||
return response.json({ deletedPosts, deletedSeen });
|
||||
}
|
||||
|
||||
response.redirect(`${request.baseUrl}/likes?reset=${deletedPosts}`);
|
||||
} catch (error) {
|
||||
console.error("[YouTube] Reset error:", error);
|
||||
if (request.accepts("json")) {
|
||||
return response.status(500).json({ error: error.message });
|
||||
}
|
||||
response.redirect(`${request.baseUrl}/likes?error=${encodeURIComponent(error.message)}`);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* GET /api/likes — public JSON API for synced likes
|
||||
*/
|
||||
|
||||
@@ -45,10 +45,14 @@
|
||||
"seenVideos": "Videos gesehen",
|
||||
"likePosts": "Like-Beiträge erstellt",
|
||||
"viewOnYouTube": "Auf YouTube ansehen",
|
||||
"reset": "Zurücksetzen",
|
||||
"resetDescription": "Alle synchronisierten Like-Beiträge, gesehene Video-IDs und Baseline löschen. Nächste Synchronisierung erstellt eine neue Baseline.",
|
||||
"resetConfirm": "Alle Likes-Daten löschen",
|
||||
"flash": {
|
||||
"connected": "YouTube-Konto erfolgreich verbunden. Starte eine Synchronisierung, um bestehende Likes zu erfassen.",
|
||||
"disconnected": "YouTube-Konto getrennt.",
|
||||
"synced": "Synchronisierung abgeschlossen: %{synced} neu, %{skipped} übersprungen."
|
||||
"synced": "Synchronisierung abgeschlossen: %{synced} neu, %{skipped} übersprungen.",
|
||||
"reset": "Zurücksetzen abgeschlossen: %{count} Like-Beiträge gelöscht. Baseline gelöscht."
|
||||
},
|
||||
"error": {
|
||||
"noOAuth": "YouTube OAuth ist nicht konfiguriert. Setze YOUTUBE_OAUTH_CLIENT_ID und YOUTUBE_OAUTH_CLIENT_SECRET."
|
||||
|
||||
@@ -45,10 +45,14 @@
|
||||
"seenVideos": "videos seen",
|
||||
"likePosts": "like posts created",
|
||||
"viewOnYouTube": "View on YouTube",
|
||||
"reset": "Reset",
|
||||
"resetDescription": "Delete all synced like posts, seen video IDs, and baseline. Next sync will re-baseline.",
|
||||
"resetConfirm": "Delete all likes data",
|
||||
"flash": {
|
||||
"connected": "YouTube account connected successfully. Run a sync to baseline your existing likes.",
|
||||
"disconnected": "YouTube account disconnected.",
|
||||
"synced": "Sync complete: %{synced} new, %{skipped} skipped."
|
||||
"synced": "Sync complete: %{synced} new, %{skipped} skipped.",
|
||||
"reset": "Reset complete: %{count} like posts deleted. Baseline cleared."
|
||||
},
|
||||
"error": {
|
||||
"noOAuth": "YouTube OAuth is not configured. Set YOUTUBE_OAUTH_CLIENT_ID and YOUTUBE_OAUTH_CLIENT_SECRET."
|
||||
|
||||
@@ -73,6 +73,15 @@
|
||||
</form>
|
||||
{% endcall %}
|
||||
|
||||
{# ── Reset (destructive, hidden in details) ── #}
|
||||
{% call section({ title: __("youtube.likes.reset") }) %}
|
||||
{% call details({ summary: __("youtube.likes.resetDescription") }) %}
|
||||
<form method="post" action="{{ mountPath }}/likes/reset">
|
||||
{{ button({ type: "submit", text: __("youtube.likes.resetConfirm") }) }}
|
||||
</form>
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
|
||||
{# ── Recent likes ── #}
|
||||
{% call section({ title: __("youtube.likes.recentLikes") }) %}
|
||||
{% if recentLikes and recentLikes.length > 0 %}
|
||||
|
||||
Reference in New Issue
Block a user