Stackedit/src/components/gutters/NewComment.vue
Benoit Schweblin 1b2d48ff22 Removed monetizejs sponsorship support.
Reduced time counter increment interval.
Added badge service.
Refactored user service.
Replaced Google+ with People API.
2019-06-22 22:19:01 +01:00

169 lines
5.6 KiB
Vue

<template>
<div class="comment comment--new" @keydown.esc.stop="cancelNewComment">
<div class="comment__header flex flex--row flex--space-between flex--align-center">
<div class="comment__user flex flex--row flex--align-center">
<div class="comment__user-image">
<user-image :user-id="userId"></user-image>
</div>
<span class="user-name">{{loginToken.name}}</span>
</div>
</div>
<div class="comment__text">
<div class="comment__text-inner">
<pre class="markdown-highlighting"></pre>
</div>
</div>
<div class="comment__buttons flex flex--row flex--end">
<button class="comment__button button" @click="cancelNewComment">Cancel</button>
<button class="comment__button button" @click="addComment">Ok</button>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations, mapActions } from 'vuex';
import Prism from 'prismjs';
import UserImage from '../UserImage';
import cledit from '../../services/editor/cledit';
import editorSvc from '../../services/editorSvc';
import markdownConversionSvc from '../../services/markdownConversionSvc';
import utils from '../../services/utils';
import userSvc from '../../services/userSvc';
import store from '../../store';
import badgeSvc from '../../services/badgeSvc';
export default {
components: {
UserImage,
},
computed: {
...mapGetters('workspace', [
'loginToken',
]),
userId() {
return userSvc.getCurrentUserId();
},
},
methods: {
...mapMutations('discussion', [
'setNewCommentFocus',
]),
...mapActions('discussion', [
'cancelNewComment',
]),
addComment() {
const text = store.state.discussion.newCommentText.trim();
if (text.length) {
if (text.length > 2000) {
store.dispatch('notification/error', 'Comment is too long.');
} else {
// Create comment
const discussionId = store.state.discussion.currentDiscussionId;
const comment = {
discussionId,
sub: this.userId,
text,
created: Date.now(),
};
const patch = {
comments: {
...store.getters['content/current'].comments,
[utils.uid()]: comment,
},
};
if (discussionId === store.state.discussion.newDiscussionId) {
// Create discussion
patch.discussions = {
...store.getters['content/current'].discussions,
[discussionId]: store.getters['discussion/newDiscussion'],
};
badgeSvc.addBadge('createDiscussion');
} else {
badgeSvc.addBadge('addComment');
}
store.dispatch('content/patchCurrent', patch);
store.commit('discussion/setNewCommentText');
store.commit('discussion/setIsCommenting');
}
}
},
},
mounted() {
const preElt = this.$el.querySelector('pre.markdown-highlighting');
const scrollerElt = this.$el.querySelector('.comment__text-inner');
const clEditor = cledit(preElt, scrollerElt, true);
clEditor.init({
sectionHighlighter: section => Prism.highlight(
section.text,
editorSvc.prismGrammars[section.data],
),
sectionParser: text => markdownConversionSvc
.parseSections(editorSvc.converter, text).sections,
content: store.state.discussion.newCommentText,
selectionStart: store.state.discussion.newCommentSelection.start,
selectionEnd: store.state.discussion.newCommentSelection.end,
getCursorFocusRatio: () => 0.2,
});
clEditor.on('focus', () => this.setNewCommentFocus(true));
// Save typed content and selection
clEditor.on('contentChanged', value =>
store.commit('discussion/setNewCommentText', value));
clEditor.selectionMgr.on('selectionChanged', (start, end) =>
store.commit('discussion/setNewCommentSelection', {
start, end,
}));
const isSticky = this.$el.parentNode.classList.contains('sticky-comment');
const isVisible = () => isSticky || store.state.discussion.stickyComment === null;
this.$watch(
() => store.state.discussion.currentDiscussionId,
() => this.$nextTick(() => {
if (isVisible() && store.state.discussion.newCommentFocus) {
clEditor.focus();
}
}),
{ immediate: true },
);
if (isSticky) {
let scrollerMirrorElt;
const getScrollerMirrorElt = () => {
if (!scrollerMirrorElt) {
scrollerMirrorElt = document.querySelector('.comment-list .comment--new .comment__text-inner');
}
return scrollerMirrorElt || { scrollTop: 0 };
};
scrollerElt.scrollTop = getScrollerMirrorElt().scrollTop;
scrollerElt.addEventListener('scroll', () => {
getScrollerMirrorElt().scrollTop = scrollerElt.scrollTop;
});
} else {
// Maintain the state with the sticky comment
this.$watch(
() => isVisible(),
(visible) => {
clEditor.toggleEditable(visible);
if (visible) {
const text = store.state.discussion.newCommentText;
clEditor.setContent(text);
const selection = store.state.discussion.newCommentSelection;
clEditor.selectionMgr.setSelectionStartEnd(selection.start, selection.end);
if (store.state.discussion.newCommentFocus) {
clEditor.focus();
}
}
},
{ immediate: true },
);
this.$watch(
() => store.state.discussion.newCommentText,
newCommentText => clEditor.setContent(newCommentText),
);
}
},
};
</script>