From c2810fd5eb23b8a0efd30a84882ed0641793b730 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 25 Nov 2022 21:21:02 +0800 Subject: [PATCH] feat: basic integration with TipTap (#87) --- components/content/ContentRich.setup.ts | 2 +- components/modal/ModalContainer.vue | 2 +- components/publish/PublishWidget.vue | 69 +++-- components/tiptap/TiptapMentionList.vue | 58 ++++ composables/tiptap.ts | 93 ++++++ composables/tiptap/suggestion.ts | 83 +++++ constants/index.ts | 2 + nuxt.config.ts | 1 + package.json | 10 + pnpm-lock.yaml | 395 ++++++++++++++++++++++++ styles/global.css | 28 +- styles/tiptap.css | 7 + styles/vars.css | 1 + tests/content.test.ts | 2 +- 14 files changed, 722 insertions(+), 31 deletions(-) create mode 100644 components/tiptap/TiptapMentionList.vue create mode 100644 composables/tiptap.ts create mode 100644 composables/tiptap/suggestion.ts create mode 100644 styles/tiptap.css diff --git a/components/content/ContentRich.setup.ts b/components/content/ContentRich.setup.ts index 77835b81..39ee0d39 100644 --- a/components/content/ContentRich.setup.ts +++ b/components/content/ContentRich.setup.ts @@ -14,6 +14,6 @@ const emojiObject = emojisArrayToObject(props.emojis || []) export default () => h( 'div', - { class: 'rich-content' }, + { class: 'content-rich' }, contentToVNode(props.content, emojiObject), ) diff --git a/components/modal/ModalContainer.vue b/components/modal/ModalContainer.vue index 46b3803c..a512513a 100644 --- a/components/modal/ModalContainer.vue +++ b/components/modal/ModalContainer.vue @@ -13,6 +13,6 @@ import { isPreviewHelpOpen, isPublishDialogOpen, isSigninDialogOpen, isUserSwitc - + diff --git a/components/publish/PublishWidget.vue b/components/publish/PublishWidget.vue index 86a04b42..800edf31 100644 --- a/components/publish/PublishWidget.vue +++ b/components/publish/PublishWidget.vue @@ -2,6 +2,7 @@ import type { CreateStatusParams, StatusVisibility } from 'masto' import { fileOpen } from 'browser-fs-access' import { useDropZone } from '@vueuse/core' +import { EditorContent } from '@tiptap/vue-3' const { draftKey, @@ -15,10 +16,19 @@ const { expanded?: boolean }>() -const expanded = $ref(_expanded) +let isExpanded = $ref(_expanded) let isSending = $ref(false) let { draft } = $(useDraft(draftKey, inReplyToId)) +const { editor } = useTiptap({ + content: toRef(draft.params, 'status'), + placeholder, + autofocus: isExpanded, + onSubimit: publish, + onFocus() { isExpanded = true }, + onPaste: handlePaste, +}) + const status = $computed(() => { return { ...draft.params, @@ -87,11 +97,16 @@ function chooseVisibility(visibility: StatusVisibility) { } async function publish() { + if (process.dev) { + alert(JSON.stringify(draft.params, null, 2)) + return + } try { isSending = true if (!draft.editingStatus) await masto.statuses.create(status) - else await masto.statuses.update(draft.editingStatus.id, status) + else + await masto.statuses.update(draft.editingStatus.id, status) draft = getDefaultDraft({ inReplyToId }) isPublishDialogOpen.value = false @@ -111,6 +126,7 @@ async function onDrop(files: File[] | null) { const { isOverDropZone } = useDropZone(dropZoneRef, onDrop) onUnmounted(() => { + // Remove draft if it's empty if (!draft.attachments.length && !draft.params.status) { nextTick(() => { delete currentUserDrafts.value[draftKey] @@ -138,7 +154,7 @@ onUnmounted(() => {
@@ -151,22 +167,17 @@ onUnmounted(() => { >
-