diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7f8c3d7..100b296 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,6 +1,6 @@ # Changelog -## Version v0.1.2 +## Version v0.2.0 ### Features * Users can edit or delete labels created by themselves on the labels page * Administrators can edit labels from the admin interface @@ -15,12 +15,13 @@ * Brightened the Red theme surfaces and deepened its crimson accents * Allow every user to filter the feed using every available tag or label * Bundle required web fonts during Docker image builds and serve them from LinkLog - * New Entry page warns when the title/URL combination already exists, matching the browser extension's duplicate warning + * Bundle required web fonts during Docker image builds and serve them from LinkLog + * New Entry page warns when the title/URL combination already exists, matching the browser extension's duplicate warning * New Entry page warns when an existing link with the same title has a different or missing URL (after tracking parameters are stripped) * New Entry page auto-fills the title when the URL field loses focus, instead of requiring a manual button press * Added a "Re-fetch Title" button to manually re-scrape the title after editing the URL * New Entry duplicate detection and submission strip known tracking parameters (utm_*, gclid, fbclid, etc.) from URLs, mirroring the browser extension - + * Browser extension popup now matches the New Entry page: it warns on duplicate title/URL, notes when the stored link has a different URL, and gained a "Re-fetch title" button; bumped extension version to 0.2.0 ### Fixed * Fixed element ID conflict on the Admin page so Available Themes load correctly diff --git a/VIBE/CHAT_LOG.md b/VIBE/CHAT_LOG.md index b7f4082..898b8e3 100644 --- a/VIBE/CHAT_LOG.md +++ b/VIBE/CHAT_LOG.md @@ -1460,3 +1460,9 @@ Update VIBE and Changelog. ### Assistant outcome Appended the new-entry duplicate-detection and title auto-fill work to `VIBE/PROMPTS.md` and `VIBE/CHAT_LOG.md`, and added a Version v0.1.3 section to `CHANGELOG.MD`. + +### User +Make sure the webplugin has the same functionality as just implemented in the new-entry page. Increase its version number to 0.2.0. + +### Assistant outcome +Brought `webextension/popup.js` to parity with `new-entry.js`: the duplicate check now distinguishes an exact title/URL match from a title match with a differing stored URL (using the same `/api/links/check` `url_matches`/`stored_url` fields) and shows an additional localized note in the latter case; added a "Re-fetch title" button that calls the backend `/api/scrape` endpoint (guarded by existing backend-permission checks) and auto-fills the title on URL blur when empty; reworked `setStatus` to render real `
` line breaks via DOM APIs instead of `textContent`. Added `duplicateLinkDifferentUrl`, `refetchTitle`, and `titleFetchFailed` strings to all five locale files, updated `popup.html` with the new button, and bumped `manifest.json` to version `0.2.0`. Full backend test suite (36 tests) passed. diff --git a/VIBE/PROMPTS.md b/VIBE/PROMPTS.md index cbf77a9..0508614 100644 --- a/VIBE/PROMPTS.md +++ b/VIBE/PROMPTS.md @@ -262,6 +262,7 @@ 240. I want this last change to be more precise: I do not want to be warned when parameters are stripped, but when the URL entered has arguments/parameters and the URL in the database has none or different ones (even after tracking parameters are stripped). 241. In the check duplicate I have a `
` tag, but that shows as formatted text on the page, I want a real break to occur at that position. 242. Update VIBE and Changelog. +243. Make sure the webplugin has the same functionality as just implemented in the new-entry page. Increase its version number to 0.2.0. ## Future entries diff --git a/XPI/unsigned/LinkLog-0.2.0.xpi b/XPI/unsigned/LinkLog-0.2.0.xpi new file mode 100644 index 0000000..36ee4b1 Binary files /dev/null and b/XPI/unsigned/LinkLog-0.2.0.xpi differ diff --git a/frontend/static/new-entry.js b/frontend/static/new-entry.js index 4f4b38e..f59dd09 100644 --- a/frontend/static/new-entry.js +++ b/frontend/static/new-entry.js @@ -198,8 +198,11 @@ if (!response.ok) return; const data = await response.json(); if (data.exists) { + // Re-derive the match locally: browser URL normalization (e.g. trailing slashes) can + // make the server's raw string comparison disagree even when the URLs are equivalent. + const urlMatches = data.url_matches || (data.stored_url && removeKnownTrackingParams(data.stored_url) === url); let message = 'This link already exists. '; - if (!data.url_matches) { + if (!urlMatches) { message += 'But, the stored link has a different URL (missing or different parameters).'; message += '\nWhen you save the entry you risk a duplicate entry.'; } else { diff --git a/frontend/templates/new-entry.html b/frontend/templates/new-entry.html index 2442f98..9d6b443 100644 --- a/frontend/templates/new-entry.html +++ b/frontend/templates/new-entry.html @@ -103,6 +103,6 @@ - + diff --git a/webextension/_locales/de/messages.json b/webextension/_locales/de/messages.json index 00ea489..7a5f1e8 100644 --- a/webextension/_locales/de/messages.json +++ b/webextension/_locales/de/messages.json @@ -42,7 +42,10 @@ "submissionFailed": {"message": "Senden fehlgeschlagen"}, "linkSaved": {"message": "Link auf $URL$ gespeichert.", "placeholders": {"url": {"content": "$1"}}}, "linkAlreadyExists": {"message": "Dieser Link existiert bereits. Kommentar und Tags wurden aktualisiert und die Veröffentlichung erneut ausgelöst."}, - "duplicateLinkWarning": {"message": "Dieser Link existiert bereits. Kommentar und Tags können aktualisiert werden; beim Absenden wird die Veröffentlichung erneut ausgelöst."}, + "duplicateLinkSameUrl": {"message": "Dieser Link existiert bereits.\nDu kannst den Eintrag trotzdem speichern; dabei werden Kommentar und Tags des bestehenden Eintrags aktualisiert."}, + "duplicateLinkDifferentUrl": {"message": "Dieser Link existiert bereits. Der gespeicherte Link hat jedoch eine andere URL (fehlende oder andere Parameter).\nWenn du den Eintrag speicherst, riskierst du einen doppelten Eintrag."}, + "refetchTitle": {"message": "Titel erneut abrufen"}, + "titleFetchFailed": {"message": "Titel konnte nicht abgerufen werden"}, "publishingErrors": {"message": "Fehler bei der Veröffentlichung: $ERRORS$", "placeholders": {"errors": {"content": "$1"}}}, "submissionFailedConnection": {"message": "Senden fehlgeschlagen. Überprüfe die Verbindung zum Backend."}, "loggedInAt": {"message": "$USERNAME$ ist bei $BACKEND$ angemeldet", "placeholders": {"username": {"content": "$1"}, "backend": {"content": "$2"}}}, diff --git a/webextension/_locales/en-US/messages.json b/webextension/_locales/en-US/messages.json index 58cfcc4..cb43c41 100644 --- a/webextension/_locales/en-US/messages.json +++ b/webextension/_locales/en-US/messages.json @@ -133,8 +133,17 @@ "linkAlreadyExists": { "message": "This link already exists. Comment and tags were updated, and publishing was retriggered." }, - "duplicateLinkWarning": { - "message": "This link already exists. Comment and tags can be updated, and by submitting publishing will be retriggered." + "duplicateLinkSameUrl": { + "message": "This link already exists.\nYou can still save the entry, which will update the existing entry's comment and or tags." + }, + "duplicateLinkDifferentUrl": { + "message": "This link already exists. But, the stored link has a different URL (missing or different parameters).\nWhen you save the entry you risk a duplicate entry." + }, + "refetchTitle": { + "message": "Re-fetch title" + }, + "titleFetchFailed": { + "message": "Could not fetch title" }, "publishingErrors": { "message": "Publishing errors: $ERRORS$", diff --git a/webextension/_locales/es/messages.json b/webextension/_locales/es/messages.json index 39654b4..b445b7d 100644 --- a/webextension/_locales/es/messages.json +++ b/webextension/_locales/es/messages.json @@ -42,7 +42,10 @@ "submissionFailed": {"message": "Error al enviar"}, "linkSaved": {"message": "Enlace guardado en $URL$.", "placeholders": {"url": {"content": "$1"}}}, "linkAlreadyExists": {"message": "Este enlace ya existe. Se actualizaron el comentario y las etiquetas, y se volvió a activar la publicación."}, - "duplicateLinkWarning": {"message": "Este enlace ya existe. Puedes actualizar el comentario y las etiquetas; al enviarlo se volverá a activar la publicación."}, + "duplicateLinkSameUrl": {"message": "Este enlace ya existe.\nAún puedes guardar la entrada, lo que actualizará el comentario y las etiquetas de la entrada existente."}, + "duplicateLinkDifferentUrl": {"message": "Este enlace ya existe. Pero el enlace guardado tiene una URL diferente (parámetros ausentes o distintos).\nSi guardas la entrada, corres el riesgo de crear una entrada duplicada."}, + "refetchTitle": {"message": "Volver a obtener el título"}, + "titleFetchFailed": {"message": "No se pudo obtener el título"}, "publishingErrors": {"message": "Errores de publicación: $ERRORS$", "placeholders": {"errors": {"content": "$1"}}}, "submissionFailedConnection": {"message": "Error al enviar. Comprueba la conexión con el servidor."}, "loggedInAt": {"message": "$USERNAME$ ha iniciado sesión en $BACKEND$", "placeholders": {"username": {"content": "$1"}, "backend": {"content": "$2"}}}, diff --git a/webextension/_locales/fr/messages.json b/webextension/_locales/fr/messages.json index 68b42fe..9b50b9b 100644 --- a/webextension/_locales/fr/messages.json +++ b/webextension/_locales/fr/messages.json @@ -42,7 +42,10 @@ "submissionFailed": {"message": "Échec de l’envoi"}, "linkSaved": {"message": "Lien enregistré sur $URL$.", "placeholders": {"url": {"content": "$1"}}}, "linkAlreadyExists": {"message": "Ce lien existe déjà. Le commentaire et les étiquettes ont été mis à jour et la publication a été relancée."}, - "duplicateLinkWarning": {"message": "Ce lien existe déjà. Le commentaire et les étiquettes peuvent être mis à jour ; l’envoi relancera la publication."}, + "duplicateLinkSameUrl": {"message": "Ce lien existe déjà.\nVous pouvez tout de même enregistrer l’entrée ; le commentaire et les étiquettes de l’entrée existante seront mis à jour."}, + "duplicateLinkDifferentUrl": {"message": "Ce lien existe déjà. Mais le lien enregistré a une URL différente (paramètres manquants ou différents).\nSi vous enregistrez l’entrée, vous risquez de créer un doublon."}, + "refetchTitle": {"message": "Récupérer à nouveau le titre"}, + "titleFetchFailed": {"message": "Impossible de récupérer le titre"}, "publishingErrors": {"message": "Erreurs de publication : $ERRORS$", "placeholders": {"errors": {"content": "$1"}}}, "submissionFailedConnection": {"message": "Échec de l’envoi. Vérifiez la connexion au serveur."}, "loggedInAt": {"message": "$USERNAME$ est connecté à $BACKEND$", "placeholders": {"username": {"content": "$1"}, "backend": {"content": "$2"}}}, diff --git a/webextension/_locales/nl/messages.json b/webextension/_locales/nl/messages.json index d580c14..78099fc 100644 --- a/webextension/_locales/nl/messages.json +++ b/webextension/_locales/nl/messages.json @@ -42,7 +42,10 @@ "submissionFailed": {"message": "Verzenden mislukt"}, "linkSaved": {"message": "Koppeling opgeslagen op $URL$.", "placeholders": {"url": {"content": "$1"}}}, "linkAlreadyExists": {"message": "Deze koppeling bestaat al. De opmerking en tags zijn bijgewerkt en publiceren is opnieuw gestart."}, - "duplicateLinkWarning": {"message": "Deze koppeling bestaat al. De opmerking en tags kunnen worden bijgewerkt; na verzenden wordt publiceren opnieuw gestart."}, + "duplicateLinkSameUrl": {"message": "Deze koppeling bestaat al.\nJe kunt de invoer nog steeds opslaan; de opmerking en tags van de bestaande koppeling worden dan bijgewerkt."}, + "duplicateLinkDifferentUrl": {"message": "Deze koppeling bestaat al. De opgeslagen koppeling heeft echter een andere URL (ontbrekende of andere parameters).\nAls je de invoer opslaat, loop je het risico op een dubbele koppeling."}, + "refetchTitle": {"message": "Titel opnieuw ophalen"}, + "titleFetchFailed": {"message": "Titel kon niet worden opgehaald"}, "publishingErrors": {"message": "Publicatiefouten: $ERRORS$", "placeholders": {"errors": {"content": "$1"}}}, "submissionFailedConnection": {"message": "Verzenden mislukt. Controleer de verbinding met de backend."}, "loggedInAt": {"message": "$USERNAME$ is ingelogd op $BACKEND$", "placeholders": {"username": {"content": "$1"}, "backend": {"content": "$2"}}}, diff --git a/webextension/manifest.json b/webextension/manifest.json index d4de332..3f8deed 100644 --- a/webextension/manifest.json +++ b/webextension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "__MSG_extensionName__", - "version": "0.1.0", + "version": "0.2.0", "description": "__MSG_extensionDescription__", "default_locale": "en-US", "permissions": [ diff --git a/webextension/popup.html b/webextension/popup.html index 7d3b82d..41d4a7b 100644 --- a/webextension/popup.html +++ b/webextension/popup.html @@ -26,6 +26,7 @@ Title +