Markdown message (half) support
This commit is contained in:
1 parent
e07f8ee05f
commit
eb9a1ad9e8
9 files changed
+147
-92
No files matched your search
@@ -0,0 +1,113 @@
|
||||
<script setup>
|
||||
import { marked } from "marked";
|
||||
marked.use({
|
||||
renderer: {
|
||||
code (code, infostring, escaped) {
|
||||
let langElem = infostring ?
|
||||
`<div class="language">${infostring}</div>` : "";
|
||||
|
||||
return `<div class="code">
|
||||
${langElem}
|
||||
<div class="content">${code}</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
message: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
function chatEntryClass(msg) {
|
||||
if (msg.type == 'note') {
|
||||
return ['note'];
|
||||
} else if (msg.type == 'message') {
|
||||
return ['message', msg.sender == 'user' ? 'sent' : 'received'];
|
||||
} else if (msg.type == 'log') {
|
||||
return ['message', 'log'];
|
||||
} else {
|
||||
return ['info'];
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="chatEntryClass(message)" @contextmenu.prevent="$emit('open-menu', message)">
|
||||
<template v-if="message.type == 'message' || message.type == null">
|
||||
<div v-if="message.sender != 'user'" class="sender">{{message.sender}}</div>
|
||||
|
||||
<div v-if="message.format == 'markdown'" v-html="marked.parse(message.content)" class="content"></div>
|
||||
<div v-else class="content">{{message.content}}</div>
|
||||
</template>
|
||||
|
||||
<template v-if="message.type == 'note'">
|
||||
<div class="sender">{{message.sender}}</div>
|
||||
<div class="content">{{message.content}}</div>
|
||||
</template>
|
||||
|
||||
<template v-if="message.type == 'log'">
|
||||
<div class="sender">Log ({{message.sender}})</div>
|
||||
<div class="content">{{message.content}}</div>
|
||||
</template>
|
||||
|
||||
<template v-if="message.type == 'thread-header'">
|
||||
<div class="content">
|
||||
Thread {{message.threadId}} ({{message.messageCount}} messages)
|
||||
<a href="#" @click.prevent="$emit('toggleThread', message.threadId, !message.expanded)">{{message.expanded ? "Hide" : "Show"}}</a>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.info {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.message {
|
||||
width: fit-content;
|
||||
max-width: 50em;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--color-background-soft);
|
||||
}
|
||||
|
||||
.note {
|
||||
width: fit-content;
|
||||
padding: 10px;
|
||||
background-color: var(--color-background-soft);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.message.sent {
|
||||
align-self: end;
|
||||
margin-left: 2em;
|
||||
}
|
||||
.message.received {
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.message .content {
|
||||
white-space: preserve;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.message ul, .message ol {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.message .sender,
|
||||
.note .sender {
|
||||
font-weight: bold;
|
||||
font-size: 100%;
|
||||
margin-top: -5px; /* half message padding */
|
||||
}
|
||||
|
||||
.message.log .content {
|
||||
font-family: monospace;
|
||||
font-size: 80%;
|
||||
}
|
||||
</style>
|
||||
@@ -5,6 +5,7 @@
|
||||
} from "vue";
|
||||
|
||||
import TitleBar from '../components/TitleBar.vue';
|
||||
import Message from '../components/Message.vue';
|
||||
|
||||
import * as backend from '../backend';
|
||||
import * as ui from '../ui';
|
||||
@@ -401,18 +402,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
function chatEntryClass (msg) {
|
||||
if (msg.type == 'note') {
|
||||
return ['note'];
|
||||
} else if (msg.type == 'message') {
|
||||
return ['message', msg.sender == 'user' ? 'sent' : 'received'];
|
||||
} else if (msg.type == 'log') {
|
||||
return ['message', 'log'];
|
||||
} else {
|
||||
return ['info'];
|
||||
}
|
||||
}
|
||||
|
||||
function inputKeyDown (event) {
|
||||
if (event.key == "Enter" && event.ctrlKey) {
|
||||
event.preventDefault();
|
||||
@@ -433,31 +422,13 @@
|
||||
</TitleBar>
|
||||
|
||||
<div class="messages-container" ref="chatContainerElem">
|
||||
<div v-for="msg in chatEntries" :class="chatEntryClass(msg)" @contextmenu.prevent="chatEntryContextMenu(msg)">
|
||||
<template v-if="msg.type == 'message' || msg.type == null">
|
||||
<div v-if="msg.sender != 'user'" class="sender">{{msg.sender}}</div>
|
||||
<div class="content">{{msg.content}}</div>
|
||||
</template>
|
||||
|
||||
<template v-if="msg.type == 'note'">
|
||||
<div class="sender">{{msg.sender}}</div>
|
||||
<div class="content">{{msg.content}}</div>
|
||||
</template>
|
||||
|
||||
<template v-if="msg.type == 'log'">
|
||||
<div class="sender">Log ({{msg.sender}})</div>
|
||||
<div class="content">{{msg.content}}</div>
|
||||
</template>
|
||||
|
||||
<template v-if="msg.type == 'thread-header'">
|
||||
<div class="content">
|
||||
Thread {{msg.threadId}} ({{msg.messageCount}} messages)
|
||||
<a hred="#" @click.prevent="expandThread(msg.threadId, !msg.expanded)">{{msg.expanded ? "Hide" : "Show"}}</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!--message v-if="!msg.collapse" :value="msg.content" :format="msg.format"></message-->
|
||||
</div>
|
||||
<Message
|
||||
v-for="msg in chatEntries"
|
||||
:key="msg.id || msg.threadId"
|
||||
:message="msg"
|
||||
@open-menu="chatEntryContextMenu"
|
||||
@toggle-thread="expandThread"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="input-container">
|
||||
@@ -511,50 +482,6 @@
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.info {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.message {
|
||||
width: fit-content;
|
||||
max-width: 50em;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--color-background-soft);
|
||||
}
|
||||
|
||||
.note {
|
||||
width: fit-content;
|
||||
padding: 10px;
|
||||
background-color: var(--color-background-soft);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.message.sent {
|
||||
align-self: end;
|
||||
margin-left: 2em;
|
||||
}
|
||||
.message.received {
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.message .content {
|
||||
white-space: preserve;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.message .sender,
|
||||
.note .sender {
|
||||
font-weight: bold;
|
||||
font-size: 100%;
|
||||
margin-top: -5px; /* half message padding */
|
||||
}
|
||||
|
||||
.message.log .content {
|
||||
font-family: monospace;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.input-container {
|
||||
padding: 10px;
|
||||
background-color: var(--color-background-soft);
|
||||
|
||||
Reference in new issue
Block a user