import React, {useState, useEffect, Fragment} from 'react'; import {observer, inject} from "mobx-react"; import { f7, Popup, Sheet, Popover, Page, Toolbar, Navbar, NavLeft, NavRight, NavTitle, Link, Input, Icon, List, ListItem, Actions, ActionsGroup, ActionsButton } from 'framework7-react'; import { useTranslation } from 'react-i18next'; import {Device} from '../../../utils/device'; // Utils const sliceQuote = (text) => { if (text) { let sliced = text.slice(0, 100); if (sliced.length < text.length) { sliced += '...'; return sliced; } return text; } }; // Add comment const AddCommentPopup = inject("storeComments")(observer(props => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); useEffect(() => { f7.popup.open('.add-comment-popup'); if(!Device.android) f7.input.focus('.input-comment'); }); const userInfo = props.userInfo; const [stateText, setText] = useState(''); return ( { f7.popup.close('.add-comment-popup'); setTimeout(() => { props.closeAddComment(); }, 500) }}>{_t.textCancel} {_t.textAddComment} { f7.popup.close('.add-comment-popup'); setTimeout(() => { props.closeAddComment(); props.onAddNewComment(stateText, false) }, 500); }}> {Device.android ? : _t.textDone}
{Device.android &&
{userInfo.initials}
}
{userInfo.name}
{setText(event.target.value);}}>
) })); const AddCommentDialog = inject("storeComments")(observer(props => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); const userInfo = props.userInfo; const templateInitials = `
${userInfo.initials}
`; useEffect(() => { f7.dialog.create({ destroyOnClose: true, containerEl: document.getElementById('add-comment-dialog'), content: `
${Device.android ? templateInitials : ''}
${userInfo.name}
`, on: { opened: () => { const cancel = document.getElementById('comment-cancel'); if(!Device.android) $$('#comment-text').focus(); cancel.addEventListener('click', () => { f7.dialog.close(); props.closeAddComment(); }); const done = document.getElementById('comment-done'); done.addEventListener('click', () => { const value = document.getElementById('comment-text').value; if (value.length > 0) { f7.dialog.close(); props.closeAddComment(); props.onAddNewComment(value, false); } }); const area = document.getElementById('comment-text'); area.addEventListener('input', (event) => { if (event.target.value.length === 0 && !done.classList.contains('disabled')) { done.classList.add('disabled'); } else if (event.target.value.length > 0 && done.classList.contains('disabled')) { done.classList.remove('disabled'); } }); done.classList.add('disabled'); } } }).open(); }); return (
); })); const AddComment = props => { return ( Device.phone ? : ) }; // Actions const CommentActions = ({comment, onCommentMenuClick, opened, openActionComment}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); return ( openActionComment(false)}> {comment && {comment.editable && {onCommentMenuClick('editComment', comment);}}>{_t.textEdit}} {!comment.resolved && comment.editable ? {onCommentMenuClick('resolve', comment);}}>{_t.textResolve} : comment.editable && {onCommentMenuClick('resolve', comment);}}>{_t.textReopen} } {onCommentMenuClick('addReply', comment);}}>{_t.textAddReply} {comment.removable && {onCommentMenuClick('deleteComment', comment);}}>{_t.textDeleteComment}} } {_t.textCancel} ) }; const ReplyActions = ({comment, reply, onCommentMenuClick, opened, openActionReply}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); return ( openActionReply(false)}> {reply && {reply.editable && {onCommentMenuClick('editReply', comment, reply);}}>{_t.textEdit}} {reply.removable && {onCommentMenuClick('deleteReply', comment, reply);}}>{_t.textDeleteReply}} } {_t.textCancel} ) }; // Edit comment const EditCommentPopup = inject("storeComments")(observer(({storeComments, comment, onEditComment}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); useEffect(() => { f7.popup.open('.edit-comment-popup'); }); const [stateText, setText] = useState(comment.comment); return ( { f7.popup.close('.edit-comment-popup'); setTimeout(() => { storeComments.openEditComment(false); }, 500); }}>{_t.textCancel} {_t.textEditComment} { f7.popup.close('.edit-comment-popup'); setTimeout(() => { storeComments.openEditComment(false); onEditComment(comment, stateText); }, 500); }} > {Device.android ? : _t.textDone}
{Device.android &&
{comment.userInitials}
}
{comment.parsedName}
{comment.date}
{setText(event.target.value);}}>
) })); const EditCommentDialog = inject("storeComments")(observer(({storeComments, comment, onEditComment}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); const templateInitials = `
${comment.userInitials}
`; useEffect(() => { f7.dialog.create({ destroyOnClose: true, containerEl: document.getElementById('edit-comment-dialog'), content: `
${Device.android ? templateInitials : ''}
${comment.parsedName}
${comment.date}
`, on: { opened: () => { const cancel = document.getElementById('comment-cancel'); cancel.addEventListener('click', () => { f7.dialog.close(); storeComments.openEditComment(false); }); const done = document.getElementById('comment-done'); done.addEventListener('click', () => { const value = document.getElementById('comment-text').value; if (value.length > 0) { onEditComment(comment, value); f7.dialog.close(); storeComments.openEditComment(false); } }); const area = document.getElementById('comment-text'); area.addEventListener('input', (event) => { if (event.target.value.length === 0 && !done.classList.contains('disabled')) { done.classList.add('disabled'); } else if (event.target.value.length > 0 && done.classList.contains('disabled')) { done.classList.remove('disabled'); } }); }, open: () => { $$('.dialog-backdrop.backdrop-in')[0].classList.add('over-popover'); }, closed: () => { $$('.dialog-backdrop.backdrop-in')[0].classList.remove('over-popover'); } } }).open(); }); return (
); })); const EditComment = ({comment, onEditComment}) => { return ( Device.phone ? : ) }; const AddReplyPopup = inject("storeComments")(observer(({storeComments, userInfo, comment, onAddReply}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); useEffect(() => { f7.popup.open('.add-reply-popup'); }); const [stateText, setText] = useState(''); return ( { f7.popup.close('.add-reply-popup'); setTimeout(() => { storeComments.openAddReply(false); }, 500); }}>{_t.textCancel} {_t.textAddReply} { f7.popup.close('.add-reply-popup'); setTimeout(() => { storeComments.openAddReply(false); onAddReply(comment, stateText); }, 500); }}> {Device.android ? : _t.textDone}
{Device.android &&
{userInfo.initials}
}
{userInfo.name}
{setText(event.target.value);}}>
) })); const AddReplyDialog = inject("storeComments")(observer(({storeComments, userInfo, comment, onAddReply}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); const templateInitials = `
${userInfo.initials}
`; useEffect(() => { f7.dialog.create({ destroyOnClose: true, containerEl: document.getElementById('add-reply-dialog'), content: `
${Device.android ? templateInitials : ''}
${userInfo.name}
`, on: { opened: () => { const cancel = document.getElementById('reply-cancel'); cancel.addEventListener('click', () => { f7.dialog.close(); storeComments.openAddReply(false); }); const done = document.getElementById('reply-done'); done.addEventListener('click', () => { const value = document.getElementById('reply-text').value; if (value.length > 0) { onAddReply(comment, value); f7.dialog.close(); storeComments.openAddReply(false); } }); const area = document.getElementById('reply-text'); area.addEventListener('input', (event) => { if (event.target.value.length === 0 && !done.classList.contains('disabled')) { done.classList.add('disabled'); } else if (event.target.value.length > 0 && done.classList.contains('disabled')) { done.classList.remove('disabled'); } }); done.classList.add('disabled'); }, open: () => { $$('.dialog-backdrop.backdrop-in')[0].classList.add('over-popover'); }, closed: () => { $$('.dialog-backdrop.backdrop-in')[0].classList.remove('over-popover'); } } }).open(); }); return (
); })); const AddReply = ({userInfo, comment, onAddReply}) => { return ( Device.phone ? : ) }; const EditReplyPopup = inject("storeComments")(observer(({storeComments, comment, reply, onEditReply}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); useEffect(() => { f7.popup.open('.edit-reply-popup'); }); const [stateText, setText] = useState(reply.reply); return ( { f7.popup.close('.edit-reply-popup'); setTimeout(() => { storeComments.openEditReply(false); }, 500); }}>{_t.textCancel} {_t.textEditReply} { f7.popup.close('.edit-reply-popup'); setTimeout(() => { storeComments.openEditReply(false); onEditReply(comment, reply, stateText); }, 500); }} > {Device.android ? : _t.textDone}
{Device.android &&
{reply.userInitials}
}
{reply.parsedName}
{reply.date}
{setText(event.target.value);}}>
) })); const EditReplyDialog = inject("storeComments")(observer(({storeComments, comment, reply, onEditReply}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); const templateInitials = `
${reply.userInitials}
`; useEffect(() => { f7.dialog.create({ destroyOnClose: true, containerEl: document.getElementById('edit-reply-dialog'), content: `
${Device.android ? templateInitials : ''}
${reply.parsedName}
${reply.date}
`, on: { opened: () => { const cancel = document.getElementById('reply-cancel'); cancel.addEventListener('click', () => { f7.dialog.close(); storeComments.openEditReply(false); }); const done = document.getElementById('reply-done'); done.addEventListener('click', () => { const value = document.getElementById('reply-text').value; if (value.length > 0) { onEditReply(comment, reply, value); f7.dialog.close(); storeComments.openEditReply(false); } }); const area = document.getElementById('reply-text'); area.addEventListener('input', (event) => { if (event.target.value.length === 0 && !done.classList.contains('disabled')) { done.classList.add('disabled'); } else if (event.target.value.length > 0 && done.classList.contains('disabled')) { done.classList.remove('disabled'); } }); }, open: () => { $$('.dialog-backdrop.backdrop-in')[0].classList.add('over-popover'); }, closed: () => { $$('.dialog-backdrop.backdrop-in')[0].classList.remove('over-popover'); } } }).open(); }); return (
); })); const EditReply = ({comment, reply, onEditReply}) => { return ( Device.phone ? : ) }; const pickLink = (message) => { let arrayComment = [], offset, len; message.replace(Common.Utils.ipStrongRe, function(subStr) { let result = /[\.,\?\+;:=!\(\)]+$/.exec(subStr); if (result) subStr = subStr.substring(0, result.index); offset = arguments[arguments.length-2]; arrayComment.push({start: offset, end: subStr.length+offset, str: window.open(subStr)} href={subStr} target="_blank" data-can-copy="true">{subStr}}); return ''; }); if (message.length<1000 || message.search(/\S{255,}/)<0) message.replace(Common.Utils.hostnameStrongRe, function(subStr) { let result = /[\.,\?\+;:=!\(\)]+$/.exec(subStr); if (result) subStr = subStr.substring(0, result.index); let ref = (! /(((^https?)|(^ftp)):\/\/)/i.test(subStr) ) ? ('http://' + subStr) : subStr; offset = arguments[arguments.length-2]; len = subStr.length; let elem = arrayComment.find(function(item){ return ( (offset>=item.start) && (offsetitem.start)); }); if (!elem) arrayComment.push({start: offset, end: len+offset, str: window.open(ref)} href={ref} target="_blank" data-can-copy="true">{subStr}}); return ''; }); message.replace(Common.Utils.emailStrongRe, function(subStr) { let ref = (! /((^mailto:)\/\/)/i.test(subStr) ) ? ('mailto:' + subStr) : subStr; offset = arguments[arguments.length-2]; len = subStr.length; let elem = arrayComment.find(function(item){ return ( (offset>=item.start) && (offsetitem.start)); }); if (!elem) arrayComment.push({start: offset, end: len+offset, str: window.open(ref)} href={ref}>{subStr}}); return ''; }); arrayComment = arrayComment.sort(function(item1,item2){ return item1.start - item2.start; }); let str_res = (arrayComment.length>0) ? : ; for (var i=1; i{str_res}{Common.Utils.String.htmlEncode(message.substring(arrayComment[i-1].end, arrayComment[i].start))}{arrayComment[i].str}; } if (arrayComment.length>0) { str_res = ; } return str_res; } // View comments const ViewComments = inject("storeComments", "storeAppOptions", "storeReview")(observer(({storeComments, storeAppOptions, onCommentMenuClick, onResolveComment, showComment, storeReview, wsProps}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); const isAndroid = Device.android; const displayMode = storeReview.displayMode; const viewMode = !storeAppOptions.canComments; const comments = storeComments.groupCollectionFilter || storeComments.collectionComments; const sortComments = comments.length > 0 ? [...comments].sort((a, b) => a.time > b.time ? -1 : 1) : null; const [clickComment, setComment] = useState(); const [commentActionsOpened, openActionComment] = useState(false); const [reply, setReply] = useState(); const [replyActionsOpened, openActionReply] = useState(false); return ( {Device.phone && } {!sortComments ?
{_t.textNoComments}
: {sortComments.map((comment, indexComment) => { return ( !comment.hide && { !e.target.closest('.comment-menu') && !e.target.closest('.reply-menu') ? showComment(comment) : null}}>
{isAndroid &&
{comment.userInitials}
}
{comment.parsedName}
{comment.date}
{!viewMode &&
{(comment.editable && displayMode === 'markup' && !wsProps?.Objects) &&
{onResolveComment(comment);}}>
} {(displayMode === 'markup' && !wsProps?.Objects) &&
{setComment(comment); openActionComment(true);}}>
}
}
{comment.quote &&
{sliceQuote(comment.quote)}
}
{pickLink(comment.comment)}
{comment.replies.length > 0 &&
    {comment.replies.map((reply, indexReply) => { return (
  • {isAndroid &&
    {reply.userInitials}
    }
    {reply.parsedName}
    {reply.date}
    {!viewMode && reply.editable &&
    {setComment(comment); setReply(reply); openActionReply(true);}} >
    }
    {pickLink(reply.reply)}
  • ) })}
}
) })}
}
) })); const CommentList = inject("storeComments", "storeAppOptions", "storeReview")(observer(({storeComments, storeAppOptions, onCommentMenuClick, onResolveComment, storeReview, wsProps}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); const isAndroid = Device.android; const displayMode = storeReview.displayMode; const viewMode = !storeAppOptions.canComments; const comments = storeComments.showComments; const [currentIndex, setCurrentIndex] = useState(0); const comment = comments[currentIndex]; const [commentActionsOpened, openActionComment] = useState(false); const [reply, setReply] = useState(); const [replyActionsOpened, openActionReply] = useState(false); const onViewPrevComment = () => { if (currentIndex - 1 < 0) { setCurrentIndex(comments.length - 1); } else { setCurrentIndex(currentIndex - 1); } }; const onViewNextComment = () => { if (currentIndex + 1 >= comments.length) { setCurrentIndex(0); } else { setCurrentIndex(currentIndex + 1); } }; if(!comment) { if (comments.length > 0) { onViewNextComment(); } return null; } return ( {!viewMode && {onCommentMenuClick('addReply', comment);}}>{_t.textAddReply} }
{isAndroid &&
{comment.userInitials}
}
{comment.parsedName}
{comment.date}
{!viewMode &&
{(comment.editable && displayMode === 'markup' && !wsProps?.Objects) &&
{onResolveComment(comment);}}>
} {(displayMode === 'markup' && !wsProps?.Objects) &&
{openActionComment(true);}}>
}
}
{comment.quote &&
{sliceQuote(comment.quote)}
}
{pickLink(comment.comment)}
{comment.replies.length > 0 &&
    {comment.replies.map((reply, indexReply) => { return (
  • {isAndroid &&
    {reply.userInitials}
    }
    {reply.parsedName}
    {reply.date}
    {!viewMode && reply.editable &&
    {setReply(reply); openActionReply(true);}} >
    }
    {pickLink(reply.reply)}
  • ) })}
}
) })); const ViewCommentSheet = ({closeCurComments, onCommentMenuClick, onResolveComment, wsProps}) => { useEffect(() => { f7.sheet.open('#view-comment-sheet'); }); const [stateHeight, setHeight] = useState('45%'); const [stateOpacity, setOpacity] = useState(1); const [stateStartY, setStartY] = useState(); const [isNeedClose, setNeedClose] = useState(false); const handleTouchStart = (event) => { const touchObj = event.changedTouches[0]; setStartY(parseInt(touchObj.clientY)); }; const handleTouchMove = (event) => { const touchObj = event.changedTouches[0]; const dist = parseInt(touchObj.clientY) - stateStartY; if (dist < 0) { // to top setHeight('90%'); setOpacity(1); setNeedClose(false); } else if (dist < 80) { setHeight('45%'); setOpacity(1); setNeedClose(false); } else { setNeedClose(true); setOpacity(0.6); } }; const handleTouchEnd = (event) => { const touchObj = event.changedTouches[0]; const swipeEnd = parseInt(touchObj.clientY); const dist = swipeEnd - stateStartY; if (isNeedClose) { closeCurComments(); } else if (stateHeight === '90%' && dist > 20) { setHeight('45%'); } }; return (
) }; const ViewCommentPopover = ({onCommentMenuClick, onResolveComment, wsProps}) => { useEffect(() => { f7.popover.open('#view-comment-popover', '#btn-coauth'); }); return ( ) }; const ViewCurrentComments = props => { return ( Device.phone ? : ) }; export { AddComment, EditComment, AddReply, EditReply, ViewComments, ViewCurrentComments };