improve comments system
This commit is contained in:
parent
8bb4f552cd
commit
e55eb48f45
5 changed files with 63 additions and 41 deletions
|
|
@ -22,7 +22,7 @@ class Position
|
||||||
public function toArray() {
|
public function toArray() {
|
||||||
$array = [];
|
$array = [];
|
||||||
|
|
||||||
if ($this->pageIndex) {
|
if (isset($this->pageIndex)) {
|
||||||
$array["pageIndex"] = $this->pageIndex;
|
$array["pageIndex"] = $this->pageIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ const route = useRoute();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const api = useApiStore();
|
const api = useApiStore();
|
||||||
const dialog = useDialogStore();
|
const dialog = useDialogStore();
|
||||||
const { activeTracks, openedComment } = storeToRefs(useDialogStore());
|
const { activeTracks, openedComment, vpvRef } = storeToRefs(useDialogStore());
|
||||||
const draftText = ref(comment.text);
|
const draftText = ref(comment.text);
|
||||||
const editField = ref(null);
|
const editField = ref(null);
|
||||||
const commentNode = useTemplateRef("comment-node");
|
const commentNode = useTemplateRef("comment-node");
|
||||||
|
|
@ -157,11 +157,15 @@ async function read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollTo() {
|
function scrollTo() {
|
||||||
const correspondingMarker = document.querySelector(
|
vpvRef.value.goToPage(comment.position.pageIndex);
|
||||||
`.comment-marker[href="#comment-${comment.id}"]`
|
setTimeout(() => {
|
||||||
);
|
const correspondingMarker = document.querySelector(
|
||||||
if (!correspondingMarker) return;
|
`.comment-marker[href="#comment-${comment.id}"]`
|
||||||
correspondingMarker.scrollIntoView();
|
);
|
||||||
|
console.log(correspondingMarker);
|
||||||
|
if (!correspondingMarker) return;
|
||||||
|
correspondingMarker.scrollIntoView();
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteComment(event) {
|
async function deleteComment(event) {
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,7 @@ async function addComment(newComment) {
|
||||||
/projects\/.*?(?=\/[^/]+\/[^/]+$)/
|
/projects\/.*?(?=\/[^/]+\/[^/]+$)/
|
||||||
);
|
);
|
||||||
newComment.fileParentUri = matchFileParentUri ? matchFileParentUri[0] : null;
|
newComment.fileParentUri = matchFileParentUri ? matchFileParentUri[0] : null;
|
||||||
|
console.log(newComment);
|
||||||
const newFile = await api.addComment(newComment);
|
const newFile = await api.addComment(newComment);
|
||||||
resetDraftComment();
|
resetDraftComment();
|
||||||
isAddOpen.value = false;
|
isAddOpen.value = false;
|
||||||
|
|
@ -271,10 +272,7 @@ function prepareDraftCommentInPdf(event) {
|
||||||
const pageContainer = event.target.closest(".page-inner-container");
|
const pageContainer = event.target.closest(".page-inner-container");
|
||||||
if (!pageContainer || !viewContainer) return;
|
if (!pageContainer || !viewContainer) return;
|
||||||
|
|
||||||
const pageLabel = pageContainer
|
const pageIndex = parseInt(pageContainer.dataset.pageIndex) + 1;
|
||||||
.closest(".vpv-page-inner-container")
|
|
||||||
.getAttribute("aria-label");
|
|
||||||
const pageIndex = pageLabel.charAt(pageLabel.length - 1);
|
|
||||||
|
|
||||||
const viewRect = viewContainer.getBoundingClientRect();
|
const viewRect = viewContainer.getBoundingClientRect();
|
||||||
const pageRect = pageContainer.getBoundingClientRect();
|
const pageRect = pageContainer.getBoundingClientRect();
|
||||||
|
|
@ -287,8 +285,6 @@ function prepareDraftCommentInPdf(event) {
|
||||||
const relativeX = (x / pageRect.width) * 100;
|
const relativeX = (x / pageRect.width) * 100;
|
||||||
const relativeY = (y / pageRect.height) * 100;
|
const relativeY = (y / pageRect.height) * 100;
|
||||||
|
|
||||||
console.log(pageIndex);
|
|
||||||
|
|
||||||
draftComment.value.position = {
|
draftComment.value.position = {
|
||||||
x: relativeX,
|
x: relativeX,
|
||||||
y: relativeY,
|
y: relativeY,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
:src="openedFile.url"
|
:src="openedFile.url"
|
||||||
local="fr_FR"
|
local="fr_FR"
|
||||||
@loaded="onPdfLoaded"
|
@loaded="onPdfLoaded"
|
||||||
|
ref="vpvRef"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
id="toggle-comments"
|
id="toggle-comments"
|
||||||
|
|
@ -23,18 +24,17 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Comments from "../comments/Comments.vue";
|
import Comments from "../comments/Comments.vue";
|
||||||
import { ref, watch } from "vue";
|
import { computed, ref, watch } from "vue";
|
||||||
import { useDialogStore } from "../../stores/dialog";
|
import { useDialogStore } from "../../stores/dialog";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { VPdfViewer, useLicense } from "@vue-pdf-viewer/viewer";
|
import { VPdfViewer, useLicense } from "@vue-pdf-viewer/viewer";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
|
||||||
|
|
||||||
const licenseKey = import.meta.env.VITE_VPV_LICENSE ?? 'd0ab730a-ebba-4060-856c-76d322565645';
|
const licenseKey =
|
||||||
|
import.meta.env.VITE_VPV_LICENSE ?? "d0ab730a-ebba-4060-856c-76d322565645";
|
||||||
useLicense({ licenseKey });
|
useLicense({ licenseKey });
|
||||||
|
|
||||||
const { openedFile, isCommentsOpen, comments, draftComment } = storeToRefs(
|
const { openedFile, isCommentsOpen, vpvRef } = storeToRefs(useDialogStore());
|
||||||
useDialogStore()
|
const { resetCommentMarkers } = useDialogStore();
|
||||||
);
|
|
||||||
|
|
||||||
const currentPageIndex = ref(1);
|
const currentPageIndex = ref(1);
|
||||||
|
|
||||||
|
|
@ -46,6 +46,9 @@ const onPdfLoaded = () => {
|
||||||
(entries) => {
|
(entries) => {
|
||||||
entries.forEach((entry, index) => {
|
entries.forEach((entry, index) => {
|
||||||
if (entry.intersectionRatio > 0.5) {
|
if (entry.intersectionRatio > 0.5) {
|
||||||
|
if (isCommentsOpen.value) {
|
||||||
|
resetCommentMarkers();
|
||||||
|
}
|
||||||
currentPageIndex.value = parseInt(
|
currentPageIndex.value = parseInt(
|
||||||
entry.target.getAttribute("aria-label").split(" ")[1]
|
entry.target.getAttribute("aria-label").split(" ")[1]
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ export const useDialogStore = defineStore("dialog", () => {
|
||||||
const content = ref(null);
|
const content = ref(null);
|
||||||
const openedFile = ref(null);
|
const openedFile = ref(null);
|
||||||
const activeTracks = ref(null);
|
const activeTracks = ref(null);
|
||||||
|
const vpvRef = ref(null);
|
||||||
|
|
||||||
const comments = computed(() => {
|
const comments = computed(() => {
|
||||||
if (activeTracks.value?.length > 0) {
|
if (activeTracks.value?.length > 0) {
|
||||||
|
|
@ -35,23 +36,6 @@ export const useDialogStore = defineStore("dialog", () => {
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
function showDraftMarker(draftComment) {
|
|
||||||
const bubble = document.createElement("a");
|
|
||||||
|
|
||||||
bubble.classList.add("comment-marker");
|
|
||||||
bubble.classList.add("comment-marker--draft");
|
|
||||||
bubble.style.left = draftComment.position.x + "%";
|
|
||||||
bubble.style.top = draftComment.position.y + "%";
|
|
||||||
bubble.href = "#comment-" + draftComment.id;
|
|
||||||
|
|
||||||
const container = draftComment.position.pageIndex
|
|
||||||
? document.querySelector(
|
|
||||||
`.vpv-page-inner-container[aria-label="page ${draftComment.position.pageIndex}"] .page-inner-container`
|
|
||||||
)
|
|
||||||
: document.querySelector(".track");
|
|
||||||
|
|
||||||
container.appendChild(bubble);
|
|
||||||
}
|
|
||||||
|
|
||||||
const isViewerDisabled = ref(false);
|
const isViewerDisabled = ref(false);
|
||||||
watch(isCommentsOpen, (newVal) => {
|
watch(isCommentsOpen, (newVal) => {
|
||||||
|
|
@ -81,14 +65,43 @@ export const useDialogStore = defineStore("dialog", () => {
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function resetCommentMarkers() {
|
||||||
|
removeCommentMarkers();
|
||||||
|
setCommentMarkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDraftMarker(draftComment) {
|
||||||
|
const bubble = document.createElement("a");
|
||||||
|
|
||||||
|
bubble.classList.add("comment-marker");
|
||||||
|
bubble.classList.add("comment-marker--draft");
|
||||||
|
bubble.style.left = draftComment.position.x + "%";
|
||||||
|
bubble.style.top = draftComment.position.y + "%";
|
||||||
|
bubble.href = "#comment-" + draftComment.id;
|
||||||
|
|
||||||
|
const container = draftComment.position.pageIndex
|
||||||
|
? document.querySelector(
|
||||||
|
`.vpv-page-inner-container[aria-label="page ${draftComment.position.pageIndex}"] .page-inner-container`
|
||||||
|
)
|
||||||
|
: document.querySelector(".track");
|
||||||
|
|
||||||
|
try {
|
||||||
|
container.appendChild(bubble);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(
|
||||||
|
`Can't show draft comment on page ${draftComment.position.pageIndex} : `,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
function setCommentMarkers() {
|
function setCommentMarkers() {
|
||||||
if (!comments.value) return;
|
if (!comments.value) return;
|
||||||
comments.value.forEach((comment) => {
|
comments.value.forEach((comment) => {
|
||||||
const correspondingMarker = document.querySelector(
|
|
||||||
`.comment-marker[href="#comment-${comment.id}"]`
|
|
||||||
);
|
|
||||||
if (comment.location.file.uuid !== openedFile.value.uuid) return;
|
if (comment.location.file.uuid !== openedFile.value.uuid) return;
|
||||||
if (comment.type === "comment-reply") return;
|
if (comment.type === "comment-reply") return;
|
||||||
|
let correspondingMarker = document.querySelector(
|
||||||
|
`.comment-marker[href="#comment-${comment.id}"]`
|
||||||
|
);
|
||||||
if (correspondingMarker) return;
|
if (correspondingMarker) return;
|
||||||
|
|
||||||
const bubble = document.createElement("a");
|
const bubble = document.createElement("a");
|
||||||
|
|
@ -106,20 +119,24 @@ export const useDialogStore = defineStore("dialog", () => {
|
||||||
|
|
||||||
const timeOut = container ? 0 : 500;
|
const timeOut = container ? 0 : 500;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
container = comment.position?.pageIndex
|
container = comment.position?.hasOwnProperty("pageIndex")
|
||||||
? document.querySelector(
|
? document.querySelector(
|
||||||
`.vpv-page-inner-container[aria-label="page ${comment.position.pageIndex}"] .page-inner-container`
|
`.vpv-page-inner-container[aria-label="page ${comment.position.pageIndex}"] .page-inner-container`
|
||||||
)
|
)
|
||||||
: document.querySelector(".track");
|
: document.querySelector(".track");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
correspondingMarker = document.querySelector(
|
||||||
|
`.comment-marker[href="#comment-${comment.id}"]`
|
||||||
|
);
|
||||||
|
if (correspondingMarker) return;
|
||||||
container.appendChild(bubble);
|
container.appendChild(bubble);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
bubble.addEventListener("mouseenter", () => highlight(comment));
|
bubble.addEventListener("mouseenter", () => highlight(comment));
|
||||||
bubble.addEventListener("mouseleave", () => unhighlight(comment));
|
bubble.addEventListener("mouseleave", () => unhighlight(comment));
|
||||||
}, 100);
|
}, 100);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(
|
console.log(
|
||||||
`Impossible de monter la bulle du commentaire ${comment.id}. La page n°${comment.position.pageIndex} n'existe pas dans le DOM.`
|
`Impossible de monter la bulle du commentaire ${comment.id}. La page n°${comment.position.pageIndex} n'existe pas dans le DOM.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -153,5 +170,7 @@ export const useDialogStore = defineStore("dialog", () => {
|
||||||
isCommentPanelEnabled,
|
isCommentPanelEnabled,
|
||||||
updateFile,
|
updateFile,
|
||||||
openedComment,
|
openedComment,
|
||||||
|
resetCommentMarkers,
|
||||||
|
vpvRef,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue