platform/plugins/chunter-resources/src/components/CommentInput.svelte
Andrey Sobolev e789207138
Fix Chunter infinite spinner. (#2585)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
2023-02-03 18:23:19 +06:00

152 lines
4.1 KiB
Svelte

<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021, 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { Comment } from '@hcengineering/chunter'
import { Doc, generateId, Ref } from '@hcengineering/core'
import { getClient, draftStore, updateDraftStore } from '@hcengineering/presentation'
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
import { createBacklinks } from '../backlinks'
import chunter from '../plugin'
export let object: Doc
export let shouldSaveDraft: boolean = false
const client = getClient()
const _class = chunter.class.Comment
let _id: Ref<Comment> = generateId()
let inputContent: string = ''
let commentInputBox: AttachmentRefInput
let draftComment: Comment | undefined = undefined
let saveTimer: number | undefined
$: updateDraft(object)
$: updateCommentFromDraft(draftComment)
async function updateDraft (object: Doc) {
if (!shouldSaveDraft) {
return
}
draftComment = $draftStore[object._id]
if (!draftComment) {
_id = generateId()
}
}
async function updateCommentFromDraft (draftComment: Comment | undefined) {
if (!shouldSaveDraft) {
return
}
inputContent = draftComment ? draftComment.message : ''
_id = draftComment ? draftComment._id : _id
}
function commentIsEmpty (message: string, attachments: number): boolean {
return (message === '<p></p>' || message === '') && !(attachments > 0)
}
async function saveDraft (object: Doc) {
updateDraftStore(object._id, draftComment)
}
async function handleCommentUpdate (message: string, attachments: number) {
if (commentIsEmpty(message, attachments)) {
draftComment = undefined
saveDraft(object)
_id = generateId()
return
}
if (!draftComment) {
draftComment = createDraftFromObject()
}
draftComment.message = message
draftComment.attachments = attachments
await commentInputBox.createAttachments()
saveDraft(object)
}
async function onUpdate (event: CustomEvent) {
if (!shouldSaveDraft) {
return
}
const { message, attachments } = event.detail
if (saveTimer) {
clearTimeout(saveTimer)
}
saveTimer = setTimeout(() => {
handleCommentUpdate(message, attachments)
}, 200)
}
function createDraftFromObject () {
const newDraft: Comment = {
_id,
_class: chunter.class.Comment,
space: object.space,
modifiedOn: Date.now(),
modifiedBy: object.modifiedBy,
attachedTo: object._id,
attachedToClass: object._class,
collection: 'comments',
message: '',
attachments: 0
}
return newDraft
}
let loading = false
async function onMessage (event: CustomEvent) {
loading = true
try {
const { message, attachments } = event.detail
await client.addCollection<Doc, Comment>(
_class,
object.space,
object._id,
object._class,
'comments',
{ message, attachments },
_id
)
// Create an backlink to document
await createBacklinks(client, object._id, object._class, _id, message)
// Remove draft from Local Storage
_id = generateId()
draftComment = undefined
await saveDraft(object)
commentInputBox.removeDraft(false)
} finally {
loading = false
}
}
</script>
<AttachmentRefInput
bind:this={commentInputBox}
bind:content={inputContent}
{_class}
space={object.space}
bind:objectId={_id}
{shouldSaveDraft}
on:message={onMessage}
on:update={onUpdate}
bind:loading
/>