mail/front/src/components/structure/message/Composer.vue
2023-04-15 15:55:31 +02:00

172 lines
5.3 KiB
Vue

<script setup>
import imapAPI from "@/services/imapAPI";
import store from "@/store/store";
import { BubbleMenu, useEditor, EditorContent, FloatingMenu } from "@tiptap/vue-3";
import { inject } from "vue";
import Underline from "@tiptap/extension-underline";
import Bold from "@tiptap/extension-bold";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
import Highlight from "@tiptap/extension-highlight";
import Italic from "@tiptap/extension-italic";
import Link from "@tiptap/extension-link";
import Strike from "@tiptap/extension-strike";
import History from "@tiptap/extension-history";
import TextAlign from "@tiptap/extension-text-align";
import OrderedList from "@tiptap/extension-ordered-list";
import bulletList from "@tiptap/extension-bullet-list";
import HardBreak from "@tiptap/extension-hard-break";
import heading from "@tiptap/extension-heading";
import Image from "@tiptap/extension-image";
import TaskList from "@tiptap/extension-task-list";
// todo style link
// todo link and drop cursor
// todo mentions
const editor = useEditor({
extensions: [
// required
Document,
Text,
// auto or on shortcut onlye
Paragraph,
HardBreak,
History.configure({
depth: 10,
}),
// marks
Underline,
Link,
Bold,
Strike,
Italic,
// nodes
Highlight.configure({
multicolor: true,
}),
TextAlign.configure({
types: ["heading", "paragraph"],
}),
],
content: `
<p>
Try to select <em>this text</em> to see what we call the bubble menu.
</p>
<p>
Neat, isn't it? Add an empty paragraph to see the floating menu.
</p>
`,
});
const room = inject("room");
const send = () => {
const htmlContent = editor.value.getHTML();
const textContent = editor.value.getText();
const accountUser = store.getters.accountOfRoom(room.value.id);
imapAPI.reponseEmail({
user: accountUser,
roomId: room.value.id,
text: textContent,
html: htmlContent,
});
};
// todo subject input when dm of group...
// Font selection: choose the font family, size, color, and style
// Images: insert pictures and graphics into your email
// Attachments: attach files to your email
// Signatures: add a custom signature to the bottom of your email
// HTML code editing: for advanced users who want to edit the HTML code of their email.
</script>
<template>
<div class="main">
<div v-if="editor">
<bubble-menu class="bubble-menu" :tippy-options="{ duration: 100 }" :editor="editor">
<button
@click="editor.chain().focus().toggleBold().run()"
:class="{ 'is-active': editor.isActive('bold') }"
>
Bold
</button>
<button
@click="editor.chain().focus().toggleItalic().run()"
:class="{ 'is-active': editor.isActive('italic') }"
>
Italic
</button>
<button
@click="editor.chain().focus().toggleStrike().run()"
:class="{ 'is-active': editor.isActive('strike') }"
>
Strike
</button>
<button
@click="editor.chain().focus().toggleUnderline().run()"
:class="{ 'is-active': editor.isActive('underline') }"
>
toggleUnderline
</button>
<button
@click="editor.commands.toggleHighlight({ color: '#ffcc00' })"
:class="{ 'is-active': editor.isActive('highlight') }"
>
Highlight
</button>
</bubble-menu>
<floating-menu class="floating-menu" :tippy-options="{ duration: 100 }" :editor="editor">
<button
@click="editor.chain().focus().toggleHeading({ level: 1 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 1 }) }"
>
H1
</button>
<button
@click="editor.chain().focus().toggleHeading({ level: 2 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 2 }) }"
>
H2
</button>
<button
@click="editor.chain().focus().toggleBulletList().run()"
:class="{ 'is-active': editor.isActive('bulletList') }"
>
Bullet List
</button>
</floating-menu>
</div>
<editor-content class="editor" :editor="editor" aria-expanded="false" />
<button @click="send()">SEND</button>
</div>
</template>
<style>
.ProseMirror:focus {
outline: none;
}
</style>
<style lang="scss" scoped>
.main {
display: flex;
flex-direction: row;
padding: 10px;
}
.editor {
background-color: var(--secondary-background);
flex: 1;
margin-right: 10px;
border-radius: 10px;
padding: 0 10px;
}
.is-active {
background-color: blue;
}
</style>