Compare commits

...

4 Commits

Author SHA1 Message Date
Rafi
deb627a9ab Convert the MsgEditor component to a composite one 2023-04-02 15:43:31 +08:00
Rafi
70efc09dae Optimize the layout of message content. 2023-04-02 15:10:22 +08:00
Rafi
8ff914582a Fix the bug of conversation title 2023-04-01 21:54:15 +08:00
Rafi
f20a3562f3 Replace blank items in the conversation list with the default title 2023-04-01 21:22:44 +08:00
5 changed files with 88 additions and 84 deletions

View File

@@ -64,18 +64,16 @@ onUpdated(() => {
rounded="lg" rounded="lg"
elevation="2" elevation="2"
> >
<v-card-text> <div
<div ref="contentElm"
ref="contentElm" v-html="contentHtml"
v-html="contentHtml" class="chat-msg-content pa-3"
class="chat-msg-content" ></div>
></div>
</v-card-text>
</v-card> </v-card>
</template> </template>
<style> <style>
.chat-msg-content ol { .chat-msg-content ol, .chat-msg-content ul {
padding-left: 2em; padding-left: 2em;
} }
.hljs-code-container { .hljs-code-container {

View File

@@ -1,3 +1,73 @@
<script setup>
import { isMobile } from 'is-mobile'
const { $i18n } = useNuxtApp()
const props = defineProps({
sendMessage: {
type: Function,
required: true
},
disabled: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: false
}
})
const message = ref('')
const rows = ref(1)
const autoGrow = ref(true)
const hint = computed(() => {
return isMobile() ? '' : $i18n.t('pressEnterToSendYourMessageOrShiftEnterToAddANewLine')
})
watchEffect(() => {
const lines = message.value.split(/\r\n|\r|\n/).length
if (lines > 8) {
rows.value = 8
autoGrow.value = false
} else {
rows.value = 1
autoGrow.value = true
}
})
const send = () => {
let msg = message.value
// remove the last "\n"
if (msg[msg.length - 1] === "\n") {
msg = msg.slice(0, -1)
}
if (msg.length > 0) {
props.sendMessage(msg)
}
message.value = ""
}
const usePrompt = (prompt) => {
message.value = prompt
}
const clickSendBtn = () => {
send()
}
const enterOnly = (event) => {
event.preventDefault();
if (!isMobile()) {
send()
}
}
defineExpose({
usePrompt
})
</script>
<template> <template>
<div <div
class="flex-grow-1 d-flex align-center justify-space-between" class="flex-grow-1 d-flex align-center justify-space-between"
@@ -24,68 +94,4 @@
@click="clickSendBtn" @click="clickSendBtn"
></v-btn> ></v-btn>
</div> </div>
</template> </template>
<script>
import { isMobile } from 'is-mobile'
export default {
name: "MsgEditor",
props: {
sendMessage: Function,
disabled: Boolean,
loading: Boolean,
},
data() {
return {
message: "",
rows: 1,
autoGrow: true,
};
},
computed: {
hint() {
return isMobile() ? "" : "Press Enter to send your message or Shift+Enter to add a new line";
},
},
watch: {
message(val) {
const lines = val.split(/\r\n|\r|\n/).length;
if (lines > 8) {
this.rows = 8;
this.autoGrow = false;
} else {
this.rows = 1;
this.autoGrow = true;
}
},
},
methods: {
send() {
let msg = this.message
// remove the last "\n"
if (msg[msg.length - 1] === "\n") {
msg = msg.slice(0, -1)
}
if (msg.length > 0) {
this.sendMessage(msg)
}
this.message = ""
},
usePrompt(prompt) {
this.message = prompt
},
clickSendBtn () {
this.send()
},
enterOnly (event) {
event.preventDefault();
if (!isMobile()) {
this.send()
}
}
},
}
</script>
<style scoped>
</style>

View File

@@ -54,7 +54,6 @@ const deleteConversation = async (index) => {
deletingConversationIndex.value = null deletingConversationIndex.value = null
if (!error.value) { if (!error.value) {
if (conversations.value[index].id === currentConversation.value.id) { if (conversations.value[index].id === currentConversation.value.id) {
console.log('delete current conversation')
createNewConversation() createNewConversation()
} }
conversations.value.splice(index, 1) conversations.value.splice(index, 1)
@@ -129,10 +128,15 @@ onMounted(async () => {
> >
<v-list> <v-list>
<v-list-item <v-list-item
prepend-icon="face"
:title="$auth.user.username" :title="$auth.user.username"
:subtitle="$auth.user.email" :subtitle="$auth.user.email"
> >
<template v-slot:prepend>
<v-icon
icon="face"
size="x-large"
></v-icon>
</template>
<template v-slot:append> <template v-slot:append>
<v-menu> <v-menu>
<template v-slot:activator="{ props }"> <template v-slot:activator="{ props }">
@@ -205,7 +209,7 @@ onMounted(async () => {
:to="conversation.id ? `/${conversation.id}` : undefined" :to="conversation.id ? `/${conversation.id}` : undefined"
v-bind="props" v-bind="props"
> >
<v-list-item-title>{{ conversation.topic }}</v-list-item-title> <v-list-item-title>{{ conversation.topic !== "" ? conversation.topic : $t('defaultConversationTitle') }}</v-list-item-title>
<template v-slot:append> <template v-slot:append>
<div <div
v-show="isHovering && conversation.id" v-show="isHovering && conversation.id"
@@ -326,14 +330,14 @@ onMounted(async () => {
> >
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon> <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>{{ currentConversation.topic ?? runtimeConfig.public.appName }}</v-toolbar-title> <v-toolbar-title>{{ currentConversation.id ? currentConversation.topic : runtimeConfig.public.appName }}</v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn <v-btn
:title="$t('newConversation')" :title="$t('newConversation')"
icon="add" icon="add"
@click="createNewConversation()" @click="createNewConversation"
class="d-md-none" class="d-md-none"
></v-btn> ></v-btn>
<v-btn <v-btn

View File

@@ -11,7 +11,7 @@ const conversation = ref(getDefaultConversationData())
const loadConversation = async () => { const loadConversation = async () => {
const { data, error } = await useAuthFetch('/api/chat/conversations/' + route.params.id) const { data, error } = await useAuthFetch('/api/chat/conversations/' + route.params.id)
if (!error.value) { if (!error.value) {
conversation.value = data.value conversation.value = Object.assign(conversation.value, data.value)
} }
} }
@@ -23,8 +23,6 @@ const loadMessage = async () => {
} }
onActivated(async () => { onActivated(async () => {
console.log('activated')
console.log(conversation.value)
if (route.params.id) { if (route.params.id) {
conversation.value.loadingMessages = true conversation.value.loadingMessages = true
await loadConversation() await loadConversation()
@@ -33,9 +31,9 @@ onActivated(async () => {
} else { } else {
conversation.value = getDefaultConversationData() conversation.value = getDefaultConversationData()
} }
console.log(conversation.value)
currentConversation.value = Object.assign({}, conversation.value) currentConversation.value = Object.assign({}, conversation.value)
}) })
</script> </script>
<template> <template>

View File

@@ -18,8 +18,6 @@ export const getConversations = async () => {
} }
export const createNewConversation = () => { export const createNewConversation = () => {
const conversation = useConversation()
conversation.value = getDefaultConversationData()
navigateTo('/') navigateTo('/')
} }