mirror of
https://github.com/sissbruecker/linkding.git
synced 2025-08-14 05:59:29 +02:00
Add bulk and single bookmark metadata refresh (#999)
* Add url create/edit query paramter to clear cache * Add refresh bookmark metadata button in create/edit bookmark page * Fix refresh bookmark metadata when editing existing bookmark * Add bulk refresh metadata functionality * Fix test cases for bulk view dropdown selection list * Allow bulk metadata refresh when background tasks are disabled * Move load preview image call on refresh metadata * Update bookmark modified time on metadata refresh * Rename function to align with convention * Add tests for refresh task * Add tests for bookmarks service refresh metadata * Add tests for bookmarks api disable cache on check * Remove bulk refresh metadata when background tasks disabled * Refactor refresh metadata task * Remove unnecessary call * Fix testing mock name * Abstract clearing metadata cache * Add test to check if load page is called twice when cache disabled * Remove refresh button for new bookmarks * Remove strict disable cache is true check * Refactor refresh metadata form logic into its own function * move button and highlight changes * polish and update tests --------- Co-authored-by: Sascha Ißbrücker <sascha.issbruecker@gmail.com>
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
<option value="bulk_share">Share</option>
|
||||
<option value="bulk_unshare">Unshare</option>
|
||||
{% endif %}
|
||||
<option value="bulk_refresh">Refresh from website</option>
|
||||
</select>
|
||||
<div class="tag-autocomplete d-none" ld-tag-autocomplete>
|
||||
<input name="bulk_tag_string" class="form-input input-sm" placeholder="Tag names..." variant="small">
|
||||
|
@@ -33,9 +33,12 @@
|
||||
<div class="form-group">
|
||||
<div class="d-flex justify-between align-baseline">
|
||||
<label for="{{ form.title.id_for_label }}" class="form-label">Title</label>
|
||||
<button ld-clear-button data-for="{{ form.title.id_for_label }}" class="btn btn-link clear-button"
|
||||
type="button">Clear
|
||||
</button>
|
||||
<div class="flex">
|
||||
<button id="refresh-button" class="btn btn-link suffix-button" type="button">Refresh from website</button>
|
||||
<button ld-clear-button data-for="{{ form.title.id_for_label }}" class="ml-2 btn btn-link suffix-button clear-button"
|
||||
type="button">Clear
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{ form.title|add_class:"form-input"|attr:"autocomplete:off" }}
|
||||
{{ form.title.errors }}
|
||||
@@ -43,7 +46,8 @@
|
||||
<div class="form-group">
|
||||
<div class="d-flex justify-between align-baseline">
|
||||
<label for="{{ form.description.id_for_label }}" class="form-label">Description</label>
|
||||
<button ld-clear-button data-for="{{ form.description.id_for_label }}" class="btn btn-link clear-button"
|
||||
<button ld-clear-button data-for="{{ form.description.id_for_label }}"
|
||||
class="btn btn-link suffix-button clear-button"
|
||||
type="button">Clear
|
||||
</button>
|
||||
</div>
|
||||
@@ -111,6 +115,7 @@
|
||||
const notesInput = document.getElementById('{{ form.notes.id_for_label }}');
|
||||
const unreadCheckbox = document.getElementById('{{ form.unread.id_for_label }}');
|
||||
const sharedCheckbox = document.getElementById('{{ form.shared.id_for_label }}');
|
||||
const refreshButton = document.getElementById('refresh-button');
|
||||
const bookmarkExistsHint = document.querySelector('.form-input-hint.bookmark-exists');
|
||||
const editedBookmarkId = {{ form.instance.id|default:0 }};
|
||||
let isTitleModified = !!titleInput.value;
|
||||
@@ -154,6 +159,7 @@
|
||||
// Display hint if URL is already bookmarked
|
||||
const existingBookmark = data.bookmark;
|
||||
bookmarkExistsHint.style['display'] = existingBookmark ? 'block' : 'none';
|
||||
refreshButton.style['display'] = existingBookmark ? 'inline-block' : 'none';
|
||||
|
||||
// Prefill form with existing bookmark data
|
||||
if (existingBookmark) {
|
||||
@@ -193,6 +199,36 @@
|
||||
});
|
||||
}
|
||||
|
||||
function refreshMetadata() {
|
||||
if (!urlInput.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
toggleLoadingIcon(urlInput, true);
|
||||
|
||||
const websiteUrl = encodeURIComponent(urlInput.value);
|
||||
const requestUrl = `{% url 'linkding:api-root' %}bookmarks/check?url=${websiteUrl}&ignore_cache=true`;
|
||||
|
||||
fetch(requestUrl)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const metadata = data.metadata;
|
||||
const existingBookmark = data.bookmark;
|
||||
toggleLoadingIcon(urlInput, false);
|
||||
|
||||
if (metadata.title && metadata.title !== existingBookmark?.title) {
|
||||
titleInput.value = metadata.title;
|
||||
titleInput.classList.add("modified");
|
||||
}
|
||||
|
||||
if (metadata.description && metadata.description !== existingBookmark?.description) {
|
||||
descriptionInput.value = metadata.description;
|
||||
descriptionInput.classList.add("modified");
|
||||
}
|
||||
});
|
||||
}
|
||||
refreshButton.addEventListener('click', refreshMetadata);
|
||||
|
||||
// Fetch website metadata when page loads and when URL changes, unless we are editing an existing bookmark
|
||||
if (!editedBookmarkId) {
|
||||
checkUrl();
|
||||
@@ -203,6 +239,8 @@
|
||||
descriptionInput.addEventListener('input', () => {
|
||||
isDescriptionModified = true;
|
||||
});
|
||||
} else {
|
||||
refreshButton.style['display'] = 'inline-block';
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user