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:
`
`,
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 (
)
};
const ReplyActions = ({comment, reply, onCommentMenuClick, opened, openActionReply}) => {
const { t } = useTranslation();
const _t = t('Common.Collaboration', {returnObjects: true});
return (
)
};
// 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:
`
`,
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:
`
`,
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:
`
`,
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);}}
>
}
)
})}
}
)
})}
}
)
}));
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);}}
>
}
)
})}
}
)
}));
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
};