Merge branch 'message_renderer' into 'master'
Message renderer See merge request crimata-ai/crimata-electron!6
This commit is contained in:
commit
42dcfd8ff0
14 changed files with 1274 additions and 1091 deletions
|
|
@ -23,8 +23,8 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, ref, reactive } from "vue";
|
import { defineComponent, onMounted, ref, reactive } from "vue";
|
||||||
import useMessageItemComp from "@/composables/computed/useMessageItemComp";
|
import useMessageItemComp from "@/composables/messageItem/useMessageItemComp";
|
||||||
import useMessageItemAnims from "@/composables/anims/useMessageItemAnims";
|
import useMessageItemAnims from "@/composables/messageItem/useMessageItemAnims";
|
||||||
import useTextWrap from "@/composables/textWrap/useTextWrap";
|
import useTextWrap from "@/composables/textWrap/useTextWrap";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "MessageItem",
|
name: "MessageItem",
|
||||||
|
|
|
||||||
54
src/components/UI/UIDetails/messageRenderer.vue
Normal file
54
src/components/UI/UIDetails/messageRenderer.vue
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
<template>
|
||||||
|
<g id="messageRenderer">
|
||||||
|
<g
|
||||||
|
v-for="(item, index) in renderArr"
|
||||||
|
:key="index"
|
||||||
|
:id="index"
|
||||||
|
class="messageList"
|
||||||
|
transform="translate(0, 0)"
|
||||||
|
>
|
||||||
|
<transition
|
||||||
|
appear
|
||||||
|
v-on:before-appear="beforeEnter"
|
||||||
|
v-on:appear="enter"
|
||||||
|
v-on:after-enter="afterEnter"
|
||||||
|
>
|
||||||
|
<MessageItem :item="item" :key="index" />
|
||||||
|
</transition>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import useMessageRenderer from "@/composables/messageRenderer/useMessageRenderer";
|
||||||
|
import { defineComponent, reactive, ref, inject } from "vue";
|
||||||
|
import MessageItem from "./messageItem.vue";
|
||||||
|
import { Message } from "@/types/message/index";
|
||||||
|
import { Mitt } from "@/types/mitt/index";
|
||||||
|
export default defineComponent({
|
||||||
|
name: "MessageRenderer",
|
||||||
|
components: { MessageItem },
|
||||||
|
setup() {
|
||||||
|
const renderArr: Message[] = reactive([]);
|
||||||
|
|
||||||
|
// imports mitt Emitter safely
|
||||||
|
let emitter: Mitt;
|
||||||
|
const emitterInject: Mitt | undefined = inject("mitt");
|
||||||
|
if (emitterInject) {
|
||||||
|
emitter = emitterInject;
|
||||||
|
emitter.on("renderMessage", (payload: Message | undefined) => {
|
||||||
|
if (payload) renderArr.push(payload);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { beforeEnter, enter, afterEnter } = useMessageRenderer();
|
||||||
|
|
||||||
|
return {
|
||||||
|
renderArr,
|
||||||
|
beforeEnter,
|
||||||
|
enter,
|
||||||
|
afterEnter,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -4,66 +4,45 @@
|
||||||
version="1.1"
|
version="1.1"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
@click="renderMessage"
|
@click="emittMessage"
|
||||||
>
|
>
|
||||||
<AI />
|
<AI />
|
||||||
|
<MessageRenderer />
|
||||||
<g id="cardsDiv">
|
|
||||||
<g
|
|
||||||
v-for="(item, index) in renderArr"
|
|
||||||
:key="index"
|
|
||||||
:id="index"
|
|
||||||
class="test"
|
|
||||||
transform="translate(0, 0)"
|
|
||||||
>
|
|
||||||
<transition
|
|
||||||
appear
|
|
||||||
v-on:before-appear="beforeEnter"
|
|
||||||
v-on:appear="enter"
|
|
||||||
v-on:after-enter="afterEnter"
|
|
||||||
>
|
|
||||||
<MessageItem :item="item" :key="index" />
|
|
||||||
</transition>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<InputItem />
|
<InputItem />
|
||||||
<TitleBar />
|
<TitleBar />
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, reactive } from "vue";
|
|
||||||
import MessageItem from "./UIDetails/messageItem.vue";
|
|
||||||
import AI from "../AI/index.vue";
|
import AI from "../AI/index.vue";
|
||||||
|
import MessageRenderer from "./UIDetails/messageRenderer.vue";
|
||||||
import InputItem from "./UIDetails/inputItem.vue";
|
import InputItem from "./UIDetails/inputItem.vue";
|
||||||
import TitleBar from "./UIDetails/titleBar.vue";
|
import TitleBar from "./UIDetails/titleBar.vue";
|
||||||
import Messages from "./UIDetails/messages";
|
import Messages from "./UIDetails/messages";
|
||||||
import useUIindexAnims from "@/composables/anims/useUIindexAnims";
|
import { Mitt } from "@/types/mitt/index";
|
||||||
|
import { defineComponent, ref, inject } from "vue";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "UIindex",
|
name: "UI",
|
||||||
components: { AI, MessageItem, InputItem, TitleBar },
|
components: { AI, MessageRenderer, InputItem, TitleBar },
|
||||||
setup() {
|
setup() {
|
||||||
const renderArr: Message[] = reactive([]);
|
|
||||||
const messages = Messages;
|
const messages = Messages;
|
||||||
const count = ref(0);
|
const count = ref(0);
|
||||||
|
|
||||||
const { beforeEnter, enter, afterEnter } = useUIindexAnims();
|
// imports mitt Emitter safely
|
||||||
|
let emitter: Mitt;
|
||||||
|
const emitterInject: Mitt | undefined = inject("mitt");
|
||||||
|
if (emitterInject) emitter = emitterInject;
|
||||||
|
|
||||||
const renderMessage = () => {
|
function emittMessage() {
|
||||||
if (count.value < messages.length) {
|
if (count.value < messages.length) {
|
||||||
renderArr.push(messages[count.value]);
|
emitter.emit("renderMessage", messages[count.value]);
|
||||||
count.value++;
|
count.value++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
renderMessage,
|
emittMessage,
|
||||||
renderArr,
|
|
||||||
beforeEnter,
|
|
||||||
enter,
|
|
||||||
afterEnter,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
||||||
import { inject, onMounted } from "vue";
|
|
||||||
import AnimeFunc from "@/types/animejs/index";
|
|
||||||
import { MessageAnimeFunc } from '@/types/message/index';
|
|
||||||
export default function useUIindexAnims() {
|
|
||||||
|
|
||||||
// imports animejs safely
|
|
||||||
let anime: AnimeFunc;
|
|
||||||
const animeInject: AnimeFunc | undefined = inject("animejs");
|
|
||||||
if (animeInject) anime = animeInject;
|
|
||||||
|
|
||||||
const msgOffset = {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
};
|
|
||||||
let winW: number;
|
|
||||||
let modifier: string;
|
|
||||||
let msg: HTMLElement | null;
|
|
||||||
let prevCardH = 0;
|
|
||||||
let messenger: HTMLElement | null;
|
|
||||||
let renderList: NodeList;
|
|
||||||
let scrollAnim = false;
|
|
||||||
let scroll = 0;
|
|
||||||
const messagePadding = 10;
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
messenger = document.getElementById("messenger");
|
|
||||||
if (messenger) winW = messenger.clientWidth;
|
|
||||||
});
|
|
||||||
|
|
||||||
function beforeEnter(el: SVGGElement): void {
|
|
||||||
modifier = el.className.baseVal.substring(0, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
function scrollOffset(l: NodeList, height: number): void {
|
|
||||||
for (const card of l) {
|
|
||||||
const c = card.parentNode as HTMLElement;
|
|
||||||
anime({
|
|
||||||
targets: c,
|
|
||||||
transform: `translate(0 ${height})`,
|
|
||||||
easing: "easeInOutQuad",
|
|
||||||
duration: 500,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setRenderList(): void {
|
|
||||||
const messages = document.querySelectorAll(".test");
|
|
||||||
if (messages.length) renderList = messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollAnimate: MessageAnimeFunc = (el, transform) => {
|
|
||||||
setRenderList();
|
|
||||||
anime({
|
|
||||||
targets: el, transform: transform.initialTranslate,
|
|
||||||
easing: "easeInOutQuad",
|
|
||||||
duration: 500,
|
|
||||||
begin: function() {
|
|
||||||
scrollOffset(renderList, scroll);
|
|
||||||
},
|
|
||||||
complete: function() {
|
|
||||||
anime({
|
|
||||||
targets: el,
|
|
||||||
transform: transform.finalTranslate,
|
|
||||||
offset: 1000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const stackAnimate: MessageAnimeFunc = (el, transform) => {
|
|
||||||
anime({
|
|
||||||
targets: el,
|
|
||||||
transform: transform.initialTranslate,
|
|
||||||
easing: "easeInOutQuad",
|
|
||||||
duration: 1000,
|
|
||||||
complete: function() {
|
|
||||||
anime({
|
|
||||||
targets: el,
|
|
||||||
transform: transform.finalTranslate,
|
|
||||||
easing: "easeInOutQuad",
|
|
||||||
duration: 500,
|
|
||||||
offset: 1000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addMessage(el: SVGGElement): void {
|
|
||||||
const transform = {
|
|
||||||
initialTranslate: `translate(${msgOffset.x} ${msgOffset.y})`,
|
|
||||||
finalTranslate: `translate(${msgOffset.x} ${msgOffset.y + 5})`
|
|
||||||
}
|
|
||||||
scrollAnim ? scrollAnimate(el, transform) : stackAnimate(el, transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setXoffset(messageWidth: number): void {
|
|
||||||
const paddingLeft = 40;
|
|
||||||
switch (modifier) {
|
|
||||||
case "sf":
|
|
||||||
msgOffset.x = winW - messageWidth;
|
|
||||||
break;
|
|
||||||
case "ai":
|
|
||||||
msgOffset.x = (winW - messageWidth) / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
msgOffset.x = paddingLeft;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setYoffset(messageHeight: number): void {
|
|
||||||
if (prevCardH === 0) {
|
|
||||||
msgOffset.y = 40;
|
|
||||||
} else {
|
|
||||||
msgOffset.y += prevCardH + messagePadding;
|
|
||||||
}
|
|
||||||
prevCardH = messageHeight;
|
|
||||||
scrollAnim = msgOffset.y > 450 ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateMessageOffsets(msg: HTMLElement): void {
|
|
||||||
const msgRect = msg.getBoundingClientRect();
|
|
||||||
setXoffset(msgRect.width)
|
|
||||||
setYoffset(msgRect.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
function enter(el: SVGGElement): void {
|
|
||||||
msg = document.getElementById(el.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function afterEnter(el: SVGGElement) {
|
|
||||||
if (msg) calculateMessageOffsets(msg);
|
|
||||||
if (scrollAnim) {
|
|
||||||
scroll -= el.getBBox().height + messagePadding;
|
|
||||||
}
|
|
||||||
addMessage(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
beforeEnter,
|
|
||||||
enter,
|
|
||||||
msgOffset,
|
|
||||||
addMessage,
|
|
||||||
afterEnter
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -42,7 +42,6 @@ export default function useKeyDownHandler() {
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
iCol = 1;
|
iCol = 1;
|
||||||
}
|
}
|
||||||
console.log(e.shiftKey);
|
|
||||||
const ch = keyboardCharMap[e.keyCode][iCol];
|
const ch = keyboardCharMap[e.keyCode][iCol];
|
||||||
// Optionally do things with non-printables,
|
// Optionally do things with non-printables,
|
||||||
// like CR, ESC, Backspace, LF, Tab, Arrows, F1-F24, etc.
|
// like CR, ESC, Backspace, LF, Tab, Arrows, F1-F24, etc.
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ export default function useMessageItemComp(m: string) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const startingOffset = computed(() => {
|
const startingOffset = computed(() => {
|
||||||
const cardsDiv = document.getElementById('cardsDiv')
|
const messageRenderer = document.getElementById('messageRenderer')
|
||||||
if (cardsDiv) {
|
if (messageRenderer) {
|
||||||
const rect = cardsDiv.getBoundingClientRect();
|
const rect = messageRenderer.getBoundingClientRect();
|
||||||
const sfX = 120;
|
const sfX = 120;
|
||||||
const aiX = 200;
|
const aiX = 200;
|
||||||
const dX = 40;
|
const dX = 40;
|
||||||
50
src/composables/messageRenderer/useMessageRenderer.ts
Normal file
50
src/composables/messageRenderer/useMessageRenderer.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import useRendererAnims from "./useRendererAnims";
|
||||||
|
import useOffsetCalculator from './useOffsetCalculator';
|
||||||
|
export default function useMessageRenderer() {
|
||||||
|
|
||||||
|
const { calculateMessageOffsets } = useOffsetCalculator();
|
||||||
|
const { shiftAnimate, stackAnimate } = useRendererAnims();
|
||||||
|
|
||||||
|
let messageList: NodeList;
|
||||||
|
let modifier: string;
|
||||||
|
let message: HTMLElement | null;
|
||||||
|
let messageOffset = { x: 0, y: 0 };
|
||||||
|
let shift = false;
|
||||||
|
let shiftValue = 0;
|
||||||
|
|
||||||
|
function animateMessage(el: SVGGElement): void {
|
||||||
|
const transform = {
|
||||||
|
initialTranslate: `translate(${messageOffset.x} ${messageOffset.y})`,
|
||||||
|
finalTranslate: `translate(${messageOffset.x} ${messageOffset.y + 5})`
|
||||||
|
}
|
||||||
|
shift ? shiftAnimate(el, transform, shiftValue, messageList) : stackAnimate(el, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeEnter(el: SVGGElement): void {
|
||||||
|
modifier = el.className.baseVal.substring(0, 2);
|
||||||
|
const queryResult = document.querySelectorAll(".messageList");
|
||||||
|
if (queryResult.length) messageList = queryResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
function enter(el: SVGGElement): void {
|
||||||
|
message = document.getElementById(el.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterEnter(el: SVGGElement) {
|
||||||
|
const messagePadding = 10;
|
||||||
|
if (message) {
|
||||||
|
messageOffset = calculateMessageOffsets(message, modifier);
|
||||||
|
shift = messageOffset.y > 450 ? true : false;
|
||||||
|
}
|
||||||
|
if (shift) {
|
||||||
|
shiftValue -= el.getBBox().height + messagePadding;
|
||||||
|
}
|
||||||
|
animateMessage(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
beforeEnter,
|
||||||
|
enter,
|
||||||
|
afterEnter
|
||||||
|
};
|
||||||
|
}
|
||||||
52
src/composables/messageRenderer/useOffsetCalculator.ts
Normal file
52
src/composables/messageRenderer/useOffsetCalculator.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { ref, onMounted } from "vue";
|
||||||
|
export default function useOffsetCalculator() {
|
||||||
|
const xOffset = ref(0);
|
||||||
|
const yOffset = ref(0);
|
||||||
|
let messenger: HTMLElement | null;
|
||||||
|
let winW: number;
|
||||||
|
let previousMessageHeight = 0;
|
||||||
|
const messagePadding = 10;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
messenger = document.getElementById("messenger");
|
||||||
|
if (messenger) winW = messenger.clientWidth;
|
||||||
|
})
|
||||||
|
|
||||||
|
function setXoffset(messageWidth: number, modifier: string): void {
|
||||||
|
const paddingLeft = 40;
|
||||||
|
switch (modifier) {
|
||||||
|
case "sf":
|
||||||
|
xOffset.value = winW - messageWidth;
|
||||||
|
break;
|
||||||
|
case "ai":
|
||||||
|
xOffset.value = (winW - messageWidth) / 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xOffset.value = paddingLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setYoffset(messageHeight: number): void {
|
||||||
|
if (previousMessageHeight === 0) {
|
||||||
|
yOffset.value = 40;
|
||||||
|
} else {
|
||||||
|
yOffset.value += previousMessageHeight + messagePadding;
|
||||||
|
}
|
||||||
|
previousMessageHeight = messageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateMessageOffsets = (msg: HTMLElement, modifier: string) => {
|
||||||
|
const msgRect = msg.getBoundingClientRect();
|
||||||
|
setXoffset(msgRect.width, modifier)
|
||||||
|
setYoffset(msgRect.height)
|
||||||
|
const offsets = {
|
||||||
|
x: xOffset.value as number,
|
||||||
|
y: yOffset.value as number
|
||||||
|
};
|
||||||
|
return offsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
calculateMessageOffsets,
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/composables/messageRenderer/useRendererAnims.ts
Normal file
67
src/composables/messageRenderer/useRendererAnims.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { inject } from "vue";
|
||||||
|
import AnimeFunc from "@/types/animejs/index";
|
||||||
|
import { MessageAnimeFunc } from '@/types/message/index';
|
||||||
|
export default function useRendererAnims() {
|
||||||
|
// imports animejs safely
|
||||||
|
let anime: AnimeFunc;
|
||||||
|
const animeInject: AnimeFunc | undefined = inject("animejs");
|
||||||
|
if (animeInject) anime = animeInject;
|
||||||
|
|
||||||
|
function shiftList({ targetList, sv }: { targetList: NodeList | undefined; sv: number | undefined }) {
|
||||||
|
if (targetList) {
|
||||||
|
for (const element of targetList) {
|
||||||
|
const el = element.parentNode as HTMLElement;
|
||||||
|
anime({
|
||||||
|
targets: el,
|
||||||
|
transform: `translate(0 ${sv})`,
|
||||||
|
easing: "easeInOutQuad",
|
||||||
|
duration: 500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shiftAnimate: MessageAnimeFunc = (el, transform, shiftValue, targetList) => {
|
||||||
|
anime({
|
||||||
|
targets: el, transform: transform.initialTranslate,
|
||||||
|
easing: "easeInOutQuad",
|
||||||
|
duration: 500,
|
||||||
|
begin: function() {
|
||||||
|
shiftList({
|
||||||
|
targetList,
|
||||||
|
sv: shiftValue
|
||||||
|
});
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
anime({
|
||||||
|
targets: el,
|
||||||
|
transform: transform.finalTranslate,
|
||||||
|
offset: 1000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const stackAnimate: MessageAnimeFunc = (el, transform) => {
|
||||||
|
anime({
|
||||||
|
targets: el,
|
||||||
|
transform: transform.initialTranslate,
|
||||||
|
easing: "easeInOutQuad",
|
||||||
|
duration: 1000,
|
||||||
|
complete: function() {
|
||||||
|
anime({
|
||||||
|
targets: el,
|
||||||
|
transform: transform.finalTranslate,
|
||||||
|
easing: "easeInOutQuad",
|
||||||
|
duration: 500,
|
||||||
|
offset: 1000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
shiftAnimate,
|
||||||
|
stackAnimate
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,6 @@ interface MessageTransform {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MessageAnimeFunc {
|
export interface MessageAnimeFunc {
|
||||||
(message: SVGElement, transform: MessageTransform): void;
|
(message: SVGElement, transform: MessageTransform, scrollHeight?: number | undefined, targetList?: NodeList | undefined): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
3
src/types/mitt/index.ts
Normal file
3
src/types/mitt/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { Emitter } from "mitt";
|
||||||
|
|
||||||
|
export type Mitt = Emitter;
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<UIindex />
|
<UI />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, inject } from "vue";
|
import { defineComponent } from "vue";
|
||||||
import UIindex from "@/components/UI/index.vue";
|
import UI from "@/components/UI/index.vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "HomeIndex",
|
name: "HomeIndex",
|
||||||
components: { UIindex },
|
components: { UI },
|
||||||
setup() {
|
|
||||||
const emitter: any = inject("mitt");
|
|
||||||
emitter.on("newSelfMessage", (payload: any) => console.log("foo", payload));
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue