feat(attachment): Support message attachments

This commit is contained in:
Rafi
2023-04-19 23:28:48 +08:00
parent 6c2faf1039
commit 01ea5f599f
4 changed files with 62 additions and 11 deletions

View File

@@ -8,6 +8,7 @@ const currentModel = useCurrentModel()
const openaiApiKey = useApiKey() const openaiApiKey = useApiKey()
const fetchingResponse = ref(false) const fetchingResponse = ref(false)
const messageQueue = [] const messageQueue = []
const attachment = ref(null)
let isProcessingQueue = false let isProcessingQueue = false
const props = defineProps({ const props = defineProps({
@@ -72,7 +73,7 @@ const fetchReply = async (message) => {
openaiApiKey: $settings.open_api_key_setting === 'True' ? openaiApiKey.value : null, openaiApiKey: $settings.open_api_key_setting === 'True' ? openaiApiKey.value : null,
message: message, message: message,
conversationId: props.conversation.id, conversationId: props.conversation.id,
frugalMode: frugalMode.value frugalMode: $settings.open_frugal_mode_control === 'True' && frugalMode.value
}, webSearchParams) }, webSearchParams)
try { try {
@@ -151,10 +152,20 @@ const send = (message) => {
if (props.conversation.messages.length === 0) { if (props.conversation.messages.length === 0) {
addConversation(props.conversation) addConversation(props.conversation)
} }
props.conversation.messages.push({message: message}) let newMessage = {
fetchReply(message) id: null,
is_bot: false,
message: message
}
if (attachment.value) {
newMessage.attachments = [attachment.value]
attachment.value = null
}
props.conversation.messages.push(newMessage)
fetchReply(newMessage)
scrollChatWindow() scrollChatWindow()
} }
const stop = () => { const stop = () => {
abortFetch() abortFetch()
} }
@@ -175,6 +186,10 @@ const deleteMessage = (index) => {
props.conversation.messages.splice(index, 1) props.conversation.messages.splice(index, 1)
} }
const updateAttachment = (file) => {
attachment.value = file
}
onNuxtReady(() => { onNuxtReady(() => {
currentModel.value = getCurrentModel() currentModel.value = getCurrentModel()
}) })
@@ -238,6 +253,20 @@ onNuxtReady(() => {
class="footer" class="footer"
> >
<div class="px-md-16 w-100 d-flex flex-column"> <div class="px-md-16 w-100 d-flex flex-column">
<div
v-if="attachment"
class="mb-2"
>
<v-chip
closable
color="teal"
label
@click:close="attachment = null"
>
<v-icon start icon="attach_file"></v-icon>
{{ attachment.original_name }}
</v-chip>
</div>
<div class="d-flex align-center"> <div class="d-flex align-center">
<v-btn <v-btn
v-show="fetchingResponse" v-show="fetchingResponse"
@@ -252,11 +281,10 @@ onNuxtReady(() => {
density="comfortable" density="comfortable"
color="transparent" color="transparent"
> >
<Prompt v-show="!fetchingResponse" :use-prompt="usePrompt" /> <Prompt :use-prompt="usePrompt" />
<EditorToolsUploadFile /> <EditorToolsUploadFile :update-attachment="updateAttachment" />
<EditorToolsWebSearch v-if="$settings.open_web_search === 'True'" /> <EditorToolsWebSearch v-if="$settings.open_web_search === 'True'" />
<EditorToolsFrugalMode v-if="$settings.open_frugal_mode_control === 'True'" /> <EditorToolsFrugalMode v-if="$settings.open_frugal_mode_control === 'True'" />
</v-toolbar> </v-toolbar>
</div> </div>
</v-footer> </v-footer>

View File

@@ -69,6 +69,19 @@ onMounted(() => {
v-html="contentHtml" v-html="contentHtml"
class="chat-msg-content pa-3" class="chat-msg-content pa-3"
></div> ></div>
<template
v-if="message.attachments && message.attachments.length > 0"
>
<v-divider class="mx-4"></v-divider>
<v-card-text class="d-flex justify-space-between">
<v-chip
label
>
<v-icon start icon="attach_file"></v-icon>
{{ message.attachments[0].original_name }}
</v-chip>
</v-card-text>
</template>
</v-card> </v-card>
</template> </template>

View File

@@ -1,19 +1,29 @@
<script setup> <script setup>
const { $i18n } = useNuxtApp() const { $i18n } = useNuxtApp()
const dialog = ref(true) const dialog = ref(false)
const uploading = ref(false) const uploading = ref(false)
const file = ref(null) const file = ref(null)
const errorMsg = ref('') const errorMsg = ref('')
const props = defineProps({
updateAttachment: {
type: Function,
required: true
}
})
const fileChanged = () => { const fileChanged = () => {
errorMsg.value = '' errorMsg.value = ''
} }
const upload = async () => { const upload = async () => {
if (file.value === null) { if (file.value.files.length < 1){
return; return;
} }
const fileObj = file.value.files[0]
uploading.value = true uploading.value = true
const formData = new FormData() const formData = new FormData()
formData.append('file', file.value.files[0]) formData.append('file', fileObj)
const { data, error } = await useAuthFetch('/api/chat/upload/', { const { data, error } = await useAuthFetch('/api/chat/upload/', {
method: 'POST', method: 'POST',
body: formData, body: formData,
@@ -22,7 +32,7 @@ const upload = async () => {
errorMsg.value = $i18n.t('Failed to upload file') errorMsg.value = $i18n.t('Failed to upload file')
} else { } else {
dialog.value = false dialog.value = false
console.log(data.value) props.updateAttachment(data.value.attachment)
} }
uploading.value = false uploading.value = false
} }

View File

@@ -13,4 +13,4 @@ export const useDrawer = () => useState('drawer', () => false)
export const useEnableWebSearch = () => useState('enableWebSearch', () => false) export const useEnableWebSearch = () => useState('enableWebSearch', () => false)
export const useFrugalMode = () => useState('frugalMode', () => false) export const useFrugalMode = () => useState('frugalMode', () => true)