// steps:
// اضافه کردن ویژگی های زیر به تگ های والد.
// 1- :ref="'section-' + propertyName"
// 2- :id="'section-' + propertyName"
// 3- @mouseup="onMouseUp"
// اضافه کردن کامپوننت های JahatCommentsForm و JahatCommentsList به صفحه
import tahrirApis from "~/apis/tahrirApi";
// import tinyTahrir from "assets/tahrir/vendors/tinymce-files/tinytahrir";
import HttpService from "~/services/httpService";
import repoApi from "~/apis/repoApi";
export default {
created() {
window.addEventListener("scroll", this.handleScroll);
},
beforeMount() {
this.commentHttpService = new HttpService(
import.meta.env.VITE_TAHRIR_BASE_URL
);
this.httpService1 = new HttpService(import.meta.env.VITE_MESSAGE_BASE_URL);
this.id = this.$route.params.id;
},
destroyed() {
window.removeEventListener("scroll", this.handleScroll);
},
data() {
return {
id: "",
comments: [],
newComment: false,
selectedText: null,
globalGuid: undefined,
paragraphId: undefined,
paragraphParentId: undefined,
commentHttpService: undefined,
httpService1: undefined,
};
},
methods: {
/*
open comment form when user select a text
*/
onMouseUp($event) {
// console.log($event.target.id)
// Get selected text and encode it
const selection = encodeURIComponent(
this.getSelected().toString()
).replace(/[!'()*]/g);
if (selection) {
this.selectedText = selection;
this.setParagraphId($event);
this.createPopup($event, "linkPopup");
}
},
/*
extract user selected text
*/
getSelected() {
if (window.getSelection) {
return window.getSelection();
} else if (document.getSelection) {
return document.getSelection();
} else {
var selection = document.selection && document.selection.createRange();
if (selection.text) {
return selection.text;
}
return false;
}
},
setParagraphId(ev) {
this.paragraphId = ev.target.id;
this.paragraphParentId = ev.target.parentNode?.id;
},
/*
create comment popup and place it on top fo the selected text;
*/
createPopup(event) {
this.openCommentForm();
// Get cursor position
// const posX = event.clientX - 130;
// const posY = event.clientY - 200;
const posX = event.clientX;
const posY = event.clientY;
try {
this.$refs.popupMenu.$el.style.top = posY + "px";
this.$refs.popupMenu.$el.style.left = posX + "px";
this.$refs.popupMenu.$el.style.opacity = 1;
} catch (err) {
setTimeout(() => {
this.$refs.popupMenu.$el.style.top = posY + "px";
this.$refs.popupMenu.$el.style.left = posX + "px";
this.$refs.popupMenu.$el.style.opacity = 1;
}, 700);
}
},
openCommentForm() {
this.newComment = true;
},
/*
summary: save selected text
description: replace selected text with the new span.tcomment tag and then save it.
send a new request to api for saving the comment.
then update/replace paragraph content with newely created content.
then crawle all paragraphs for .tcomment ids.
then request api for paragraphs comments.
@fires when user clicked on comment popup save button.
@param {userComment} Html user comment.
@return void.
*/
saveSelectedTextComment(userComment) {
const url = tahrirApis.comments.addCommentToSelectedParag;
const replacedContent = this.replaceSelectedText();
const payload = {
content: replacedContent,
guid: this.paragraphId,
};
this.commentHttpService
.formDataRequest(url, payload)
.then((res) => {
this.newComment = false;
this.addComment(
{
text: userComment,
pid: this.globalGuid,
},
replacedContent
);
})
.catch((err) => {
this.mySwalToast({
html: err?.message,
});
})
.finally(() => (this.loading = false));
},
/*
summary: save comment
description:
send a new request to api for saving the comment.
then update/replace paragraph content with newely created content.
then crawle all paragraphs for .tcomment ids.
then request api for paragraphs comments.
@fires when saveSelectedTextComment method completed...
@param {text} String user comment.
@param {pid} String globalGuid.
@param {replacedContent} Html user comment.
@return void.
*/
addComment({ text, pid }, replacedContent) {
const payload = { text: JSON.stringify(text) };
const url = tahrirApis.comments.add + "/" + pid;
this.commentHttpService.formDataRequest(url, payload).then((res) => {
this.updateParagraphContentProperty(replacedContent);
this.crawlParagsForCommentId(this.localParagraphs).then((guidList) => {
this.getComments(guidList);
});
this.mySwalToast({
html: res.message,
});
});
},
/*
summary: update paragraph content property
description: update paragraph old content property with updated content.
@fires when addComment method completed...
@param {replacedContent} Html user comment.
@return void.
*/
updateParagraphContentProperty(replacedContent) {
this.localParagraphs.forEach((pars) => {
if (pars.id == this.paragraphParentId.slice(7))
pars.content = replacedContent;
});
},
/*
summary: update new comment form position
description: update position of new comment form when scrolling.
@fires when user scroll
@param {event} event window scroll event.
@return void.
*/
updateCommentFormTopPosition(event) {
// Find out how much (if any) user has scrolled
var scrollTop =
window.screenY !== undefined
? window.screenY
: (
document.documentElement ||
document.body.parentNode ||
document.body
).scrollTop;
const posY = event.clientY - 200 + scrollTop;
this.$refs.popupMenu._vnode.elm.style.top = posY + "px";
},
/*
summary: comment list
description: getting list of comments from the api.
@fires after page crawl for tcomment complete.
@param {array} guidList paragraph's comment ids.
@return void.
*/
getComments(guidList) {
let payload = {
limit: 50,
offset: 0,
refrence_id: this.$route.params.id,
entity_type_id: this.$route.meta.entityType,
entity_field_id: 1,
};
let url = repoApi.messages.update;
this.httpService1
.postRequest(url, payload)
.then((res) => {
this.mySwalToast({
html: res.message,
});
this.comments = res.data;
})
.catch((err) => {
this.mySwalToast({
html: err?.message,
});
})
.finally(() => {});
// let conversation = {
// limit: 50,
// offset: 0,
// refrence_id: this.id,
// };
// let url = repoApi.messages.list;
// this.httpService1.formDataRequest(url, conversation).then((res) => {
// this.comments=res.data
// if (res.data) {
// this.attachCommentsToParags(res.data);
// }
// });
// const payload = {
// pids: guidList,
// };
// this.commentHttpService.formDataRequest(tahrirApis.comments.documentComment, payload).then(
// (res) => {
// if (res.data)
// this.attachCommentsToParags(res.data);
// }
// );
},
/*
summary: attach comments to paragraphs object
description: loop over paragraphs and find paragraphs that
its content property math the comment id catched from the api.
@fires after getComment method called.
@param {object}
@return void.
*/
attachCommentsToParags(comments) {
try {
this.localParagraphs.forEach((parag) => {
const commentList = [];
Object.keys(comments).forEach((value) => {
if (parag.content.includes(value))
commentList.push(comments[value]);
});
this.$set(parag, "comments", commentList);
});
} catch (err) {
this.comments = comments;
}
this.fetchingData = false;
},
/*
summary: replace selected text with new span.
description: find the parent paragraph with its refs and
then replace the selected text with new span.
@fires when saveSelectedTextComment method called.
@return Html.
*/
replaceSelectedText() {
const text = decodeURIComponent(this.selectedText);
this.globalGuid = this.newGuid();
const replacementTag = ``;
const refContent = this.$refs[this.paragraphParentId][0];
refContent.innerHTML = refContent.innerHTML.replace(text, replacementTag);
return refContent.innerHTML;
},
closeCommentForm() {
this.newComment = false;
},
/*
summary: crawl paragraphs for .tcomment.
description: crawl paragraph fot .tcomment tags and getting its id.
@fires when addComment method called.
@return Html.
*/
async crawlParagsForCommentId(pars) {
return await pars
.map((par) => {
if (par?.content.includes("tcomment"))
return this.geCommenttIds(par.content);
})
.filter((item) => item)
.join(",");
},
/*
summary: create unique id.
@fires when crawlParagsForCommentId method called.
@return string.
*/
newGuid() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (c) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
}
);
},
/*
summary: separate spans id property..
@fires when crawlParagsForCommentId method called.
@return string.
*/
geCommenttIds(content) {
var ids = "";
var regex =
/\