-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue with mobile devices and deleting annotation one by one #51
Comments
@gasman <head>
<style>
.annotator-controls {
position: relative;
cursor: pointer;
font-size: 20px;
color: white !important; /* X color */
background-color: red; /* Button background */
padding: 5px;
border-radius: 50%; /* Make it a circle */
width: 30px; /* Set width and height to create a circular shape */
height: 30px;
display: flex;
align-items: center; /* Center the X vertically */
justify-content: center; /* Center the X horizontally */
font-weight: bold; /* Make the X bold */
transition: background-color 0.3s ease; /* Optional: Transition effect */
}
/* Add the X using the ::before pseudo-element */
.annotator-controls::before {
content: '×'; /* The X mark */
color: white;
}
/* Optional hover effect for better UX */
.annotator-controls:hover {
background-color: darkred; /* Darker red on hover */
}
</style>
</head>
<script>
const app = new annotator.App();
{% if allow_annotations %}
app.include(annotator.ui.main, {
viewerExtensions: [annotatorExt.viewerWithUsernames]
});
{% else %}
app.include(annotatorExt.viewerModeUi);
{% endif %}
app.include(annotator.storage.http, {
'prefix': "{% url 'wagtail_review:annotations_api_root' %}",
'urls': {
create: 'annotations/',
update: 'annotations/{id}/',
destroy: 'annotations/{id}/',
search: 'search/'
},
'headers': {
{% if allow_annotations %}
'X-CSRFToken': document.getElementById('wagtailreview-respond-form').csrfmiddlewaretoken.value,
{% endif %}
'X-WagtailReview-mode': '{{ mode }}',
'X-WagtailReview-reviewer': '{{ reviewer.id }}',
'X-WagtailReview-token': '{{ token }}',
}
});
app.start().then(function () {
app.annotations.load();
});
{% if allow_responses %}
document.addEventListener('DOMContentLoaded', function() {
function deleteAnnotation() {
// Assuming you have access to the annotator.js instance and its methods
// Call the annotator.js method to delete the annotation
console.log("it is clicked")
console.log(this)
}
// Function to inject text and add click event to the span
function injectTextAndAddEvent(span) {
span.addEventListener('click', deleteAnnotation); // Add click event to call delete function
}
document.querySelectorAll('.annotator-outer.annotator-viewer').forEach(parentDiv => {
parentDiv.addEventListener('mouseenter', function() {
// When the parent is hovered, find the span with class 'annotator-controls'
const span = parentDiv.querySelector('.annotator-controls');
if (span) {
injectTextAndAddEvent(span);
}
});
parentDiv.addEventListener('mouseleave', function() {
// You can optionally remove the click event or take another action when hover is removed
const span = parentDiv.querySelector('.annotator-controls');
if (span) {
span.removeEventListener('click', deleteAnnotation); // Optional clean-up
}
});
});
const form = document.getElementById('wagtailreview-respond-form');
form.style.display = 'none';
formShown = false;
{# Auto-update the form's hidden input when clicking on one of the buttons #}
form.querySelectorAll("button").forEach(button =>
button.addEventListener("click", (event) =>
document.querySelector("#id_result").value =
(event.currentTarget.id === "approve_text")
{# values from wagtail_review/models.py RESULT_CHOICES #}
? "approve" : "comment"
)
);
let button_close_modal=document.getElementById("close_modal");
let overlay = document.getElementById("my-overlay");
let button_respond_review=document.getElementById('wagtailreview-respond-button')
button_close_modal.addEventListener('click', function() {
if (formShown) {
form.style.display = 'none';
overlay.style.display = "none";
formShown = false;
}
})
window.onclick = function(event) {
if (event.target == overlay && formShown) {
form.style.display = 'none';
overlay.style.display = "none";
formShown = false;
}
}
button_respond_review.addEventListener('click', function() {
if (formShown) {
form.style.display = 'none';
overlay.style.display = "none";
formShown = false;
} else {
form.style.display = 'block';
overlay.style.display = "block";
if (document.querySelector(".annotator-hl")){
let approved = document.getElementById('approve_text')
let refused = document.getElementById('refuse_text')
approved.classList.add("hidden");
refused.classList.remove("hidden");
}
formShown = true;
}
return false;
});
});
// TODO: add error alert if approve and comment are not selected
{% endif %}
</script>
{% endif %} |
Screencast.from.10-21-2024.09.51.14.AM.webm |
here related question in stackoverflow: https://stackoverflow.com/q/79108407/5792426 |
@gasman // Function to delete the annotation by sending an API DELETE request
function deleteAnnotation(annotationId) {
// Use the correct API root (prefix) for Wagtail Review annotations
const prefix = app.annotations.store.options.prefix; // This is '/review/api/'
const deleteUrl = `${prefix}annotations/${annotationId}/`; // Construct the full delete URL
// Retrieve the CSRF token directly from app.annotations.store
const csrfToken = app.annotations.store.options.headers["X-CSRFToken"];
fetch(deleteUrl, {
method: 'DELETE',
headers: {
'X-CSRFToken': csrfToken, // Use the CSRF token from app.annotations.store
'Content-Type': 'application/json'
}
})
.then(response => {
if (response.ok) {
console.log(`Annotation ${annotationId} deleted successfully`);
} else {
console.error(`Failed to delete annotation ${annotationId}: ${response.status}`);
}
})
.catch(error => {
console.error('Error during deletion:', error);
});
}
// Function to inject text and add click event to the span
function injectTextAndAddEvent(span, annotationId) {
span.addEventListener('click', function() {
deleteAnnotation(annotationId); // Call delete function with the correct ID
});
}
document.querySelectorAll('.annotator-outer.annotator-viewer').forEach(parentDiv => {
parentDiv.addEventListener('mouseenter', function() {
// When the parent is hovered, find the span with class 'annotator-controls'
const span = parentDiv.querySelector('.annotator-controls');
if (span) {
// Pass the correct annotation ID to the function
const annotationId = 158; // Replace this with the correct ID dynamically
injectTextAndAddEvent(span, annotationId);
}
});
parentDiv.addEventListener('mouseleave', function() {
// You can optionally remove the click event or take another action when hover is removed
const span = parentDiv.querySelector('.annotator-controls');
if (span) {
span.removeEventListener('click', deleteAnnotation); // Optional clean-up
}
});
}); also I can access all annotation through this code : app.annotations.query().then(response => {
// Now you have access to the results
const annotations = response.results;
// Log the annotations array to inspect it
console.log('Annotations:', annotations);
});
``` |
by the way we need to update the item view to become like this (so it can handle delete URL requests: @never_cache
def item(request, id):
reviewer, mode = _check_reviewer_credentials(request)
if request.method == 'GET':
annotation = get_object_or_404(Annotation, id=id)
# only allow retrieving annotations within the same review as the current user's credentials
if reviewer.review != annotation.reviewer.review:
raise PermissionDenied
return JsonResponse(annotation.as_json_data())
elif request.method == 'DELETE':
annotation = get_object_or_404(Annotation, id=id)
# Check if the reviewer is allowed to delete the annotation
if reviewer.review != annotation.reviewer.review:
raise PermissionDenied
# If the reviewer has permission, delete the annotation
annotation.delete()
return JsonResponse({'status': 'Annotation deleted successfully'}, status=204)
else:
return HttpResponseNotAllowed(['GET', 'DELETE'], "Method not allowed") |
@gasman |
almost resolved it: document.addEventListener('DOMContentLoaded', function() {
const csrfToken = document.getElementById('wagtailreview-respond-form').csrfmiddlewaretoken.value;
// Function to remove the highlight from the text corresponding to the deleted annotation
function removeHighlight(annotationId) {
// Assuming the highlight has a specific class or attribute related to the annotation ID
const highlights = document.querySelectorAll(`[data-annotation-id="${annotationId}"]`);
highlights.forEach(function(highlight) {
highlight.classList.remove('annotator-hl'); // Option 1: Reset background color
// Option 2: Remove the highlight element entirely
// highlight.parentNode.removeChild(highlight);
});
}
// Function to delete the annotation by ID
// Function to delete the annotation by sending an API DELETE request
function deleteAnnotation(annotationId) {
const prefix = app.annotations.store.options.prefix;
const deleteUrl = `${prefix}annotations/${annotationId}/`;
// Retrieve necessary headers
const mode = app.annotations.store.options.headers["X-WagtailReview-mode"];
const reviewerId = app.annotations.store.options.headers["X-WagtailReview-reviewer"];
const token = app.annotations.store.options.headers["X-WagtailReview-token"];
fetch(deleteUrl, {
method: 'DELETE',
headers: {
'X-CSRFToken': csrfToken,
'X-WagtailReview-Mode': mode,
'X-WagtailReview-Reviewer': reviewerId,
'X-WagtailReview-Token': token,
'Content-Type': 'application/json'
}
})
.then(response => {
if (response.ok) {
console.log(`Annotation ${annotationId} deleted successfully`);
removeHighlight(annotationId); // Call this function to remove the highlight
} else {
console.error(`Failed to delete annotation ${annotationId}: ${response.status}`);
}
})
.catch(error => {
console.error('Error during deletion:', error);
});
}
// Function to inject text and add click event to the span
function injectTextAndAddEvent(span, annotationId) {
span.addEventListener('click', function() {
deleteAnnotation(annotationId); // Call delete function with the correct ID
});
}
document.querySelectorAll('.annotator-outer.annotator-viewer').forEach(parentDiv => {
parentDiv.addEventListener('mouseenter', function() {
// When the parent is hovered, find the span with class 'annotator-controls'
// Find the inner div inside the structure that contains the text
const textDiv = parentDiv.querySelector('ul li div');
// Exclude the reviewer name and only get the annotation text after the <p> tag
const annotationText = textDiv.childNodes[1].textContent.trim(); // Get only the second child node, which is the text
app.annotations.query().then(response => {
// Assign the results to the broader scope variable
annotations = response.results;
// Loop through the annotations and find the one that matches the text
const span = parentDiv.querySelector('.annotator-controls');
annotations.forEach(annotation => {
if (annotation.text === annotationText) { // Ensure 'annotationText' is defined before comparison
annotationId = annotation.id; // Assign the annotationId
}
});
if (span) {
// Pass the correct annotation ID to the function
injectTextAndAddEvent(span, annotationId);
}
});
});
parentDiv.addEventListener('mouseleave', function() {
// You can optionally remove the click event or take another action when hover is removed
const span = parentDiv.querySelector('.annotator-controls');
if (span) {
span.removeEventListener('click', deleteAnnotation); // Optional clean-up
}
});
});
}) |
Hi @oladhari - I don't remember seeing this issue before, but I probably skipped over it because your message never stated what the issue actually is. "Issue with mobile devices" could mean anything at all, ranging from "it is completely broken" to "the animation isn't very smooth". There are hundreds of open issues across all Wagtail projects, and if I need to do extra work (or research a new JS library) just to learn what the problem is, then this one will end up very low on my priority list. Unfortunately I do not have the resources to keep track of the issue list for add-on packages in the same way that I would do for Wagtail itself. Chasing me up simultaneously on Github, Slack, email and Stack Overflow is not appropriate, and will not get this addressed any faster. |
Thank you very much for your reply and sorry for the harrassement |
the best solution that I suggest is to replace
Annotator.js
package in wagtail-review byRecogito.js
package which can support both deleting annotation one by one and also using on mobile and tabletThe text was updated successfully, but these errors were encountered: