[mobile] Make view current comments, fixed change comment

This commit is contained in:
JuliaSvinareva 2021-03-10 21:08:59 +03:00
parent c9e5a41954
commit f5d48e6492
5 changed files with 233 additions and 85 deletions

View file

@ -58,6 +58,8 @@ class CommentsController extends Component {
api.asc_registerCallback('asc_onRemoveComment', this.removeComment.bind(this));
api.asc_registerCallback('asc_onRemoveComments', this.removeComments.bind(this));
api.asc_registerCallback('asc_onChangeCommentData', this.changeCommentData.bind(this));
api.asc_registerCallback('asc_onShowComment', this.changeShowComments.bind(this));
api.asc_registerCallback('asc_onHideComment', this.hideComments.bind(this));
});
Common.Notifications.on('comments:filterchange', this.onFilterChange.bind(this)); // for sse
@ -97,57 +99,58 @@ class CommentsController extends Component {
this.removeComment(data[i]);
}
}
changeShowComments (id) {
this.storeComments.changeShowComment(id);
}
hideComments () {
//Common.Notifications.trigger('closeviewcomment');
}
changeCommentData (id, data) {
let date = null;
let replies = null;
let repliesCount = 0;
const changeComment = {};
const date = (data.asc_getOnlyOfficeTime()) ? new Date(stringOOToLocalDate(data.asc_getOnlyOfficeTime())) :
((data.asc_getTime() === '') ? new Date() : new Date(stringUtcToLocalDate(data.asc_getTime())));
let user = this.usersStore.searchUserById(data.asc_getUserId());
changeComment.comment = data.asc_getText();
changeComment.userId = data.asc_getUserId();
changeComment.userName = data.asc_getUserName();
changeComment.userColor = (user) ? user.asc_getColor() : null;
changeComment.resolved = data.asc_getSolved();
changeComment.quote = data.asc_getQuoteText();
changeComment.time = date.getTime();
changeComment.date = dateToLocaleTimeString(date);
changeComment.editable = this.appOptions.canEditComments || (data.asc_getUserId() === this.curUserId);
changeComment.removable = this.appOptions.canDeleteComments || (data.asc_getUserId() === this.curUserId);
let dateReply = null;
const replies = [];
const comment = this.storeComments.findComment(id);
const repliesCount = data.asc_getRepliesCount();
for (let i = 0; i < repliesCount; ++i) {
if (comment) {
dateReply = (data.asc_getReply(i).asc_getOnlyOfficeTime()) ? new Date(stringOOToLocalDate(data.asc_getReply(i).asc_getOnlyOfficeTime())) :
((data.asc_getReply(i).asc_getTime() === '') ? new Date() : new Date(stringUtcToLocalDate(data.asc_getReply(i).asc_getTime())));
date = (data.asc_getOnlyOfficeTime()) ? new Date(stringOOToLocalDate(data.asc_getOnlyOfficeTime())) :
((data.asc_getTime() === '') ? new Date() : new Date(stringUtcToLocalDate(data.asc_getTime())));
let user = this.usersStore.searchUserById(data.asc_getUserId());
comment.comment = data.asc_getText();
comment.userId = data.asc_getUserId();
comment.userName = data.asc_getUserName();
comment.userColor = (user) ? user.asc_getColor() : null;
comment.resolved = data.asc_getSolved();
comment.quote = data.asc_getQuoteText();
comment.time = date.getTime();
comment.date = dateToLocaleTimeString(date);
comment.editable = this.appOptions.canEditComments || (data.asc_getUserId() === this.curUserId);
comment.removable = this.appOptions.canDeleteComments || (data.asc_getUserId() === this.curUserId);
replies = [];
repliesCount = data.asc_getRepliesCount();
for (let i = 0; i < repliesCount; ++i) {
dateReply = (data.asc_getReply(i).asc_getOnlyOfficeTime()) ? new Date(stringOOToLocalDate(data.asc_getReply(i).asc_getOnlyOfficeTime())) :
((data.asc_getReply(i).asc_getTime() === '') ? new Date() : new Date(stringUtcToLocalDate(data.asc_getReply(i).asc_getTime())));
user = this.usersStore.searchUserById(data.asc_getReply(i).asc_getUserId());
const userName = data.asc_getReply(i).asc_getUserName();
replies.push({
ind: i,
userId: data.asc_getReply(i).asc_getUserId(),
userName: userName,
userColor: (user) ? user.asc_getColor() : null,
date: dateToLocaleTimeString(dateReply),
reply: data.asc_getReply(i).asc_getText(),
time: dateReply.getTime(),
userInitials: this.usersStore.getInitials(userName),
editable: this.appOptions.canEditComments || (data.asc_getReply(i).asc_getUserId() === this.curUserId),
removable: this.appOptions.canDeleteComments || (data.asc_getReply(i).asc_getUserId() === this.curUserId)
});
}
comment.replies = replies;
user = this.usersStore.searchUserById(data.asc_getReply(i).asc_getUserId());
const userName = data.asc_getReply(i).asc_getUserName();
replies.push({
ind: i,
userId: data.asc_getReply(i).asc_getUserId(),
userName: userName,
userColor: (user) ? user.asc_getColor() : null,
date: dateToLocaleTimeString(dateReply),
reply: data.asc_getReply(i).asc_getText(),
time: dateReply.getTime(),
userInitials: this.usersStore.getInitials(userName),
editable: this.appOptions.canEditComments || (data.asc_getReply(i).asc_getUserId() === this.curUserId),
removable: this.appOptions.canDeleteComments || (data.asc_getReply(i).asc_getUserId() === this.curUserId)
});
}
changeComment.replies = replies;
this.props.storeComments.changeComment(id, changeComment);
}
onFilterChange (filter) {
this.storeComments.changeFilter(filter);
@ -308,7 +311,7 @@ class EditCommentController extends Component {
var reply = comment.replies;
if (reply && reply.length > 0) {
reply.forEach((reply) => {
var addReply = (!!Asc.asc_CCommentDataWord ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null));
var addReply = (typeof Asc.asc_CCommentDataWord !== 'undefined' ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null));
if (addReply) {
addReply.asc_putText(reply.reply);
addReply.asc_putTime(utcDateToString(new Date(reply.time)));
@ -325,11 +328,12 @@ class EditCommentController extends Component {
}
}
onEditComment (comment, text) {
comment.comment = text.trim();
const changeComment = {...comment};
changeComment.comment = text.trim();
const user = this.props.users.currentUser;
comment.userid = user.asc_getIdOriginal();
comment.username = user.asc_getUserName();
this.onChangeComment(comment);
changeComment.userid = user.asc_getIdOriginal();
changeComment.username = user.asc_getUserName();
this.onChangeComment(changeComment);
}
onAddReply (comment, replyVal) {
let reply = null;
@ -386,10 +390,13 @@ class EditCommentController extends Component {
onEditReply (comment, reply, textReply) {
const currentUser = this.props.users.currentUser;
const indReply = reply.ind;
comment.replies[indReply].reply = textReply;
comment.replies[indReply].userid = currentUser.asc_getIdOriginal();
comment.replies[indReply].username = currentUser.asc_getUserName();
this.onChangeComment(comment);
const changeComment = {...comment};
changeComment.replies = [...comment.replies];
changeComment.replies[indReply] = {...reply};
changeComment.replies[indReply].reply = textReply;
changeComment.replies[indReply].userid = currentUser.asc_getIdOriginal();
changeComment.replies[indReply].username = currentUser.asc_getUserName();
this.onChangeComment(changeComment);
}
render() {
const storeComments = this.props.storeComments;
@ -418,14 +425,18 @@ class ViewCommentsController extends Component {
Common.Notifications.on('viewcomment', () => {
this.setState({isOpenViewCurComments: true});
});
Common.Notifications.on('closeviewcomment', () => {
this.closeViewCurComments();
});
}
closeViewCurComments () {
f7.sheet.close('#view-comment-sheet');
this.setState({isOpenViewCurComments: false});
}
onResolveComment (comment) {
let reply = null,
addReply = null,
ascComment = (!!Asc.asc_CCommentDataWord ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null));
ascComment = (typeof Asc.asc_CCommentDataWord !== 'undefined' ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null));
if (ascComment && comment) {
ascComment.asc_putText(comment.comment);
@ -444,7 +455,7 @@ class ViewCommentsController extends Component {
reply = comment.replies;
if (reply && reply.length > 0) {
reply.forEach((reply) => {
addReply = (!!Asc.asc_CCommentDataWord ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null));
addReply = (typeof Asc.asc_CCommentDataWord !== 'undefined' ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null));
if (addReply) {
addReply.asc_putText(reply.reply);
addReply.asc_putTime(utcDateToString(new Date(reply.time)));
@ -546,7 +557,11 @@ class ViewCommentsController extends Component {
return(
<Fragment>
{this.props.allComments && <ViewComments onCommentMenuClick={this.onCommentMenuClick} onResolveComment={this.onResolveComment} />}
{this.state.isOpenViewCurComments && <ViewCurrentComments opened={this.state.isOpenViewCurComments} closeCurComments={this.closeViewCurComments} />}
{this.state.isOpenViewCurComments && <ViewCurrentComments opened={this.state.isOpenViewCurComments}
closeCurComments={this.closeViewCurComments}
onCommentMenuClick={this.onCommentMenuClick}
onResolveComment={this.onResolveComment}
/>}
</Fragment>
)
}

View file

@ -9,8 +9,12 @@ export class storeComments {
filter: observable,
groupCollectionFilter: observable,
showComments: observable,
changeShowComment: action,
addComment: action,
removeComment: action,
changeComment: action,
changeFilter: action,
sortComments: computed,
@ -29,6 +33,14 @@ export class storeComments {
filter = undefined;
groupCollectionFilter = []; // for sse
showComments = [];
changeShowComment (uid) {
this.showComments.length = 0;
uid.forEach((item) => {
this.showComments.push(this.findComment(item));
});
}
addComment (comment) {
comment.groupName ? this.addCommentToGroupCollection(comment) : this.addCommentToCollection(comment);
}
@ -81,6 +93,23 @@ export class storeComments {
}
}
changeComment (id, changeComment) {
const comment = this.findComment(id);
if (comment) {
comment.comment = changeComment.comment;
comment.userId = changeComment.userId;
comment.userName = changeComment.userName;
comment.userColor = changeComment.userColor;
comment.resolved = changeComment.resolved;
comment.quote = changeComment.quote;
comment.time = changeComment.time;
comment.date = changeComment.date;
comment.editable = changeComment.editable;
comment.removable = changeComment.removable;
comment.replies = changeComment.replies;
}
}
changeFilter (filter) {
let comments = [];
this.filter = filter;

View file

@ -4,6 +4,18 @@ import { f7, Popup, Sheet, Popover, Page, Toolbar, Navbar, NavLeft, NavRight, Na
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 => {
@ -533,16 +545,6 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes
const viewMode = !storeAppOptions.canComments;
const comments = storeComments.sortComments;
const sliceQuote = (text) => {
if (text) {
let sliced = text.slice(0, 100);
if (sliced.length < text.length) {
sliced += '...';
return sliced;
}
return text;
}
};
const [clickComment, setComment] = useState();
const [commentActionsOpened, openActionComment] = useState(false);
@ -633,18 +635,105 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes
const _ViewComments = inject('storeComments', 'storeAppOptions')(observer(ViewComments));
const CommentList = () => {
return (
<List>
</List>
)
};
const ViewCommentSheet = ({closeCurComments}) => {
const CommentList = inject("storeComments", "storeAppOptions")(observer(({storeComments, storeAppOptions, onCommentMenuClick, onResolveComment}) => {
const { t } = useTranslation();
const _t = t('Common.Collaboration', {returnObjects: true});
const isAndroid = Device.android;
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);
return (
<Fragment>
<Toolbar position='bottom'>
<Link className='btn-add-reply' href='#'>{_t.textAddReply}</Link>
<div className='comment-navigation row'>
<Link href='#'><Icon slot='media' icon='icon-prev'/></Link>
<Link href='#'><Icon slot='media' icon='icon-next'/></Link>
</div>
</Toolbar>
<Page className='page-current-comment'>
<List className='comment-list'>
<ListItem>
<div slot='header' className='comment-header'>
<div className='left'>
{isAndroid && <div className='initials' style={{backgroundColor: `${comment.userColor ? comment.userColor : '#cfcfcf'}`}}>{comment.userInitials}</div>}
<div>
<div className='user-name'>{comment.userName}</div>
<div className='comment-date'>{comment.date}</div>
</div>
</div>
{!viewMode &&
<div className='right'>
<div className='comment-resolve' onClick={() => {onResolveComment(comment);}}><Icon icon={comment.resolved ? 'icon-resolve-comment check' : 'icon-resolve-comment'} /></div>
<div className='comment-menu'
onClick={() => {openActionComment(true);}}
><Icon icon='icon-menu-comment'/></div>
</div>
}
</div>
<div slot='footer'>
{comment.quote && <div className='comment-quote'>{sliceQuote(comment.quote)}</div>}
<div className='comment-text'><pre>{comment.comment}</pre></div>
{comment.replies.length > 0 &&
<ul className='reply-list'>
{comment.replies.map((reply, indexReply) => {
return (
<li key={`reply-${indexReply}`}
className='reply-item'
>
<div className='item-content'>
<div className='item-inner'>
<div className='item-title'>
<div slot='header' className='reply-header'>
<div className='left'>
{isAndroid && <div className='initials' style={{backgroundColor: `${reply.userColor ? reply.userColor : '#cfcfcf'}`}}>{reply.userInitials}</div>}
<div>
<div className='user-name'>{reply.userName}</div>
<div className='reply-date'>{reply.date}</div>
</div>
</div>
{!viewMode &&
<div className='right'>
<div className='reply-menu'
onClick={() => {setReply(reply); openActionReply(true);}}
>
<Icon icon='icon-menu-comment'/>
</div>
</div>
}
</div>
<div slot='footer'>
<div className='reply-text'><pre>{reply.reply}</pre></div>
</div>
</div>
</div>
</div>
</li>
)
})}
</ul>
}
</div>
</ListItem>
</List>
<CommentActions comment={comment} onCommentMenuClick={onCommentMenuClick} opened={commentActionsOpened} openActionComment={openActionComment}/>
<ReplyActions comment={comment} reply={reply} onCommentMenuClick={onCommentMenuClick} opened={replyActionsOpened} openActionReply={openActionReply}/>
</Page>
</Fragment>
)
}));
const ViewCommentSheet = ({closeCurComments, onCommentMenuClick, onResolveComment}) => {
useEffect(() => {
f7.sheet.open('#view-comment-sheet');
});
@ -681,7 +770,6 @@ const ViewCommentSheet = ({closeCurComments}) => {
const swipeEnd = parseInt(touchObj.clientY);
const dist = swipeEnd - stateStartY;
if (isNeedClose) {
f7.sheet.close('#view-comment-sheet');
closeCurComments();
} else if (stateHeight === '90%' && dist > 20) {
setHeight('45%');
@ -689,17 +777,10 @@ const ViewCommentSheet = ({closeCurComments}) => {
};
return (
<Sheet id='view-comment-sheet' style={{height: `${stateHeight}`, opacity: `${stateOpacity}`}}>
<Toolbar position='bottom'>
<Link className='btn-add-reply' href='#'>{_t.textAddReply}</Link>
<div className='comment-navigation row'>
<Link href='#'><Icon slot='media' icon='icon-prev'/></Link>
<Link href='#'><Icon slot='media' icon='icon-next'/></Link>
</div>
</Toolbar>
<div id='swipe-handler' className='swipe-container' onTouchStart={handleTouchStart} onTouchMove={handleTouchMove} onTouchEnd={handleTouchEnd}>
<Icon icon='icon-swipe'/>
</div>
<CommentList />
<CommentList onCommentMenuClick={onCommentMenuClick} onResolveComment={onResolveComment}/>
</Sheet>
)
};

View file

@ -154,4 +154,24 @@
}
}
}
}
.page-current-comment {
position: relative;
.page-content {
background-color: @white;
}
.comment-list {
ul {
&:before, &:after {
content: none;
}
.item-content .item-inner {
padding-top: 0;
.reply-list .item-content .item-inner {
padding-top: 13px;
}
}
}
}
}

View file

@ -7,4 +7,7 @@ i.icon {
height: 24px;
.encoded-svg-uncolored-mask('<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 2H0V20H9V24H24V7H19V2H14V3H18V7H9V19H1V3H5V2ZM10 8H23V23H10V8Z" /><path d="M5 0H14V5H5V0Z" /><path fill-rule="evenodd" clip-rule="evenodd" d="M21 12H12V11H21V12Z" /><path fill-rule="evenodd" clip-rule="evenodd" d="M21 16H12V15H21V16Z" /><path fill-rule="evenodd" clip-rule="evenodd" d="M21 20H12V19H21V20Z" /></svg>');
}
&.icon-prev:after, &.icon-next:after {
content: none;
}
}