| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- <script setup lang="ts">
- import AppLayout from "@/Layouts/AppLayout.vue"
- import {ArrowUpIcon, Loader2} from "lucide-vue-next"
- import {
- InputGroup,
- InputGroupAddon,
- InputGroupButton,
- InputGroupTextarea
- } from "@/Packages/Shadcn/Components/ui/input-group"
- import {computed, nextTick, watch} from "vue";
- import {useForm} from "@inertiajs/vue3";
- import { parse } from 'marked'
- const { chat } = defineProps(['chats', 'chat'])
- const form = useForm({
- uuid: chat?.id ?? null,
- message: null
- })
- const submit = function () {
- if (!form.message || form.processing) return
- form.post(route('chats.message'), {
- onSuccess: () => form.reset()
- })
- }
- const handleEnter = function (e) {
- if (e.metaKey || e.ctrlKey || e.shiftKey) {
- const {selectionStart, selectionEnd, value} = e.target
- form.message = value.slice(0, selectionStart) + '\n' + value.slice(selectionEnd)
- nextTick(() => {
- const pos = selectionStart + 1
- e.target.setSelectionRange(pos, pos)
- })
- } else submit()
- }
- const messages = computed(() => chat?.messages ?? [])
- watch(() => chat?.id, () => form.defaults('uuid', chat?.id ?? null))
- </script>
- <template>
- <AppLayout page-class="!py-0" :chats="chats">
- <div class="max-w-4xl mx-auto flex flex-col h-full">
- <div class="overflow-y-auto duration-500 space-y-4" :class="{'grow mt-2': messages.length !== 0}">
- <div v-for="message in messages">
- <div class="flex" v-if="message.from === 'user'">
- <div class="ml-auto border bg-card text-card-foreground p-2 rounded-lg max-w-[75%]"
- v-html="message.text.replaceAll('\n', '<br />')"></div>
- </div>
- <div class="prose dark:prose-invert" v-else v-html="parse(message.text)"></div>
- </div>
- <!-- <div class=""></div>-->
- </div>
- <div class="my-auto pb-2 pt-5" :class="{'sticky bottom-0': messages.length !== 0}">
- <InputGroup class="!bg-card">
- <InputGroupTextarea placeholder="Ask, Search or Chat..." v-model="form.message"
- @keydown.enter.prevent="handleEnter"/>
- <InputGroupAddon align="block-end">
- <InputGroupButton class="ml-auto cursor-pointer" variant="default"
- :disabled="!form.message || form.processing" :loading="true"
- @click="() => submit()">
- <template v-if="!form.processing">
- <ArrowUpIcon class="size-5"/>
- <span>Отправить</span>
- </template>
- <template v-else>
- <Loader2 class="w-4 h-4 animate-spin"/>
- Отправка
- </template>
- </InputGroupButton>
- </InputGroupAddon>
- </InputGroup>
- </div>
- </div>
- </AppLayout>
- </template>
- <style scoped>
- </style>
|