ui enhacements and next-gen input item code (not implented)
This commit is contained in:
parent
346bfcba01
commit
a79dbf0e6c
10 changed files with 271 additions and 16 deletions
|
|
@ -50,6 +50,7 @@ export default defineComponent({
|
|||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #EBEBEB;
|
||||
}
|
||||
|
||||
#app {
|
||||
|
|
@ -61,7 +62,6 @@ export default defineComponent({
|
|||
height: 100vh;
|
||||
width: 100vw;
|
||||
|
||||
background-color: #EBEBEB;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export async function main() {
|
|||
|
||||
// create main window.
|
||||
await createWindow({
|
||||
width: 350,
|
||||
width: 600,
|
||||
height: 500,
|
||||
resizable: true
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,11 +9,8 @@ interface RenderMessage {
|
|||
text: string;
|
||||
audio: boolean | Buffer;
|
||||
};
|
||||
avatar: string;
|
||||
context: string;
|
||||
subContext: string;
|
||||
modifier: string;
|
||||
time: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
26
src/components/drag.ts
Normal file
26
src/components/drag.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
// When user clicks and holds inputItem.
|
||||
function onMouseDown (e: any) {
|
||||
window.addEventListener('mousemove', onMouseMove, true);
|
||||
}
|
||||
|
||||
// When user drags inputItem.
|
||||
function onMouseMove (e: any) {
|
||||
|
||||
const element = document.getElementById('inputItem')
|
||||
|
||||
if (element) {
|
||||
|
||||
const inputItemRect = element.getBoundingClientRect()
|
||||
inputItemX.value = inputItemRect.left + e.movementX
|
||||
inputItemY.value = inputItemRect.top + e.movementY
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// When user lets go of inputItem.
|
||||
function onMouseUp (e: any) {
|
||||
|
||||
}
|
||||
|
||||
133
src/components/inputItem.vue
Normal file
133
src/components/inputItem.vue
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
<template>
|
||||
<div id=inputItem
|
||||
:style="{ top: `${inputItemY}px`, left: `${inputItemX}px` }">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent, onMounted, ref, onUnmounted } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "InputItem",
|
||||
|
||||
setup() {
|
||||
|
||||
let inputItemX = ref(0)
|
||||
let inputItemY = ref(0)
|
||||
|
||||
let xShort: object = {
|
||||
distance: Number,
|
||||
side: String
|
||||
}
|
||||
|
||||
let percentX: number;
|
||||
let percentY: number;
|
||||
|
||||
// Draggable on mousedown.
|
||||
const mouseDown = (e: any) => {
|
||||
window.addEventListener('mousemove', divMove, true);
|
||||
}
|
||||
|
||||
// Update the positional refs.
|
||||
const mouseUp = (e: any) => {
|
||||
window.removeEventListener('mousemove', divMove, true);
|
||||
|
||||
|
||||
|
||||
const winW = window.innerWidth
|
||||
const winH = window.innerHeight
|
||||
console.log(`Window dimensions: W${winW} H${winH}`)
|
||||
|
||||
}
|
||||
|
||||
// Called on mousemove event. Updates the inputItem cords when user is
|
||||
// dragging it.
|
||||
const divMove = (e: any) => {
|
||||
const element = document.getElementById('inputItem')
|
||||
|
||||
if (element) {
|
||||
|
||||
const inputItemRect = element.getBoundingClientRect()
|
||||
inputItemX.value = inputItemRect.left + e.movementX
|
||||
inputItemY.value = inputItemRect.top + e.movementY
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Adjust position of inputItem on window resize.
|
||||
// If inputItem is within 10% of corner, keep the distances from that
|
||||
// corner fixed, else resize relative to percentages.
|
||||
const handleResize = (e: any) => {
|
||||
|
||||
// Adjust X:
|
||||
// Is X close to a vertical side?
|
||||
// If so: position fixed
|
||||
if (inputItemX.onSide) {
|
||||
|
||||
if (inputItemX.rightSide) {
|
||||
inputItemX.value = window.innerWidth - xShort
|
||||
} else {
|
||||
inputItemX.value = xShort
|
||||
}
|
||||
|
||||
// Else: position relative
|
||||
} else {
|
||||
inputItemX.value = window.innerWidth * percentX
|
||||
}
|
||||
|
||||
// Initialize InputPosition.
|
||||
inputItemX.value = 300
|
||||
inputItemY.value = 300
|
||||
percentX = 0.5
|
||||
percentY = 0.5
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
const element = document.getElementById('inputItem')
|
||||
|
||||
if (element) {
|
||||
element.addEventListener('mousedown', mouseDown, false);
|
||||
}
|
||||
|
||||
window.addEventListener('mouseup', mouseUp, false);
|
||||
window.addEventListener('resize', handleResize, false)
|
||||
|
||||
});
|
||||
|
||||
return {
|
||||
inputItemX,
|
||||
inputItemY
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
#inputItem {
|
||||
position: absolute;
|
||||
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
border-radius: 19px;
|
||||
|
||||
z-index: 20;
|
||||
|
||||
top: 200px;
|
||||
right: 0px;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 4px;
|
||||
border-color: #C3C3C3;
|
||||
|
||||
background-color: white;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -5,6 +5,9 @@
|
|||
:key="message.id"
|
||||
>
|
||||
|
||||
<!-- Three types of messages: self (sf), friend (fr), and crimata (ai) -->
|
||||
<!-- !denoted by the modifier attribute -->
|
||||
|
||||
<!-- Includes bubble and context. -->
|
||||
<div class="messageBox" :id="`${message.modifier}MessageBox`">
|
||||
|
||||
|
|
@ -13,19 +16,20 @@
|
|||
class="bubble"
|
||||
:id="`${message.modifier}Bubble`"
|
||||
>
|
||||
{{ message.content }}
|
||||
{{ message.content.text }}
|
||||
</div>
|
||||
|
||||
<!-- message context -->
|
||||
<span class="context">
|
||||
|
||||
<!-- Render Crimata icon or initials. -->
|
||||
<div v-if="message.avatar == 'crimata'" class="photo">
|
||||
<!-- Render Crimata icon or friend's initials. -->
|
||||
<div v-if="message.modifier == 'ai'" class="photo">
|
||||
<img src="@/assets/crimata.svg"/>
|
||||
</div>
|
||||
|
||||
<div v-else class="photo">
|
||||
{{ message.avatar }}
|
||||
<!-- Render Crimata icon or friend's initials. -->
|
||||
<div v-if="message.modifier == 'fr'" class="photo">
|
||||
{{ message.context[0] }}
|
||||
</div>
|
||||
|
||||
{{ message.context }}
|
||||
|
|
@ -79,12 +83,28 @@
|
|||
align-items: flex-end;
|
||||
}
|
||||
|
||||
#frMessage {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.messageBox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#aiMessageBox {
|
||||
margin-left: 20px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#sfMessageBox {
|
||||
margin-right: 20px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
#frMessageBox {
|
||||
margin-left: 20px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
|
|
@ -110,6 +130,10 @@
|
|||
color: white;
|
||||
}
|
||||
|
||||
#frBubble {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.context {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -117,7 +141,6 @@
|
|||
font-family: "SF Compact Display";
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin-left: 7px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
|
|
|
|||
7
src/components/resize.ts
Normal file
7
src/components/resize.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
// Update inputItem position on window resize.
|
||||
// Gets called on window.resize event.
|
||||
function handleWindowResize (e: any) {
|
||||
|
||||
}
|
||||
|
||||
66
src/test.vue
Normal file
66
src/test.vue
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// Snap to the nearest window border and update percentages. Called when
|
||||
// user stops dragging the inputItem.
|
||||
const mouseUp = (e: any) => {
|
||||
window.removeEventListener('mousemove', divMove, true);
|
||||
|
||||
const winW = window.innerWidth
|
||||
const winH = window.innerHeight
|
||||
console.log(`Window dimensions: W${winW} H${winH}`)
|
||||
|
||||
// First, are we changing inputItemX or inputItemY?
|
||||
|
||||
let xShort = winW - inputItemX.value
|
||||
if (xShort > winW / 2) {
|
||||
xShort = inputItemX.value
|
||||
}
|
||||
|
||||
let yShort = winH - inputItemY.value
|
||||
if (yShort > winH / 2) {
|
||||
yShort = inputItemY.value
|
||||
}
|
||||
|
||||
const shortest = (xShort < yShort) ? "inputItemX" : "inputItemY"
|
||||
|
||||
// Then, are we tranlating it positive or negative?
|
||||
// To answer this, we see which side is it closer to.
|
||||
// We also update percentages to aid in window resizing (handleResize).
|
||||
|
||||
if (shortest == "inputItemX") {
|
||||
if (inputItemX.value < winW / 2) {
|
||||
inputItemX.value = 0
|
||||
percentX = 0.0
|
||||
} else {
|
||||
inputItemX.value = winW - 38
|
||||
percentX = 1.0
|
||||
}
|
||||
percentY = inputItemY.value / winH
|
||||
} else {
|
||||
if (inputItemY.value < winH / 2) {
|
||||
inputItemY.value = 0
|
||||
percentY = 0.0
|
||||
} else {
|
||||
inputItemY.value = winH - 38
|
||||
percentY = 1.0
|
||||
}
|
||||
percentX = inputItemX.value / winW
|
||||
|
||||
}
|
||||
console.log(`Percents updated: iX: ${percentX} iY: ${percentY}`)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (percentX == 1.0) {
|
||||
inputItemX.value = window.innerWidth * percentX - 38
|
||||
} else {
|
||||
inputItemX.value = window.innerWidth * percentX
|
||||
}
|
||||
|
||||
if (percentY == 1.0) {
|
||||
inputItemY.value = window.innerHeight * percentY - 38
|
||||
} else {
|
||||
inputItemY.value = window.innerHeight * percentY
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
export interface Message {
|
||||
content: string;
|
||||
avatar: string;
|
||||
content: {
|
||||
text: string;
|
||||
audio: boolean | Buffer;
|
||||
};
|
||||
context: string;
|
||||
subContext: string;
|
||||
modifier: string;
|
||||
id: string;
|
||||
time: string;
|
||||
}
|
||||
|
||||
interface MessageTransform {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
|
||||
<TextAudioInput />
|
||||
<!-- <InputItem /> -->
|
||||
|
||||
<!-- List of message bubbles. -->
|
||||
<div id="messenger" >
|
||||
|
|
@ -15,6 +16,7 @@ import { defineComponent, reactive, onMounted, ref, onUnmounted } from "vue";
|
|||
import TextAudioInput from "@/components/taInput/index.vue";
|
||||
import { Message } from "@/types/message/index";
|
||||
import MessageItem from '@/components/messageItem.vue'
|
||||
// import InputItem from "@/components/inputItem.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "Messenger",
|
||||
|
|
@ -22,6 +24,7 @@ export default defineComponent({
|
|||
components: {
|
||||
TextAudioInput,
|
||||
MessageItem,
|
||||
// InputItem
|
||||
},
|
||||
|
||||
setup() {
|
||||
|
|
@ -33,7 +36,7 @@ export default defineComponent({
|
|||
// Render a message.
|
||||
const render = (message: Message) => {
|
||||
messages.push(message);
|
||||
console.log(`Pushing: ${message.modifier}: ${message.avatar}, ${message.content}`);
|
||||
console.log(`Pushing: ${message.modifier}: ${message.content.text} ${message.context}`);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue