socket = true;
// Begin audio stream.
- initRecorder();
+ // initRecorder();
}
}
const ip = 'ws://127.0.0.1';
-const port = 8081;
+const port = 8760;
const reconnectTimeout = 3000; //ms
let socket: WebSocket;
let success = false;
--- /dev/null
+<!-- components/messageView/messageView.vue -->
+
+<template>
+
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ width="500"
+ height="500"
+ viewBox="0 0 500 500"
+ >
+
+ <g id="messengerGroup">
+
+ <!-- Messages view bounding box -->
+ <rect id="messagesView" data-name="Rectangle 1496" width="500" height="500" rx="15" fill="#ff8e8e"/>
+
+ <!-- List of messages -->
+ <g id="messages" v-for="(item, index) in renderArr" :key="index">
+
+ <transition
+ appear
+ v-on:before-appear="get"
+ v-on:appear="enter"
+ v-on:after-enter="afterEnter"
+ >
+ <TextBubble :item="item" :key="index" />
+ </transition>
+
+ </g>
+
+ </g>
+
+ </svg>
+
+<!-- <svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ >
+ <g id="messagesView">
+ <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 { Queue } from "@/modules/queue";
+import useTransitions from "./viewDetails/transitions";
+import useScrollView from "@/modules/scrollView";
+import { defineComponent, reactive, onMounted, onUnmounted, watch } from "vue";
+
+export default defineComponent({
+ name: "MessageView",
+ components: { TextBubble },
+
+ setup() {
+ const renderArr: Message[] = reactive([]);
+ const renderQ = new Queue();
+
+ // 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(() => {
+ window.ipcRenderer.on("render-message", (event, payload) => {
+ const m = payload.message;
+ if (m.content) render(m);
+ });
+
+ });
+
+ onUnmounted(() => {
+ window.ipcRenderer.removeAllListeners("render-message");
+ });
+
+ return {
+ renderArr,
+ beforeEnter,
+ enter,
+ afterEnter,
+ };
+ },
+});
+</script>
+
+<style lang="scss" scoped>
+#messageView {
+ width: 1000px;
+ height: 100vh;
+ color: red;
+}
+</style>
--- /dev/null
+<template>
+
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ width="width"
+ height="height"
+ viewBox="0 0 100 46"
+ >
+
+ <rect
+ :id="item.id"
+ :class="item.modifier"
+ :transform="position"
+
+ width="width" height="height" rx="10" fill="#58c4fd"
+ />
+
+ </svg>
+
+</template>
+
+<script lang="ts">
+
+import { defineComponent, computed, onMounted, ref, reactive } from "vue";
+
+export default defineComponent({
+ name: "TextBubble",
+
+ props: {
+
+ // Passing in the message contents.
+ message: {
+ type: Object,
+ required: true,
+ },
+
+ },
+
+ setup(props) {
+
+ // The position of the bubble.
+ const position = ref()
+
+ // Calculate the position.
+ computed(() => {
+
+ const calculateX = () => {
+ let x = 20 // side-padding
+
+ if (props.message.modifier == 'sf') {
+ x = window.innerWidth - 100 - 20
+ }
+
+ return x
+ }
+
+ const calculateY = () => {
+ let y = 45 // top-padding
+
+ if (previousMessage) {
+ prev = document.getElementById(previousMessage)
+ prevPosition = prev.getBoundingClientRect().height
+
+ y = prevPosition + 15 // message-message padding
+ }
+
+ return y
+ }
+
+ let X = calculateX();
+ let Y = calculateY();
+
+ position.value = `translate(${X} ${Y})`;
+
+ })
+
+ return {
+ position
+ }
+ },
+
+});
+</script>
--- /dev/null
+import { computed, onMounted, ref } from "vue";
+
+/**
+ * single message svg item computed properties
+ */
+export default function useComputedBubble(m: string, id: string) {
+ const yMargin = 0;
+ const messageMargin = 20;
+ const messageWidth = ref(0);
+
+
+ // const textFill = computed(() => {
+ // switch (m) {
+ // case "sf":
+ // return "#fff";
+ // default:
+ // return "#000";
+ // }
+ // });
+
+ // const bubbleFill = computed(() => {
+ // switch (m) {
+ // case "sf":
+ // return "#61b4f4";
+ // default:
+ // return "#fff";
+ // }
+ // });
+
+ // const setMessageWidthRef = () => {
+ // const msg = document.getElementById(id);
+
+ // if (msg) {
+ // messageWidth.value = msg.getBoundingClientRect().width;
+ // }
+
+ // }
+
+ const calculateXoffset = (w: number) => {
+ let offset = messageMargin;
+
+ // If self message, render on righthand side.
+ if (m == "sf") {
+ offset = w - messageMargin - 232
+
+ // Else, render on left.
+ }
+
+ console.log(`${m} : ${offset}`);
+ return offset
+ }
+
+ const calculateYoffset = (h: number) => {
+
+ // Bubble will render a little bit below the screen.
+ return h + yMargin
+ }
+
+ // Where the textBubble is going to initially render.
+ const startingOffset = computed(() => {
+
+ // Get current dimensions of the messenger.
+ const parentView = document.getElementById('messagesView');
+
+ if (parentView) {
+ const dimensions = parentView.getBoundingClientRect();
+
+ let X = calculateXoffset(dimensions.width);
+ let Y = calculateYoffset(dimensions.height);
+
+ return `translate(${X} ${Y})`;
+ }
+
+ });
+
+ return {
+ startingOffset
+ };
+}
<template>
- <g :id="item.id" :class="item.modifier" :transform="startingOffset">
- <rect ref="messageRect" x="30" y="10" width="196" height="63" rx="10" :fill="bubbleFill" />
- <text font-size="14" font-family="SF Pro Text" ref="messageText" :fill="textFill">
- <tspan dy="16" x="0" v-for="(item, index) in textArr" :key="index">{{ item }}</tspan>
+ <g
+ :id="item.id"
+ :class="item.modifier"
+ :transform="startingOffset"
+ >
+ <rect
+ ref="messageRect"
+ x="30"
+ y="10"
+ width="196"
+ height="63"
+ rx="10"
+ :fill="bubbleFill"
+ />
+ <text
+ font-size="14"
+ font-family="SF Pro Text"
+ ref="messageText"
+ :fill="textFill">
+
+ <tspan dy="16" x="0" v-for="(item, index) in textArr" :key="index">
+ {{ item }}
+ </tspan>
+
</text>
+
<g :transform="signatureTranslate">
<text
transform="translate(0, 5)"
font-family="SFCompactDisplay-Bold, SF Compact Display"
font-weight="700"
>
- <tspan xml:space="preserve">{{ item.context }}</tspan>
+
+ <tspan xml:space="preserve">
+ {{ item.context }}
+ </tspan>
+
</text>
+
<text
transform="translate(0, 20)"
fill="#6f6f6f"
font-size="9"
font-family="SFCompactDisplay, SF Compact Display"
>
- <tspan v-if="item.subContext">{{item.subContext}}</tspan>
+
+ <tspan v-if="item.subContext">
+ {{item.subContext}}
+ </tspan>
+
</text>
</g>
</g>
</template>
<script lang="ts">
-import useComputedBubble from "./bubbleDetails/computed";
-import useBubbleDrawer from "./bubbleDetails/drawer";
+
+import useBubbleDrawer from "./drawer";
+import useComputedBubble from "./computed";
+
import useTextWrap from "@/modules/textWrap";
+
import { defineComponent, onMounted, ref, reactive } from "vue";
export default defineComponent({
const messageRect = ref(`message${msgID.value}`);
const messageText = ref(`text${msgID.value}`);
+ // Visual attribues of bubble.
const { textFill, bubbleFill, startingOffset } = useComputedBubble(
props.item.modifier,
props.item.id
);
+
const { textWrap } = useTextWrap();
const { drawMessage, signatureTranslate } = useBubbleDrawer({
mr: messageRect,
rendering.value = false;
}
+ // const beforeEnter: VueTransitionCallback = () => {
+ // const parentView = document.getElementById('messagesView');
+
+ // if (parentView) {
+ // const dimensions = parentView.getBoundingClientRect();
+
+ // }
+ // }
+
+
+
// Get height of messageView.
const beforeEnter: VueTransitionCallback = () => {
rendering.value = true;
audio: 0,
text: input
};
+<<<<<<< Updated upstream
// trigger send animation
emitter.emit("animate-send");
const {
visualizeStreamAsPaths,
+=======
+ emitter.emit("animate-send", message);
+ }
+
+ const {
+ visualizeStreamAsPaths,
+>>>>>>> Stashed changes
expandBubble
} = useAudioVisualizer(visualizeStream);
<style lang="scss" scoped>
.inputBubble {
+ position: fixed;
max-width: 180px;
min-height: 32px;
font-size: 14px;
+ bottom: 20px;
+ margin-left: 50%;
+
p {
max-width: 150px;
overflow-wrap: break-word;
const x = ref(0)
const paddingLeft = 30;
- const winW = 350;
+ let winW = 350;
const messageWidth = ref(0);
const messageMarginTop = 75;
}
});
+ const updatewinW = computed(() => {
+ const parentView = document.getElementById('messageView');
+ if (parentView) {
+ winW = parentView.getBoundingClientRect().width;
+ }
+ })
+
const setMessageWidthRef = async () => {
const msg = await document.getElementById(id);
if (msg) {
const heightResult = getHeight();
const widthResult = getWidth();
+ console.log(heightResult);
+ console.log(widthResult);
+
if (heightResult) {
// only scroll if renderer scrollStart
if (heightResult > scrollStartHeight) {
}
onMounted(() => {
- scrollTarget = document.getElementById(targetId);
+ scrollTarget = document.getElementById("targetId");
if (scrollTarget) {
window.addEventListener("wheel", scrollUpdate);
}
createWebHashHistory,
RouteRecordRaw
} from "vue-router";
-import Home from "@/views/home.vue";
+import Home from "@/views/messenger.vue";
import Splash from "@/views/splash.vue";
import { useAuth } from '@/modules/auth';
+++ /dev/null
-<template>
- <svg
- id="messenger"
- version="1.1"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- @click="emittMessage"
- >
- <MessageView />
- <TextAudioInput />
- </svg>
-</template>
-
-<script lang="ts">
-
-// Home consists on MessageView and Text/Audio imput component.
-import MessageView from "@/components/messageView/index.vue";
-import TextAudioInput from "@/components/taInput/index.vue";
-
-import { defineComponent } from "vue";
-
-export default defineComponent({
- name: "Messenger",
- components: { MessageView, TextAudioInput },
-});
-
-</script>
-
-<style lang="scss" scoped>
-
- #messenger {
- width: 100vw;
- height: 100vh;
- background-color: #EBEBEB;
- }
-
-</style>
--- /dev/null
+<template>
+
+ <TextAudioInput />
+
+ <!-- List of text bubbles. -->
+ <div id="messenger" v-for="message in messages">
+ <!-- <TextBubble :message="message"/> -->
+ <div>Hello</div>
+ </div>
+
+</template>
+
+<script lang="ts">
+
+import { defineComponent, reactive, onMounted } from "vue";
+
+import TextAudioInput from "@/components/taInput/index.vue";
+// import TextBubble from "@/components/messageView/textBubble.vue";
+import { Message } from "@/types/message/index";
+
+export default defineComponent({
+ name: "Messenger",
+
+ components: {
+ // TextBubble
+ TextAudioInput
+ },
+
+ setup() {
+
+ // List of messages in the view.
+ const messages: Message[] = reactive([])
+
+ // Render a message.
+ const render = (message: Message) => {
+ messages.push(message)
+ }
+
+ onMounted(() => {
+
+ // Listen for new messages to render.
+ window.ipcRenderer.on("render-message", (event, payload) => {
+ if (payload.message.content) render(payload.message);
+ });
+
+ })
+
+ return {
+ messages
+ }
+
+ }
+
+});
+
+</script>
+
+<style lang="scss" scoped>
+
+ #messenger {
+ width: 100vw;
+ height: 100vh;
+
+ background-color: #EBEBEB;
+ }
+
+</style>