]> Repos - mime-chat/commitdiff
message positioning for svgs
authorAndrew Gundersen <gundersena@xavier.edu>
Fri, 26 Feb 2021 01:31:00 +0000 (19:31 -0600)
committerAndrew Gundersen <gundersena@xavier.edu>
Fri, 26 Feb 2021 01:31:00 +0000 (19:31 -0600)
src/components/messageView/message/calcPosition.ts [new file with mode: 0644]
src/components/messageView/message/message.vue [new file with mode: 0644]
src/components/messageView/textBubble.vue [deleted file]
src/components/messageView/textBubble/computed.ts
src/components/taInput/inputController.ts
src/views/messenger.vue

diff --git a/src/components/messageView/message/calcPosition.ts b/src/components/messageView/message/calcPosition.ts
new file mode 100644 (file)
index 0000000..ada379c
--- /dev/null
@@ -0,0 +1,33 @@
+import {computed} from "vue";
+
+// Size of "side-gutters" of message window.
+const margin = 20;
+const messagePadding = 15;
+const firstChildMargin = 45;
+
+
+function calcXPosition(messageWidth: number, windowWidth: number, modifier: string) {
+       let offset = margin;
+
+       if (modifier == "sf") {
+               offset = windowWidth - messageWidth - margin;
+       }
+
+       return offset
+}
+
+function calcMessagePosition(modifier: string, messageWidth: number, 
+    windowWidth: number, anchorPosition: any) {
+
+       const X = calcXPosition(messageWidth, windowWidth, modifier);
+
+    // Depends on if first child.
+    let Y = firstChildMargin;
+    if (anchorPosition != "none") {
+        Y = anchorPosition + messagePadding;
+    }
+
+       return `translate(${X} ${Y})`;
+}
+
+export default calcMessagePosition;
\ No newline at end of file
diff --git a/src/components/messageView/message/message.vue b/src/components/messageView/message/message.vue
new file mode 100644 (file)
index 0000000..bd8e804
--- /dev/null
@@ -0,0 +1,101 @@
+<template>
+
+  <svg 
+    xmlns="http://www.w3.org/2000/svg" 
+    width="100" 
+    height="46" 
+    :transform="position"
+  >
+
+    <rect 
+      :id="message.id"
+      :class="message.modifier" 
+
+      width="100" height="46" rx="10" fill="#58c4fd"
+    />
+
+  </svg>
+
+</template>
+
+<script lang="ts">
+
+import { defineComponent, computed, onMounted, ref, reactive } from "vue";
+
+import calcMessagePosition from "./calcPosition";
+
+
+export default defineComponent({
+  name: "MessageBubble",
+
+  props: {
+
+    // DOM ID of the previous message.
+    // Null if message is first child.
+    anchor: {
+      type: String,
+      required: true
+    },
+
+    // Passing in the message contents.
+    message: {
+      type: Object,
+      required: true
+    },
+
+  },
+
+  setup(props) {
+
+    // e.g. "translate(20 200)"
+    const position = ref("");
+    let anchorPosition: any;
+
+    // Call to update the position variable.
+    const updatePosition = () => {
+
+      // First get anchor's position.
+      if (props.anchor == "none") {
+        anchorPosition = "none";
+      }
+
+      const m = document.getElementById(props.anchor)
+      if (m) {
+        anchorPosition = m.getBoundingClientRect().bottom
+      }
+
+      position.value = calcMessagePosition(
+        props.message.modifier,
+        100,
+        window.innerWidth,
+        anchorPosition
+      );
+
+      console.log(
+        `Message: ${props.message.id}: \n
+            Anchor: ${props.anchor}: ${anchorPosition} \n
+            Position: ${position.value}`
+      )
+
+    }
+
+    // Assign initial position.
+    updatePosition();
+
+    onMounted(() => {
+
+      // We gotta know when the message above us changes position.
+
+      // Add listener for window resize.
+      window.addEventListener("resize", updatePosition);
+
+    })
+
+    return {
+      position
+    }
+
+  },
+
+});
+</script>
diff --git a/src/components/messageView/textBubble.vue b/src/components/messageView/textBubble.vue
deleted file mode 100644 (file)
index 3e02ebb..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<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>
index c6a9c86b2e0d4044c608393e8464b5abb7988b18..e26ba0f84c1e55b751d64506c3a3c7c297a5f8b1 100644 (file)
@@ -65,8 +65,8 @@ export default function useComputedBubble(m: string, id: string) {
         if (parentView) {
             const dimensions = parentView.getBoundingClientRect();
 
-            let X = calculateXoffset(dimensions.width);
-            let Y = calculateYoffset(dimensions.height);
+            const X = calculateXoffset(dimensions.width);
+            const Y = calculateYoffset(dimensions.height);
 
             return `translate(${X} ${Y})`;
         }
index d95f7dc97fd5c095948ce7b9bb7a81d0d8d0ad45..1f79bb21ddf5d325e5f5924f2b5aa771969ed4a6 100644 (file)
@@ -29,7 +29,6 @@ export default function useInputController() {
             audio: 0,
             text: input
         };
-<<<<<<< Updated upstream
 
         // trigger send animation
         emitter.emit("animate-send");
@@ -40,13 +39,6 @@ export default function useInputController() {
 
     const {
         visualizeStreamAsPaths,
-=======
-        emitter.emit("animate-send", message);
-    }
-
-    const { 
-        visualizeStreamAsPaths, 
->>>>>>> Stashed changes
         expandBubble
     } = useAudioVisualizer(visualizeStream);
 
index c15f33202da25d079e2cf9336716ad6e22259e5a..6071aca3809271ab91339748e230044cf235eada 100644 (file)
@@ -2,38 +2,56 @@
 
     <TextAudioInput />
 
-    <!-- List of text bubbles. -->
-    <div id="messenger" v-for="message in messages">
-      <!-- <TextBubble :message="message"/> -->
-      <div>Hello</div>
+    <!-- List of message bubbles. -->
+    <div id="messenger">
+      
+      <MessageBubble id="message" v-for="(message, index) in messages"
+        :message="message" 
+        :anchor="getAnchor(index)"  
+      />
+
     </div>
 
 </template>
 
 <script lang="ts">
 
-import { defineComponent, reactive, onMounted } from "vue";
+import { defineComponent, computed, reactive, onMounted, ref } from "vue";
 
 import TextAudioInput from "@/components/taInput/index.vue";
-// import TextBubble from "@/components/messageView/textBubble.vue";
+import MessageBubble from "@/components/messageView/message/message.vue";
 import { Message } from "@/types/message/index";
 
 export default defineComponent({
   name: "Messenger",
 
-  components: { 
-    // TextBubble
+  components: {
+    MessageBubble,
     TextAudioInput 
   },
 
-  setup() {
+  setup(props) {
 
     // List of messages in the view.
+    // Oldest message first.
     const messages: Message[] = reactive([])
 
     // Render a message.
     const render = (message: Message) => {
       messages.push(message)
+      console.log(`Pushing: ${message.modifier}: ${message.content}`)
+    }
+
+    // Get the "anchor" message for a given message.
+    const getAnchor = (index: number) => {
+      let anchor = "none";
+
+      // If not the first message.
+      if (index > 0) {
+        anchor = messages[index - 1].id
+      }
+
+      return anchor
     }
 
     onMounted(() => {
@@ -46,7 +64,8 @@ export default defineComponent({
     })
 
     return {
-      messages
+      messages,
+      getAnchor
     }
 
   }
@@ -59,9 +78,15 @@ export default defineComponent({
 
   #messenger {
     width: 100vw;
-    height: 100vh;
+    min-height: 100vh;
+
+    overflow: scroll;
 
     background-color: #EBEBEB;
   }
 
+  #message {
+    position: absolute;
+  }
+
 </style>