This commit is contained in:
isUnknown 2025-01-08 12:12:10 +01:00
parent cd04c232a6
commit 32b01f4c98
3 changed files with 87 additions and 18 deletions

View file

@ -3,7 +3,10 @@
:id="`comment-${comment.id}`"
class="comment | flow"
:data-status="getStatus"
@click="read()"
@click="handleClick()"
@mouseenter="hightlightCorrespondingMarker()"
@mouseleave="unhightlightCorrespondingMarker()"
ref="comment-node"
>
<header>
<p>
@ -80,7 +83,7 @@ import "dayjs/locale/fr";
import { useUserStore } from "../../stores/user";
import { useApiStore } from "../../stores/api";
import { useDialogStore } from "../../stores/dialog";
import { computed, ref } from "vue";
import { computed, onMounted, ref, useTemplateRef } from "vue";
import { storeToRefs } from "pinia";
dayjs.locale("fr");
@ -95,9 +98,11 @@ const emits = defineEmits(["update:file", "close:comment"]);
const userStore = useUserStore();
const api = useApiStore();
const dialog = useDialogStore();
const { activeTracks } = storeToRefs(useDialogStore());
const { activeTracks, openedComment } = storeToRefs(useDialogStore());
const draftText = ref(comment.text);
const editField = ref(null);
const commentNode = useTemplateRef("comment-node");
let correspondingMarker = null;
// Functions
const getStatus = computed(() => {
@ -130,6 +135,11 @@ function closeAddField() {
newCommentText.value = "";
}
function handleClick() {
read();
scrollTo();
}
async function read() {
if (getStatus.value !== "unread") return;
try {
@ -141,13 +151,21 @@ async function read() {
}
}
function scrollTo() {
const correspondingMarker = document.querySelector(
`.comment-marker[href="#comment-${comment.id}"]`
);
if (!correspondingMarker) return;
correspondingMarker.scrollIntoView();
}
async function deleteComment(event) {
event.stopPropagation();
const newFile = await api.deleteComment(comment);
// If there is an active track,
// it's not the opened file that should be updated
// but the corresponding file in the active track
// If there is an active track, we are not in PDF mode with a single file.
// Thus, it's not the opened file that should be updated
// but the corresponding file in the active track.
if (activeTracks.value?.length > 0) {
activeTracks.value[0].files = activeTracks.value[0].files.map((file) => {
if (file.uuid !== newFile.uuid) return file;
@ -181,6 +199,32 @@ function editComment(event) {
editField.value.focus();
}, 100);
}
function hightlightCorrespondingMarker() {
if (comment.type === "comment-reply") return;
const correspondingMarker = document.querySelector(
`.comment-marker[href="#comment-${comment.id}"]`
);
if (!correspondingMarker) return;
commentNode.value.classList.add("highlight");
correspondingMarker.classList.add("active");
correspondingMarker.classList.add("big");
}
function unhightlightCorrespondingMarker() {
if (comment.type === "comment-reply") return;
const correspondingMarker = document.querySelector(
`.comment-marker[href="#comment-${comment.id}"]`
);
if (!correspondingMarker) return;
if (openedComment.value) return;
commentNode.value.classList.remove("highlight");
correspondingMarker.classList.remove("active");
correspondingMarker.classList.remove("big");
}
</script>
<style scoped>

View file

@ -121,13 +121,10 @@ dayjs.locale("fr");
const { user } = useUserStore();
const { page } = usePageStore();
const dialog = useDialogStore();
const { comments, openedFile, draftComment, activeTracks } = storeToRefs(
useDialogStore()
);
const { comments, openedFile, openedComment, draftComment, activeTracks } =
storeToRefs(useDialogStore());
const api = useApiStore();
const openedComment = ref(null);
const isAddOpen = ref(false);
const route = useRoute();
const waitingForCommentPosition = ref(false);
@ -139,6 +136,10 @@ const sortedReplies = ref(null);
watch(openedComment, (newVal) => {
sortedReplies.value = newVal ? newVal.replies.slice().reverse() : null;
if (!newVal) {
unhighlightAllComments();
}
});
watch(isAddOpen, (newVal) => {
@ -165,6 +166,13 @@ window.addEventListener("keydown", (event) => {
});
// Functions
function unhighlightAllComments() {
document.querySelectorAll(".comment-marker.big").forEach((commentNode) => {
commentNode.classList.remove("big");
commentNode.classList.remove("active");
});
}
function handleSubmit(event = null) {
if (event) {
event.preventDefault();
@ -427,6 +435,7 @@ function openComment(comment) {
width: var(--marker-size);
height: var(--marker-size);
background: var(--icon-comment-default) no-repeat center / contain;
scroll-margin-block-start: 4rem;
cursor: pointer !important;
z-index: 999;
overflow: visible;
@ -435,7 +444,8 @@ function openComment(comment) {
margin-left: calc(var(--marker-size) * -0.025);
margin-top: calc(var(--marker-size) / -1.025);
}
.comment-marker:hover {
.comment-marker:hover,
.comment-marker.big {
transform: scale(1.1);
}
.comment-marker.active,