182 lines
6.2 KiB
JavaScript
182 lines
6.2 KiB
JavaScript
import utils from '../services/utils';
|
|
import giteeHelper from '../services/providers/helpers/giteeHelper';
|
|
import syncSvc from '../services/syncSvc';
|
|
|
|
const idShifter = offset => (state, getters) => {
|
|
const ids = Object.keys(getters.currentFileDiscussions)
|
|
.filter(id => id !== state.newDiscussionId);
|
|
const idx = ids.indexOf(state.currentDiscussionId) + offset + ids.length;
|
|
return ids[idx % ids.length];
|
|
};
|
|
|
|
export default {
|
|
namespaced: true,
|
|
state: {
|
|
currentDiscussionId: null,
|
|
newDiscussion: null,
|
|
newDiscussionId: null,
|
|
isCommenting: false,
|
|
newCommentText: '',
|
|
newCommentSelection: { start: 0, end: 0 },
|
|
newCommentFocus: false,
|
|
stickyComment: null,
|
|
},
|
|
mutations: {
|
|
setCurrentDiscussionId: (state, value) => {
|
|
if (state.currentDiscussionId !== value) {
|
|
state.currentDiscussionId = value;
|
|
state.isCommenting = false;
|
|
}
|
|
},
|
|
setNewDiscussion: (state, value) => {
|
|
state.newDiscussion = value;
|
|
state.newDiscussionId = utils.uid();
|
|
state.currentDiscussionId = state.newDiscussionId;
|
|
state.isCommenting = true;
|
|
state.newCommentFocus = true;
|
|
},
|
|
patchNewDiscussion: (state, value) => {
|
|
Object.assign(state.newDiscussion, value);
|
|
},
|
|
setIsCommenting: (state, value) => {
|
|
state.isCommenting = value;
|
|
if (!value) {
|
|
state.newDiscussionId = null;
|
|
} else {
|
|
state.newCommentFocus = true;
|
|
}
|
|
},
|
|
setNewCommentText: (state, value) => {
|
|
state.newCommentText = value || '';
|
|
},
|
|
setNewCommentSelection: (state, value) => {
|
|
state.newCommentSelection = value;
|
|
},
|
|
setNewCommentFocus: (state, value) => {
|
|
state.newCommentFocus = value;
|
|
},
|
|
setStickyComment: (state, value) => {
|
|
state.stickyComment = value;
|
|
},
|
|
},
|
|
getters: {
|
|
newDiscussion: ({ currentDiscussionId, newDiscussionId, newDiscussion }) =>
|
|
currentDiscussionId === newDiscussionId && newDiscussion,
|
|
currentFileDiscussionLastComments: (state, getters, rootState, rootGetters) => {
|
|
const { discussions, comments } = rootGetters['content/current'];
|
|
const discussionLastComments = {};
|
|
Object.entries(comments).forEach(([, comment]) => {
|
|
if (discussions[comment.discussionId]) {
|
|
const lastComment = discussionLastComments[comment.discussionId];
|
|
if (!lastComment || lastComment.created < comment.created) {
|
|
discussionLastComments[comment.discussionId] = comment;
|
|
}
|
|
}
|
|
});
|
|
return discussionLastComments;
|
|
},
|
|
currentFileDiscussions: (
|
|
{ newDiscussionId },
|
|
{ newDiscussion, currentFileDiscussionLastComments },
|
|
rootState,
|
|
rootGetters,
|
|
) => {
|
|
const currentFileDiscussions = {};
|
|
if (newDiscussion) {
|
|
currentFileDiscussions[newDiscussionId] = newDiscussion;
|
|
}
|
|
const { discussions } = rootGetters['content/current'];
|
|
Object.entries(currentFileDiscussionLastComments)
|
|
.sort(([, lastComment1], [, lastComment2]) =>
|
|
lastComment1.created - lastComment2.created)
|
|
.forEach(([discussionId]) => {
|
|
currentFileDiscussions[discussionId] = discussions[discussionId];
|
|
});
|
|
return currentFileDiscussions;
|
|
},
|
|
currentDiscussion: ({ currentDiscussionId }, { currentFileDiscussions }) =>
|
|
currentFileDiscussions[currentDiscussionId],
|
|
previousDiscussionId: idShifter(-1),
|
|
nextDiscussionId: idShifter(1),
|
|
currentDiscussionComments: (
|
|
{ currentDiscussionId },
|
|
{ currentDiscussion },
|
|
rootState,
|
|
rootGetters,
|
|
) => {
|
|
const comments = {};
|
|
if (currentDiscussion) {
|
|
const contentComments = rootGetters['content/current'].comments;
|
|
Object.entries(contentComments)
|
|
.filter(([, comment]) =>
|
|
comment.discussionId === currentDiscussionId)
|
|
.sort(([, comment1], [, comment2]) =>
|
|
comment1.created - comment2.created)
|
|
.forEach(([commentId, comment]) => {
|
|
comments[commentId] = comment;
|
|
});
|
|
}
|
|
return comments;
|
|
},
|
|
currentDiscussionLastCommentId: (state, { currentDiscussionComments }) =>
|
|
Object.keys(currentDiscussionComments).pop(),
|
|
currentDiscussionLastComment: (
|
|
state,
|
|
{ currentDiscussionComments, currentDiscussionLastCommentId },
|
|
) => currentDiscussionComments[currentDiscussionLastCommentId],
|
|
},
|
|
actions: {
|
|
cancelNewComment({ commit, getters }) {
|
|
commit('setIsCommenting', false);
|
|
if (!getters.currentDiscussion) {
|
|
commit('setCurrentDiscussionId', getters.nextDiscussionId);
|
|
}
|
|
},
|
|
async createNewDiscussion({ commit, dispatch, rootGetters }, selection) {
|
|
const loginToken = rootGetters['workspace/loginToken'];
|
|
if (!loginToken) {
|
|
try {
|
|
await dispatch('modal/open', 'signInForComment', { root: true });
|
|
await giteeHelper.signin();
|
|
syncSvc.requestSync();
|
|
await dispatch('createNewDiscussion', selection);
|
|
} catch (e) { /* cancel */ }
|
|
} else if (selection) {
|
|
let text = rootGetters['content/current'].text.slice(selection.start, selection.end).trim();
|
|
const maxLength = 80;
|
|
if (text.length > maxLength) {
|
|
text = `${text.slice(0, maxLength - 1).trim()}…`;
|
|
}
|
|
commit('setNewDiscussion', { ...selection, text });
|
|
}
|
|
},
|
|
cleanCurrentFile({
|
|
getters,
|
|
rootGetters,
|
|
commit,
|
|
dispatch,
|
|
}, { filterComment, filterDiscussion } = {}) {
|
|
const { discussions } = rootGetters['content/current'];
|
|
const { comments } = rootGetters['content/current'];
|
|
const patch = {
|
|
discussions: {},
|
|
comments: {},
|
|
};
|
|
Object.entries(comments).forEach(([commentId, comment]) => {
|
|
const discussion = discussions[comment.discussionId];
|
|
if (discussion && comment !== filterComment && discussion !== filterDiscussion) {
|
|
patch.discussions[comment.discussionId] = discussion;
|
|
patch.comments[commentId] = comment;
|
|
}
|
|
});
|
|
|
|
const { nextDiscussionId } = getters;
|
|
dispatch('content/patchCurrent', patch, { root: true });
|
|
if (!getters.currentDiscussion) {
|
|
// Keep the gutter open
|
|
commit('setCurrentDiscussionId', nextDiscussionId);
|
|
}
|
|
},
|
|
},
|
|
};
|