Merge branch 'UIv2' into 'master'
UI v2 design update See merge request crimata-ai/crimata-electron!12
This commit is contained in:
commit
3ac351b4c5
9 changed files with 245 additions and 177 deletions
|
|
@ -19,7 +19,7 @@ import { SpeechRecorder } from "speech-recorder";
|
||||||
// });
|
// });
|
||||||
//
|
//
|
||||||
|
|
||||||
const recorder = new SpeechRecorder({ sampleRate: 16000, framesPerBuffer: 320 });
|
// const recorder = new SpeechRecorder({ sampleRate: 16000, framesPerBuffer: 320 });
|
||||||
|
|
||||||
// Keep a global reference of the window object, if you don't, the window will
|
// Keep a global reference of the window object, if you don't, the window will
|
||||||
// be closed automatically when the JavaScript object is garbage collected.
|
// be closed automatically when the JavaScript object is garbage collected.
|
||||||
|
|
@ -33,9 +33,9 @@ protocol.registerSchemesAsPrivileged([
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
win = new BrowserWindow({
|
win = new BrowserWindow({
|
||||||
width: 350,
|
width: 450,
|
||||||
height: 525,
|
height: 1025,
|
||||||
resizable: false,
|
resizable: true,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
// Use pluginOptions.nodeIntegration, leave this alone
|
// Use pluginOptions.nodeIntegration, leave this alone
|
||||||
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
|
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
|
||||||
|
|
@ -56,24 +56,26 @@ function createWindow() {
|
||||||
win.loadURL("app://./index.html");
|
win.loadURL("app://./index.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
win.webContents.on('did-finish-load', () => {
|
// win.webContents.on('did-finish-load', () => {
|
||||||
if (win) {
|
// if (win) {
|
||||||
recorder.start({
|
// recorder.start({
|
||||||
onAudio: (audio: object, speech: boolean) => {
|
// onAudio: (audio: object, speech: boolean) => {
|
||||||
if (win) {
|
// if (win) {
|
||||||
win.webContents.send('render-audio', {
|
// win.setTitle("Listening...");
|
||||||
audio: audio,
|
// // win.webContents.send('render-audio', {
|
||||||
speech: speech
|
// // audio: audio,
|
||||||
})
|
// // speech: speech
|
||||||
}
|
// // })
|
||||||
if (speech) {
|
// if (speech) {
|
||||||
// TODO: send audio to crimata BE
|
// win.setTitle("Recording...");
|
||||||
// ws.send(audio);
|
// // TODO: send audio to crimata BE
|
||||||
}
|
// // ws.send(audio);
|
||||||
}
|
// }
|
||||||
});
|
// }
|
||||||
}
|
// }
|
||||||
})
|
// });
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
win.on("closed", () => {
|
win.on("closed", () => {
|
||||||
win = null;
|
win = null;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ export default defineComponent({
|
||||||
let gradient;
|
let gradient;
|
||||||
const radius = ref(0);
|
const radius = ref(0);
|
||||||
const think = ref(false);
|
const think = ref(false);
|
||||||
const aiOffset = ref(1.0);
|
const aiOffset = ref(0.7);
|
||||||
|
|
||||||
const anime = inject("animejs");
|
const anime = inject("animejs");
|
||||||
let thinkAnimation;
|
let thinkAnimation;
|
||||||
|
|
@ -100,24 +100,24 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(think, async (think, prevThink) => {
|
// watch(think, async (think, prevThink) => {
|
||||||
if (think) {
|
// if (think) {
|
||||||
anime({
|
// anime({
|
||||||
targets: gradient,
|
// targets: gradient,
|
||||||
cy: "0.7",
|
// cy: "0.7",
|
||||||
});
|
// });
|
||||||
thinkAnimation.play();
|
// thinkAnimation.play();
|
||||||
} else {
|
// } else {
|
||||||
thinkAnimation.pause();
|
// thinkAnimation.pause();
|
||||||
// thinkAnimation.reset();
|
// // thinkAnimation.reset();
|
||||||
anime({
|
// anime({
|
||||||
targets: gradient,
|
// targets: gradient,
|
||||||
cy: "1",
|
// cy: "1",
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
// thinkAnimation.reset();
|
// // thinkAnimation.reset();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
return {
|
return {
|
||||||
radius,
|
radius,
|
||||||
aiOffset,
|
aiOffset,
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
<template>
|
<template>
|
||||||
<g :id="item.id" :class="item.modifier" :transform="startingOffset">
|
<g :id="item.id" :class="item.modifier" :transform="startingOffset">
|
||||||
<rect ref="messageRect" x="30" y="10" width="196" height="63" rx="20" :fill="bubbleFill" />
|
<rect ref="messageRect" x="30" y="10" width="196" height="63" rx="10" :fill="bubbleFill" />
|
||||||
<text font-size="14" font-family="SF Pro" ref="messageText" :fill="textFill">
|
<text font-size="14" font-family="SF Pro" ref="messageText" :fill="textFill">
|
||||||
<tspan dy="16" x="0" v-for="(item, index) in textArr" :key="index">{{ item }}</tspan>
|
<tspan dy="16" x="0" v-for="(item, index) in textArr" :key="index">{{ item }}</tspan>
|
||||||
</text>
|
</text>
|
||||||
<g :transform="signatureTranslate">
|
<g :transform="signatureTranslate">
|
||||||
<image xlink:href="profile.png" width="29" height="29" fill="#b5b5b5" clip-path="url(#clip)" />
|
|
||||||
<text
|
<text
|
||||||
transform="translate(36, 17)"
|
transform="translate(0, 5)"
|
||||||
fill="#888"
|
fill="#000"
|
||||||
font-size="10"
|
font-size="10"
|
||||||
font-family="SFCompactDisplay-Bold, SF Compact Display"
|
font-family="SFCompactDisplay-Bold, SF Compact Display"
|
||||||
font-weight="700"
|
font-weight="700"
|
||||||
>
|
>
|
||||||
<tspan v-if="item.outgoing">You to</tspan>
|
<tspan xml:space="preserve">{{ item.context }}</tspan>
|
||||||
<tspan v-else>From</tspan>
|
</text>
|
||||||
<tspan xml:space="preserve" fill="#000">{{ item.signature }}</tspan>
|
<text
|
||||||
|
transform="translate(0, 20)"
|
||||||
|
fill="#6f6f6f"
|
||||||
|
font-size="9"
|
||||||
|
font-family="SFCompactDisplay, SF Compact Display"
|
||||||
|
>
|
||||||
|
<tspan v-if="item.subContext">{{item.subContext}}</tspan>
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|
|
||||||
|
|
@ -4,156 +4,156 @@ const Messages: Message[] = [
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
"I can be there at 5 pm tomorrow to greet you at a Chick file with my almond and chive salad.",
|
"I can be there at 5 pm tomorrow to greet you at a Chick file with my almond and chive salad.",
|
||||||
signature: "Tommy McConville",
|
context: "You to Josie Wright",
|
||||||
outgoing: true,
|
subContext: "josie@gmail.com",
|
||||||
modifier: "sf",
|
modifier: "sf",
|
||||||
imgURL: "../assets/logo.png",
|
id: "1",
|
||||||
id: "1"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Sounds good, see you Thursday.",
|
content: "Sounds good, see you Thursday.",
|
||||||
signature: "Josie Wright",
|
context: "Message from Josie Wright",
|
||||||
outgoing: false,
|
subContext: "Subject: Chick File",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "@/assets/logo.png",
|
id: "2",
|
||||||
id: "2"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey Anna, did you get the paper done?",
|
content: "Hey Anna, did you get the paper done?",
|
||||||
signature: "Tommy McConville",
|
context: "Mesage from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "New Conversation",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "@/assets/logo.png",
|
id: "3",
|
||||||
id: "3"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Yes posting it online soon.",
|
content: "Yes posting it online soon.",
|
||||||
signature: "Tommy McConville",
|
context: "You to Tommy McConville",
|
||||||
outgoing: true,
|
subContext: "",
|
||||||
modifier: "sf",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "4",
|
||||||
id: "4"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Sweet, thanks!",
|
content: "Sweet, thanks!",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "5",
|
||||||
id: "5"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey do you know Enrique Hernandez?",
|
content: "Hey do you know Enrique Hernandez?",
|
||||||
signature: "Crimata AI",
|
context: "Message from Crimata AI",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "ai",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "6",
|
||||||
id: "6"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey do you know Enrique Hernandez?",
|
content: "Hey do you know Enrique Hernandez?",
|
||||||
signature: "Crimata AI",
|
context: "Message from Crimata",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "ai",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "7",
|
||||||
id: "7"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey do you know Enrique Hernandez?",
|
content: "Hey do you know Enrique Hernandez?",
|
||||||
signature: "Crimata AI",
|
context: "Message from Crimata",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "ai",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "8",
|
||||||
id: "8"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey Anna, did you get the paper done?",
|
content: "Hey Anna, did you get the paper done?",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "@/assets/logo.png",
|
id: "9",
|
||||||
id: "9"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey Anna, did you get the paper done?",
|
content: "Hey Anna, did you get the paper done?",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "@/assets/logo.png",
|
id: "10",
|
||||||
id: "10"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Yes posting it online soon.",
|
content: "Yes posting it online soon.",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: true,
|
subContext: "",
|
||||||
modifier: "sf",
|
modifier: "sf",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "11",
|
||||||
id: "11"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content:
|
content:
|
||||||
"I can be there at 5 pm tomorrow to greet you at a Chick file with my almond and chive salad.",
|
"I can be there at 5 pm tomorrow to greet you at a Chick file with my almond and chive salad.",
|
||||||
signature: "Tommy McConville",
|
context: "You to Tommy McConville",
|
||||||
outgoing: true,
|
subContext: "",
|
||||||
modifier: "sf",
|
modifier: "sf",
|
||||||
imgURL: "../assets/logo.png",
|
id: "12",
|
||||||
id: "12"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey Anna, did you get the paper done?",
|
content: "Hey Anna, did you get the paper done?",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "@/assets/logo.png",
|
id: "13",
|
||||||
id: "13"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey Anna, did you get the paper done?",
|
content: "Hey Anna, did you get the paper done?",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "@/assets/logo.png",
|
id: "14",
|
||||||
id: "14"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Yes posting it online soon.",
|
content: "Yes posting it online soon.",
|
||||||
signature: "Tommy McConville",
|
context: "You to Tommy McConville",
|
||||||
outgoing: true,
|
subContext: "",
|
||||||
modifier: "sf",
|
modifier: "sf",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "15",
|
||||||
id: "15"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Sweet, thanks!",
|
content: "Sweet, thanks!",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "16",
|
||||||
id: "16"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Hey do you know Enrique Hernandez?",
|
content: "Hey do you know Enrique Hernandez?",
|
||||||
signature: "Crimata AI",
|
context: "Message from Crimata AI",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "ai",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "17",
|
||||||
id: "17"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Yes posting it online soon.",
|
content: "Yes posting it online soon.",
|
||||||
signature: "Tommy McConville",
|
context: "You to Tommy McConville",
|
||||||
outgoing: true,
|
subContext: "",
|
||||||
modifier: "sf",
|
modifier: "sf",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "18",
|
||||||
id: "18"
|
time: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: "Sweet, thanks!",
|
content: "Sweet, thanks!",
|
||||||
signature: "Tommy McConville",
|
context: "Message from Tommy McConville",
|
||||||
outgoing: false,
|
subContext: "",
|
||||||
modifier: "fr",
|
modifier: "ai",
|
||||||
imgURL: "../../assets/logo.png",
|
id: "19",
|
||||||
id: "19"
|
time: ""
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
export default Messages;
|
export default Messages;
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
@click="emittMessage"
|
@click="emittMessage"
|
||||||
>
|
>
|
||||||
<AI />
|
<!-- <AI /> -->
|
||||||
<MessageRenderer />
|
<MessageRenderer />
|
||||||
<InputItem />
|
<InputItem />
|
||||||
<!-- <TitleBar /> -->
|
<!-- <TitleBar /> -->
|
||||||
|
|
@ -23,7 +23,7 @@ import { Mitt } from "@/types/mitt/index";
|
||||||
import { defineComponent, ref, inject } from "vue";
|
import { defineComponent, ref, inject } from "vue";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "UI",
|
name: "UI",
|
||||||
components: { AI, MessageRenderer, InputItem, TitleBar },
|
components: { MessageRenderer, InputItem },
|
||||||
setup() {
|
setup() {
|
||||||
const messages = Messages;
|
const messages = Messages;
|
||||||
const count = ref(0);
|
const count = ref(0);
|
||||||
|
|
|
||||||
53
src/composables/audioRenderer/useAudioRenderer.ts
Normal file
53
src/composables/audioRenderer/useAudioRenderer.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
export default function useAudioRenderer() {
|
||||||
|
const audioCtx = new (window.AudioContext)();
|
||||||
|
const analyzer = audioCtx.createAnalyser();
|
||||||
|
analyzer.fftSize = 2048;
|
||||||
|
const xInitial = 24;
|
||||||
|
const xFinal = 640;
|
||||||
|
// analyzer.minDecibels = -90;
|
||||||
|
analyzer.smoothingTimeConstant = 0.85;
|
||||||
|
const dataArray = new Uint8Array(analyzer.frequencyBinCount);
|
||||||
|
const sampleRate = 16000;
|
||||||
|
|
||||||
|
function convertBlock(buffer: ArrayBuffer): Float32Array {
|
||||||
|
// incoming data is an ArrayBuffer
|
||||||
|
const incomingData = new Uint8Array(buffer); // create a uint8 view on the ArrayBuffer
|
||||||
|
const l = incomingData.length; // length, we need this for the loop
|
||||||
|
const outputData = new Float32Array(incomingData.length); // create the Float32Array for output
|
||||||
|
for (let i = 0; i < l; i++) {
|
||||||
|
outputData[i] = (incomingData[i] - 128) / 128.0; // convert audio to float
|
||||||
|
}
|
||||||
|
return outputData; // return the Float32Array
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAudioFrequencyData = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderAudio = (payload) => {
|
||||||
|
|
||||||
|
// step 1: convert audio from Uint8 to Float32Array
|
||||||
|
const floatArray = convertBlock(payload.audio.buffer);
|
||||||
|
|
||||||
|
// step 2: source audio frequency {ffft} data
|
||||||
|
const buffer = audioCtx.createBuffer(1, floatArray.length, sampleRate);
|
||||||
|
buffer.copyToChannel(floatArray, 0, 0);
|
||||||
|
const source = audioCtx.createBufferSource();
|
||||||
|
source.buffer = buffer;
|
||||||
|
source.connect(analyzer);
|
||||||
|
source.start();
|
||||||
|
analyzer.getByteFrequencyData(dataArray);
|
||||||
|
|
||||||
|
// step 3: process audio frequency data
|
||||||
|
const dataView = dataArray.slice(xInitial, xFinal);
|
||||||
|
const sum = dataView.reduce((a, b) => a + b);
|
||||||
|
const average = sum / dataView.length;
|
||||||
|
const scaled = average / 255;
|
||||||
|
const zeroed = scaled - 0.6;
|
||||||
|
return zeroed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
renderAudio
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ export default function useMessageItemAnims({
|
||||||
|
|
||||||
function adjustMessageRect(): void {
|
function adjustMessageRect(): void {
|
||||||
// must get dimensions of text box to fit bubble around
|
// must get dimensions of text box to fit bubble around
|
||||||
const padding = 20;
|
const padding = 12.5;
|
||||||
const textBox = messageText.getBBox();
|
const textBox = messageText.getBBox();
|
||||||
messageRect.setAttribute("x", String(textBox.x - padding));
|
messageRect.setAttribute("x", String(textBox.x - padding));
|
||||||
messageRect.setAttribute("y", String(textBox.y - padding));
|
messageRect.setAttribute("y", String(textBox.y - padding));
|
||||||
|
|
@ -29,8 +29,7 @@ export default function useMessageItemAnims({
|
||||||
function translateMsgSignature(): void {
|
function translateMsgSignature(): void {
|
||||||
if (messageRect.getAttribute("height") !== null) {
|
if (messageRect.getAttribute("height") !== null) {
|
||||||
const height = Number(messageRect.getAttribute("height"));
|
const height = Number(messageRect.getAttribute("height"));
|
||||||
const p = -10;
|
signatureTranslate.value = `translate(-10 ${height})`;
|
||||||
signatureTranslate.value = `translate(-10 ${height + p})`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,10 @@
|
||||||
import { computed, onMounted, ref } from "vue";
|
import { computed, onMounted, ref } from "vue";
|
||||||
export default function useMessageItemComp(m: string, id: string) {
|
export default function useMessageItemComp(m: string, id: string) {
|
||||||
const x = ref(0)
|
const x = ref(0)
|
||||||
const xOffset = async () => {
|
const paddingLeft = 30;
|
||||||
const paddingLeft = 40;
|
const winW = 350;
|
||||||
const messageMargin = 20;
|
const messageWidth = ref(0);
|
||||||
const winW = 350;
|
const messageMarginTop = 75;
|
||||||
let x: number;
|
|
||||||
const msg = await document.getElementById(id);
|
|
||||||
if (msg) {
|
|
||||||
const messageWidth = msg.getBoundingClientRect().width;
|
|
||||||
switch (m) {
|
|
||||||
case "sf":
|
|
||||||
x = winW - messageWidth;
|
|
||||||
break;
|
|
||||||
case "ai":
|
|
||||||
x = messageMargin + (winW -messageWidth) / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
x = paddingLeft;
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
const result = await xOffset();
|
|
||||||
if(result) {
|
|
||||||
x.value = result;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const textFill = computed(() => {
|
const textFill = computed(() => {
|
||||||
switch (m) {
|
switch (m) {
|
||||||
|
|
@ -44,25 +19,59 @@ export default function useMessageItemComp(m: string, id: string) {
|
||||||
switch (m) {
|
switch (m) {
|
||||||
case "sf":
|
case "sf":
|
||||||
return "#61b4f4";
|
return "#61b4f4";
|
||||||
case "ai":
|
default:
|
||||||
return "#DDDDDD";
|
|
||||||
default:
|
|
||||||
return "#fff";
|
return "#fff";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setMessageWidthRef = async () => {
|
||||||
|
const msg = await document.getElementById(id);
|
||||||
|
if (msg) {
|
||||||
|
messageWidth.value = msg.getBoundingClientRect().width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateXoffset = async () => {
|
||||||
|
switch (m) {
|
||||||
|
case "sf":
|
||||||
|
x.value = winW - messageWidth.value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
x.value = paddingLeft;
|
||||||
|
// to center a message
|
||||||
|
// x = messageMargin + (winW -messageWidth) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO implement func in order to reduce dual renderer height call startingOffset computed prop
|
||||||
|
const getRendererHeight = () => {
|
||||||
|
const messageRenderer = document.getElementById('messageRenderer');
|
||||||
|
if (messageRenderer) {
|
||||||
|
const rect = messageRenderer.getBoundingClientRect();
|
||||||
|
return rect.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const startingOffset = computed(() => {
|
const startingOffset = computed(() => {
|
||||||
const messageRenderer = document.getElementById('messageRenderer')
|
const messageRenderer = document.getElementById('messageRenderer');
|
||||||
if (messageRenderer) {
|
if (messageRenderer) {
|
||||||
const rect = messageRenderer.getBoundingClientRect();
|
const rect = messageRenderer.getBoundingClientRect();
|
||||||
let Y = 600;
|
let Y = 600;
|
||||||
if (rect.height > 500) {
|
if (rect.height > 500) {
|
||||||
Y = rect.height + 75;
|
Y = rect.height + messageMarginTop;
|
||||||
}
|
}
|
||||||
return `translate(${x.value} ${Y})`;
|
return `translate(${x.value} ${Y})`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
// to calculate X offset:
|
||||||
|
// First: set message width ref
|
||||||
|
await setMessageWidthRef();
|
||||||
|
// Then: calculate message X offset
|
||||||
|
calculateXoffset();
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
textFill,
|
textFill,
|
||||||
bubbleFill,
|
bubbleFill,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
export interface Message {
|
export interface Message {
|
||||||
content: string;
|
content: string;
|
||||||
signature: string;
|
context: string;
|
||||||
outgoing: boolean;
|
subContext: string;
|
||||||
modifier: string;
|
modifier: string;
|
||||||
imgURL: string;
|
|
||||||
id: string;
|
id: string;
|
||||||
|
time: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MessageTransform {
|
interface MessageTransform {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue