Compare commits

..

No commits in common. "e44584df0a36a91fecdd59f78372811efc89d585" and "4799e477becb28e31ef8ed4cae30cab100b26997" have entirely different histories.

4 changed files with 145 additions and 95 deletions

View File

@ -27,7 +27,7 @@ export async function getAccounts() {
return await execQueryAsync(query, values); return await execQueryAsync(query, values);
} }
export async function getRooms(mailboxId: number) { export async function getRooms(mailboxId) {
const query = ` const query = `
SELECT SELECT
room.room_id AS id, room.room_id AS id,

View File

@ -3,7 +3,7 @@ import imapAPI from "@/services/imapAPI";
import store from "@/store/store"; import store from "@/store/store";
import StarterKit from "@tiptap/starter-kit"; import StarterKit from "@tiptap/starter-kit";
import { BubbleMenu, useEditor, EditorContent, FloatingMenu } from "@tiptap/vue-3"; import { BubbleMenu, useEditor, EditorContent, FloatingMenu } from "@tiptap/vue-3";
import { inject } from "vue"; import { inject, onBeforeUnmount } from "vue";
const editor = useEditor({ const editor = useEditor({
extensions: [StarterKit], extensions: [StarterKit],
@ -35,7 +35,6 @@ const send = () => {
</script> </script>
<template> <template>
<div class="main">
<div v-if="editor"> <div v-if="editor">
<bubble-menu class="bubble-menu" :tippy-options="{ duration: 100 }" :editor="editor"> <bubble-menu class="bubble-menu" :tippy-options="{ duration: 100 }" :editor="editor">
<button <button
@ -80,30 +79,76 @@ const send = () => {
</floating-menu> </floating-menu>
</div> </div>
<editor-content class="editor" :editor="editor" aria-expanded="false" /> <editor-content class="editor" :editor="editor" />
<button @click="send()">SEND</button> <div class="send" @click="send()">SEND</div>
</div>
</template> </template>
<style> <style lang="scss">
.ProseMirror:focus { .send:hover {
outline: none; background-color: var(--selected);
}
</style>
<style lang="scss" scoped>
.main {
display: flex;
flex-direction: row;
padding: 10px;
} }
/* Basic editor styles */
.editor { .editor {
background-color: var(--secondary-background); background-color: var(--secondary-background);
flex: 1; }
margin-right: 10px;
border-radius: 10px; .ProseMirror {
padding: 0 10px; > * + * {
line-height: 0.6rem; margin-top: 0.75em;
}
ul,
ol {
padding: 0 1rem;
}
blockquote {
padding-left: 1rem;
border-left: 2px solid rgba(#0d0d0d, 0.1);
}
}
.bubble-menu {
display: flex;
background-color: #0d0d0d;
padding: 0.2rem;
border-radius: 0.5rem;
button {
border: none;
background: none;
color: #fff;
font-size: 0.85rem;
font-weight: 500;
padding: 0 0.2rem;
opacity: 0.6;
&:hover,
&.is-active {
opacity: 1;
}
}
}
.floating-menu {
display: flex;
background-color: #0d0d0d10;
padding: 0.2rem;
border-radius: 0.5rem;
button {
border: none;
background: none;
font-size: 0.85rem;
font-weight: 500;
padding: 0 0.2rem;
opacity: 0.6;
&:hover,
&.is-active {
opacity: 1;
}
}
} }
</style> </style>

View File

@ -21,6 +21,8 @@ interface AccountFromBack {
email: string; email: string;
} }
const buffer: RoomFromBack[] = [];
function createRoom(options: RoomFromBack): Room { function createRoom(options: RoomFromBack): Room {
return { return {
id: options.id, id: options.id,
@ -115,7 +117,6 @@ const store = createStore<State>({
}, },
addRooms(state, payload) { addRooms(state, payload) {
// todo add if not exist // todo add if not exist
const buffer: RoomFromBack[] = [];
payload.rooms.forEach((room: RoomFromBack) => { payload.rooms.forEach((room: RoomFromBack) => {
if (room.roomType == RoomType.THREAD) { if (room.roomType == RoomType.THREAD) {
buffer.push(room); buffer.push(room);
@ -173,7 +174,7 @@ const store = createStore<State>({
}, },
getters: { getters: {
rooms: (state) => (): Room[] => { rooms: (state) => (): Room[] => {
if (state.activeAccount === 0) return state.rooms.filter((room) => room.roomType != RoomType.THREAD); if (state.activeAccount === 0) return state.rooms;
return state.rooms.filter( return state.rooms.filter(
(room) => room.mailboxId == state.activeAccount && room.roomType != RoomType.THREAD, (room) => room.mailboxId == state.activeAccount && room.roomType != RoomType.THREAD,
); );
@ -199,13 +200,6 @@ const store = createStore<State>({
store.dispatch("fetchMessages", { roomId: roomId, obj: msgOnRoomId(state, roomId) }); store.dispatch("fetchMessages", { roomId: roomId, obj: msgOnRoomId(state, roomId) });
return msgOnRoomId(state, roomId)?.messages ?? []; return msgOnRoomId(state, roomId)?.messages ?? [];
}, },
message:
(state) =>
(roomId: number, messageId: number): Message | undefined => {
const roomMessage = msgOnRoomId(state, roomId);
if (!roomMessage) return;
return roomMessage.messages.find((msg) => msg.id === messageId);
},
accountOfRoom: accountOfRoom:
(state) => (state) =>
(roomId: number): string | undefined => { (roomId: number): string | undefined => {

View File

@ -39,19 +39,19 @@ const shouldDisplayComposer = () => {
); );
}; };
function openMessageView(messageId) { function openMessageView(id) {
messageIdView.value = messageId; messageIdView.value = id;
if (messageId === -1) return; message.value = room.value?.messages.find((message) => message.id == id);
message.value = store.getters.message(room.value.id, messageId);
} }
provide("room", room); provide("room", room);
</script> </script>
<template> <template>
<div class="container"> <div id="main">
<Header :id="id" :room="room"></Header> <Header :id="id" :room="room"></Header>
<div class="messages"> <div id="RoomViewBody">
<div class="content">
<Message <Message
v-for="(message, index) in store.getters.messages(room?.id)" v-for="(message, index) in store.getters.messages(room?.id)"
:key="index" :key="index"
@ -61,26 +61,37 @@ provide("room", room);
/> />
</div> </div>
<Composer class="composer" v-if="shouldDisplayComposer()" /> <Composer class="composer" v-if="shouldDisplayComposer()" />
</div>
<MessageViewModal :message="message" :messageId="messageIdView" @close="() => openMessageView(-1)" /> <MessageViewModal :message="message" :messageId="messageIdView" @close="() => openMessageView(-1)" />
</div> </div>
</template> </template>
<style scoped> <style scoped>
.container { #main {
display: flex;
flex-direction: column;
background-color: var(--primary-background); background-color: var(--primary-background);
color: var(--primary-text); color: var(--primary-text);
height: 100vh;
width: 100%; width: 100%;
} }
.messages { #RoomViewBody {
flex-grow: 1; display: flex;
flex-direction: column;
height: 100%;
} }
.composer { .composer {
position: absolute;
bottom: 0;
width: 100%;
padding-top: 10px;
height: 35px;
}
.content {
display: flex; display: flex;
align-items: center; flex-direction: column-reverse;
overflow: auto;
margin-bottom: 60px;
} }
</style> </style>