mime-chat/src/components/inputItem.vue
Andrew Gundersen 81662942a2 merging
2021-03-30 10:48:45 -05:00

194 lines
3.8 KiB
Vue

<template>
<div
id="inputItem"
class="input-item"
:class="{ playing: recording }"
:style="{ top: `${elementY}px`, left: `${elementX}px` }"
>
<div>{{ initials }}</div>
<!-- Recording animation on space bar -->
<span v-if="recording" class="play"></span>
<span v-if="recording" class="pause"></span>
<!-- Show text input on key-down -->
<TextInput />
<!-- Show suggestions menu on click -->
<!-- <Menu /> -->
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import draggify from "@/modules/draggify";
import TextInput from "@/components/textInput.vue";
import useTextInputController from
"@/components/controllers/textCtrl";
import useAudioInputController from
"@/components/controllers/audioCtrl";
export default defineComponent({
name: "InputItem",
props: ["initials"],
components: {
TextInput
},
setup() {
// Default values for position.
const xStart = 15;
const yStart = window.innerHeight - 200;
// Calculate position of inputItem on drag.
const { elementX, elementY } = draggify("inputItem", xStart, yStart, 15);
// Controllers for text and audio.
const { typing } = useTextInputController(elementX)
const { recording } = useAudioInputController(typing)
return {
elementX,
elementY,
recording
};
},
});
</script>
<style lang="scss" scoped>
.input-item {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
width: 40px;
height: 40px;
z-index: 3;
// To prevent window drag when overlapping with titlebar.
-webkit-app-region: no-drag;
// border: 4px solid #C6C6C6;
border-radius: 50%;
// Set opacity here to not affect child.
background-color: rgba(235, 235, 235, 0.75);
cursor: pointer;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15);
.play,
.pause {
z-index: 5;
&::before,
&::after {
-webkit-border-radius: 1000px;
-moz-border-radius: 1000px;
border-radius: 1000px;
content: "";
position: absolute;
height: 2.35em;
width: 2.35em;
left: 50%;
transform: translate(-50%, -50%);
top: 50%;
z-index: 0;
}
}
.play::before {
box-shadow: 0 0 0 rgba(195, 195, 195, 0);
}
.pause {
opacity: 0;
}
&.playing {
.play {
opacity: 0;
}
.pause {
opacity: 1;
&::before {
-moz-animation: circle1 1.5s infinite ease-in-out;
-o-animation: circle1 1.5s infinite ease-in-out;
-webkit-animation: circle1 1.5s infinite ease-in-out;
animation: circle1 1.5s infinite ease-in-out;
}
&::after {
-moz-animation: circle2 2.2s infinite ease-in-out;
-o-animation: circle2 2.2s infinite ease-in-out;
-webkit-animation: circle2 2.2s infinite ease-in-out;
animation: circle2 2.2s infinite ease-in-out;
}
}
}
}
.rec-icon {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: red;
transform: translate(14px);
animation-name: rec;
animation-duration: 0.5s;
}
@keyframes rec {
from {
transform: translate(14px) scale(0.3);
}
to {
transform: translate(14px) scale(1.0);
}
}
@keyframes circle1 {
0%,
100% {
box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.4);
}
25% {
box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.15);
}
50% {
box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.55);
}
75% {
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25);
}
}
@keyframes circle2 {
0%,
100% {
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.15);
}
25% {
box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.3);
}
50% {
box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.05);
}
75% {
box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.45);
}
}
</style>