111 lines
2.6 KiB
Vue
111 lines
2.6 KiB
Vue
<template>
|
|
<svg
|
|
version="1.1"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
:viewBox="scrollView"
|
|
@click="emittMessage"
|
|
>
|
|
<g id="messageView" transform="translate(0, 20)">
|
|
<g v-for="(item, index) in renderArr" :key="index" preserverAspectRatio="none">
|
|
<transition
|
|
appear
|
|
v-on:before-appear="beforeEnter"
|
|
v-on:appear="enter"
|
|
v-on:after-enter="afterEnter"
|
|
>
|
|
<TextBubble :item="item" :key="index" />
|
|
</transition>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import TextBubble from "@/components/textBubble/index.vue";
|
|
import { Message } from "@/types/message/index";
|
|
import { useIpc } from "@/modules/ipc";
|
|
import { Queue } from "@/modules/queue";
|
|
import useTransitions from "./viewDetails/transitions";
|
|
import useScrollView from "@/modules/scrollView";
|
|
import useMitt from "@/modules/mitt";
|
|
import {
|
|
defineComponent,
|
|
reactive,
|
|
onMounted,
|
|
onUnmounted,
|
|
watch,
|
|
} from "vue";
|
|
|
|
export default defineComponent({
|
|
name: "MessageView",
|
|
components: { TextBubble },
|
|
|
|
setup() {
|
|
const { emitter } = useMitt();
|
|
const renderArr: Message[] = reactive([]);
|
|
const renderQ = new Queue();
|
|
|
|
const { invoke } = useIpc("message");
|
|
|
|
// Each method will be called on their respective lifecycle event.
|
|
const { beforeEnter, enter, afterEnter, rendering } = useTransitions();
|
|
const { scrollView } = useScrollView({
|
|
targetId: "messageView",
|
|
});
|
|
|
|
const render = (m: Message) => {
|
|
if (rendering.value) {
|
|
renderQ.enqueue(m);
|
|
} else {
|
|
renderArr.push(m);
|
|
}
|
|
};
|
|
|
|
watch(rendering, (rendering, _prevRendering) => {
|
|
if (!rendering) {
|
|
const m = renderQ.dequeue() as Message | null;
|
|
if (m) renderArr.push(m);
|
|
}
|
|
});
|
|
|
|
onMounted(() => {
|
|
// Call render function on event "render-message."
|
|
window.ipcRenderer.on("render-message", (event, payload) => {
|
|
const m = payload.message;
|
|
if (m.content) render(m);
|
|
});
|
|
|
|
emitter.on("user-message", async (message) => {
|
|
try {
|
|
const res = await invoke(message);
|
|
render(res);
|
|
} catch (e) {
|
|
console.log("No response. Do not render.");
|
|
}
|
|
});
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
window.ipcRenderer.removeAllListeners("render-message");
|
|
emitter.all.clear();
|
|
});
|
|
|
|
return {
|
|
renderArr,
|
|
beforeEnter,
|
|
enter,
|
|
afterEnter,
|
|
scrollView,
|
|
};
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
#messageView {
|
|
width: 1000px;
|
|
height: 100vh;
|
|
color: red;
|
|
}
|
|
</style>
|