pdf viewer : show draft bubble
This commit is contained in:
parent
94b9143cab
commit
b3c921cd31
3 changed files with 193 additions and 17 deletions
|
|
@ -16,8 +16,8 @@ Comments:
|
||||||
url: file://3vTh1tMFeFM2JxaN
|
url: file://3vTh1tMFeFM2JxaN
|
||||||
position:
|
position:
|
||||||
pageIndex: 1
|
pageIndex: 1
|
||||||
x: '26.50821702805'
|
x: "26.50821702805"
|
||||||
y: '62.355212355212'
|
y: "62.355212355212"
|
||||||
replies: [ ]
|
replies: [ ]
|
||||||
text: test
|
text: test
|
||||||
author:
|
author:
|
||||||
|
|
@ -29,6 +29,146 @@ Comments:
|
||||||
id: m3n5k0mb
|
id: m3n5k0mb
|
||||||
type: comment
|
type: comment
|
||||||
isRead: false
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/proposal
|
||||||
|
title: Offre commerciale
|
||||||
|
href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0'
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://3vTh1tMFeFM2JxaN
|
||||||
|
url: file://3vTh1tMFeFM2JxaN
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: "67.213040131138"
|
||||||
|
y: "36.872586872587"
|
||||||
|
replies: [ ]
|
||||||
|
text: test2
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-19T15:53:46+01:00
|
||||||
|
id: m3okrmlt
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/proposal
|
||||||
|
title: Offre commerciale
|
||||||
|
href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0'
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://3vTh1tMFeFM2JxaN
|
||||||
|
url: file://3vTh1tMFeFM2JxaN
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: "98.083140873747"
|
||||||
|
y: "79.343629343629"
|
||||||
|
replies: [ ]
|
||||||
|
text: test3
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-19T15:53:57+01:00
|
||||||
|
id: m3okrvaa
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/proposal
|
||||||
|
title: Offre commerciale
|
||||||
|
href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0'
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://3vTh1tMFeFM2JxaN
|
||||||
|
url: file://3vTh1tMFeFM2JxaN
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: "65.027546273254"
|
||||||
|
y: "55.791505791506"
|
||||||
|
replies: [ ]
|
||||||
|
text: test4
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-19T15:54:03+01:00
|
||||||
|
id: m3okrzsb
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/proposal
|
||||||
|
title: Offre commerciale
|
||||||
|
href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0'
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://3vTh1tMFeFM2JxaN
|
||||||
|
url: file://3vTh1tMFeFM2JxaN
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: "75.408642098202"
|
||||||
|
y: "20.849420849421"
|
||||||
|
replies: [ ]
|
||||||
|
text: test
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-19T16:27:21+01:00
|
||||||
|
id: m3olyt8i
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/proposal
|
||||||
|
title: Offre commerciale
|
||||||
|
href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0#comment-m3olyt8i'
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://3vTh1tMFeFM2JxaN
|
||||||
|
url: file://3vTh1tMFeFM2JxaN
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: '27.327777224757'
|
||||||
|
y: '78.185328185328'
|
||||||
|
replies: [ ]
|
||||||
|
text: test198
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-19T16:53:10+01:00
|
||||||
|
id: m3omw0ci
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@
|
||||||
placeholder="Ajouter un commentaire…"
|
placeholder="Ajouter un commentaire…"
|
||||||
rows="5"
|
rows="5"
|
||||||
class="text-sm | rounded-lg bg-black p-12"
|
class="text-sm | rounded-lg bg-black p-12"
|
||||||
v-model="newCommentText"
|
v-model="draftComment.text"
|
||||||
></textarea>
|
></textarea>
|
||||||
<footer class="flex">
|
<footer class="flex">
|
||||||
<input type="submit" class="btn btn--tranparent" />
|
<input type="submit" class="btn btn--tranparent" />
|
||||||
|
|
@ -118,27 +118,30 @@ import { useRoute } from "vue-router";
|
||||||
|
|
||||||
dayjs.locale("fr");
|
dayjs.locale("fr");
|
||||||
|
|
||||||
|
const emits = defineEmits(["show-draft-bubble", "hide-draft-bubble"]);
|
||||||
|
|
||||||
const { user } = useUserStore();
|
const { user } = useUserStore();
|
||||||
const { page } = usePageStore();
|
const { page } = usePageStore();
|
||||||
const dialog = useDialogStore();
|
const dialog = useDialogStore();
|
||||||
const { comments, openedFile } = storeToRefs(useDialogStore());
|
const { comments, openedFile } = storeToRefs(useDialogStore());
|
||||||
const api = useApiStore();
|
const api = useApiStore();
|
||||||
|
|
||||||
|
const draftComment = ref({});
|
||||||
const openedComment = ref(null);
|
const openedComment = ref(null);
|
||||||
|
|
||||||
const newCommentPageIndex = ref(null);
|
|
||||||
const newCommentPosition = ref(null);
|
|
||||||
const newCommentText = ref("");
|
|
||||||
const isAddOpen = ref(false);
|
const isAddOpen = ref(false);
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const waitingForCommentPosition = ref(false);
|
const waitingForCommentPosition = ref(false);
|
||||||
|
|
||||||
const sortedComments = computed(() => comments.value.reverse());
|
const sortedComments = computed(() => {
|
||||||
|
return [...comments.value].reverse();
|
||||||
|
});
|
||||||
const sortedReplies = ref(null);
|
const sortedReplies = ref(null);
|
||||||
|
|
||||||
watch(openedComment, (newVal) => {
|
watch(openedComment, (newVal) => {
|
||||||
sortedReplies.value = newVal ? newVal.replies.slice().reverse() : null;
|
sortedReplies.value = newVal ? newVal.replies.slice().reverse() : null;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(isAddOpen, (newVal) => {
|
watch(isAddOpen, (newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -147,6 +150,18 @@ watch(isAddOpen, (newVal) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
draftComment,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal.position) {
|
||||||
|
emits("show-draft-bubble", newVal);
|
||||||
|
} else {
|
||||||
|
emits("hide-draft-bubble");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
const viewContainer = document.querySelector(".vpv-pages-inner-container");
|
const viewContainer = document.querySelector(".vpv-pages-inner-container");
|
||||||
|
|
||||||
window.addEventListener("keydown", (event) => {
|
window.addEventListener("keydown", (event) => {
|
||||||
|
|
@ -168,13 +183,13 @@ function handleSubmit(event = null) {
|
||||||
path: route.fullPath,
|
path: route.fullPath,
|
||||||
fileName: openedFile ? openedFile.value.name : false,
|
fileName: openedFile ? openedFile.value.name : false,
|
||||||
userUuid: user.uuid,
|
userUuid: user.uuid,
|
||||||
text: newCommentText.value,
|
text: draftComment.value.text,
|
||||||
date,
|
date,
|
||||||
position:
|
position:
|
||||||
{
|
{
|
||||||
pageIndex: newCommentPageIndex.value,
|
pageIndex: draftComment.value.pageIndex,
|
||||||
x: newCommentPosition.value?.x,
|
x: draftComment.value.position?.x,
|
||||||
y: newCommentPosition.value?.y,
|
y: draftComment.value.position?.y,
|
||||||
} ?? false,
|
} ?? false,
|
||||||
id: uniqid(),
|
id: uniqid(),
|
||||||
};
|
};
|
||||||
|
|
@ -188,7 +203,9 @@ function handleSubmit(event = null) {
|
||||||
async function replyComment(newComment) {
|
async function replyComment(newComment) {
|
||||||
newComment.parentId = openedComment.value.id;
|
newComment.parentId = openedComment.value.id;
|
||||||
const newFile = await api.replyComment(newComment);
|
const newFile = await api.replyComment(newComment);
|
||||||
newCommentText.value = "";
|
draftComment.value.text = "";
|
||||||
|
draftComment.value.position = null;
|
||||||
|
draftComment.value.padeIndex = null;
|
||||||
isAddOpen.value = false;
|
isAddOpen.value = false;
|
||||||
dialog.updateFile(newFile);
|
dialog.updateFile(newFile);
|
||||||
openedComment.value = newFile.comments.find(
|
openedComment.value = newFile.comments.find(
|
||||||
|
|
@ -198,7 +215,9 @@ async function replyComment(newComment) {
|
||||||
|
|
||||||
async function addComment(newComment) {
|
async function addComment(newComment) {
|
||||||
const newFile = await api.addComment(newComment);
|
const newFile = await api.addComment(newComment);
|
||||||
newCommentText.value = "";
|
draftComment.value.text = "";
|
||||||
|
draftComment.value.position = null;
|
||||||
|
draftComment.value.padeIndex = null;
|
||||||
isAddOpen.value = false;
|
isAddOpen.value = false;
|
||||||
|
|
||||||
dialog.updateFile(newFile);
|
dialog.updateFile(newFile);
|
||||||
|
|
@ -229,7 +248,7 @@ function handleCommentPositionClick(event) {
|
||||||
.getAttribute("aria-label");
|
.getAttribute("aria-label");
|
||||||
const pageIndex = pageLabel.charAt(pageLabel.length - 1);
|
const pageIndex = pageLabel.charAt(pageLabel.length - 1);
|
||||||
|
|
||||||
newCommentPageIndex.value = parseInt(pageIndex);
|
draftComment.value.pageIndex = parseInt(pageIndex);
|
||||||
|
|
||||||
const viewRect = viewContainer.getBoundingClientRect();
|
const viewRect = viewContainer.getBoundingClientRect();
|
||||||
const pageRect = pageContainer.getBoundingClientRect();
|
const pageRect = pageContainer.getBoundingClientRect();
|
||||||
|
|
@ -242,7 +261,7 @@ function handleCommentPositionClick(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;
|
||||||
|
|
||||||
newCommentPosition.value = {
|
draftComment.value.position = {
|
||||||
x: relativeX,
|
x: relativeX,
|
||||||
y: relativeY,
|
y: relativeY,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
>
|
>
|
||||||
<span class="sr-only">Afficher les commentaires</span>
|
<span class="sr-only">Afficher les commentaires</span>
|
||||||
</button>
|
</button>
|
||||||
<Comments v-if="isCommentsOpen" />
|
<Comments v-if="isCommentsOpen" @show-draft-bubble="showDraftBubble" />
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -57,7 +57,7 @@ openedFile.value = route.query.fileIndex
|
||||||
const licenseKey = import.meta.env.VITE_VPV_LICENSE;
|
const licenseKey = import.meta.env.VITE_VPV_LICENSE;
|
||||||
useLicense({ licenseKey });
|
useLicense({ licenseKey });
|
||||||
|
|
||||||
// Variables
|
const draftComment = ref(null);
|
||||||
const isOpen = ref(true);
|
const isOpen = ref(true);
|
||||||
watch(isOpen, (newValue) => {
|
watch(isOpen, (newValue) => {
|
||||||
router.push({ name: route.name });
|
router.push({ name: route.name });
|
||||||
|
|
@ -76,6 +76,7 @@ watch(isCommentsOpen, (newVal) => {
|
||||||
watch(openedFile, (newVal) => {
|
watch(openedFile, (newVal) => {
|
||||||
removeCommentBubbles();
|
removeCommentBubbles();
|
||||||
if (newVal.comments) {
|
if (newVal.comments) {
|
||||||
|
console.log(newVal.comments);
|
||||||
setCommentBubbles();
|
setCommentBubbles();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -158,6 +159,22 @@ function removeCommentBubbles() {
|
||||||
bubble.parentNode.removeChild(bubble);
|
bubble.parentNode.removeChild(bubble);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showDraftBubble(draftComment) {
|
||||||
|
const bubble = document.createElement("a");
|
||||||
|
|
||||||
|
bubble.classList.add("comment-bubble");
|
||||||
|
bubble.classList.add("comment-bubble--draft");
|
||||||
|
bubble.style.left = draftComment.position.x + "%";
|
||||||
|
bubble.style.top = draftComment.position.y + "%";
|
||||||
|
bubble.href = "#comment-" + draftComment.id;
|
||||||
|
|
||||||
|
const container = document.querySelector(
|
||||||
|
`.vpv-page-inner-container[aria-label="page ${draftComment.pageIndex}"] .page-inner-container`
|
||||||
|
);
|
||||||
|
|
||||||
|
container.appendChild(bubble);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue