working new protocols

This commit is contained in:
Andrew Gundersen 2021-06-29 16:21:18 -05:00
commit b6b1f3e894
8 changed files with 168 additions and 139 deletions

View file

@ -6,22 +6,14 @@
<script lang='ts'>
import { defineComponent, ref, onMounted } from 'vue';
import { defineComponent } from 'vue';
export default defineComponent({
name: "Bubble",
props: ["modifier", "content", "child"],
setup(props) {
onMounted(() => {
});
return {
};
setup() {
}
@ -38,30 +30,18 @@
font-size: 14px;
padding: 10px;
border-radius: 18px;
margin-left: 15px;
margin-right: 15px;
margin-bottom: 4px;
// animation-name: bubble-init-anim;
// animation-duration: 0.5s;
}
@keyframes bubble-init-anim {
from {
opacity: 0;
transform: translateY(25px);
} to {
opacity: 1;
transform: translateY(0px);
}
}
.ai-bubble {
background-color: #FFFFFF;
margin-left: 15px;
}
.client-bubble {
color: white;
background-color: #58C4FD;
margin-right: 15px;
}
.ai-first-child {
@ -94,7 +74,6 @@
border-top-right-radius: 9px;
}
// .notify {
// position: absolute;
// width: 12px;

View file

@ -0,0 +1,88 @@
<template>
<span :class="`context ${modifier}-context`">
<div v-if="modifier==='ai'" class="avatar"></div>
{{ contextRef }}
</span>
</template>
<script lang='ts'>
import { defineComponent, ref, watch } from 'vue';
import { annotateAnim } from "@/render/components/controllers/helpers";
export default defineComponent({
name: "Context",
props: ["modifier", "context", "uid"],
setup(props) {
const contextRef = ref(" ");
contextRef.value = props.context;
watch(() => props.context, (val: string, _oldval: string) => {
annotateAnim(props.uid, val, contextRef);
});
return {
contextRef
};
}
})
</script>
<style lang="scss" scoped>
.context {
position: relative;
min-height: 14px;
display: flex;
align-items: center;
font-family: "SF Compact Display";
font-size: 12px;
font-weight: bold;
margin-top: 5px;
}
.ai-context {
margin-left: 15px;
}
.client-context {
margin-right: 15px;
}
.avatar {
margin-right: 5px;
width: 30px;
height: 30px;
background-color: white;
border-radius: 15px;
}
.playing {
animation-name: message-playback-anim;
animation-duration: 2s;
animation-iteration-count: infinite;
}
@keyframes message-playback-anim {
0%,
100% {
box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.4), 0 0 0 0.25em rgba(195, 195, 195, 0.15);
}
25% {
box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.15), 0 0 0 0.4em rgba(195, 195, 195, 0.3);
}
50% {
box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.55), 0 0 0 0.15em rgba(195, 195, 195, 0.05);
}
75% {
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25), 0 0 0 0.55em rgba(195, 195, 195, 0.45);
}
}
</style>

View file

@ -1,6 +1,5 @@
import { ref, Ref } from "vue";
import anime from "animejs";
import { v4 as uuidv4 } from 'uuid';
export function animateTextInput () {
@ -93,7 +92,7 @@ export function annotateAnim (uid: string, val: string, contextRef: Ref) {
anime({
targets: `#${uid} span`,
opacity: [1, 0],
duration: 500,
duration: 250,
easing: 'easeOutExpo'
})
@ -105,7 +104,7 @@ export function annotateAnim (uid: string, val: string, contextRef: Ref) {
anime({
targets: `#${uid} span`,
opacity: [0, 1],
duration: 500,
duration: 250,
easing: 'easeOutExpo'
})
})

View file

@ -32,7 +32,7 @@ import draggify from "@/render/composables/useDraggify";
import useTextInputController from
"@/render/components/controllers/inputItem.control.text";
import useAudioInputController from
// import useAudioInputController from
"@/render/components/controllers/inputItem.control.audio";
export default defineComponent({
@ -51,7 +51,8 @@ export default defineComponent({
// Controllers for text and audio.
const { typing } = useTextInputController(elementX)
const { recording } = useAudioInputController(typing)
// const { recording } = useAudioInputController(typing)
const recording = false;
return {
elementX,

View file

@ -8,19 +8,21 @@
:child="calcChild(index, content.length)"
/>
<span class="context">
<div v-if="modifier==='ai'" class="avatar"></div>
{{ contextRef }}
</span>
<Context
:modifier="modifier"
:context="context"
:uid="uid"
/>
</div>
</template>
<script lang='ts'>
import { defineComponent, ref, Ref, onMounted, watch } from 'vue';
import { defineComponent } from 'vue';
import Bubble from "@/render/components/bubble.vue";
import { annotateAnim, calcChild } from "@/render/components/controllers/helpers";
import Context from "@/render/components/context.vue";
import { calcChild } from "@/render/components/controllers/helpers";
export default defineComponent({
name: "Message",
@ -28,25 +30,14 @@
props: ["modifier", "content", "context", "uid"],
components: {
Bubble
Bubble,
Context
},
setup(props) {
const contextRef = ref(" ");
contextRef.value = props.context;
watch(() => props.context, (val: string, oldval: string) => {
annotateAnim(props.uid, val, contextRef);
});
onMounted(() => {
});
setup() {
return {
calcChild,
contextRef
calcChild
};
}
@ -57,85 +48,41 @@
<style lang="scss" scoped>
.message {
width: 100vw;
display: flex;
flex-direction: column;
padding-top: 9px;
padding-bottom: 9px;
animation-name: message-init-anim;
animation-duration: 0.5s;
}
.message {
width: 100vw;
display: flex;
flex-direction: column;
padding-top: 9px;
padding-bottom: 9px;
animation-name: message-init-anim;
animation-duration: 0.25s;
}
@keyframes message-init-anim {
from {
opacity: 0;
transform: translateY(50px);
} to {
opacity: 1;
transform: translateY(0px);
}
@keyframes message-init-anim {
from {
opacity: 0;
} to {
opacity: 1;
}
}
.message:first-child {
margin-top: 55px;
}
.message:first-child {
margin-top: 55px;
}
.message:last-child {
margin-bottom: 18px;
}
.message:last-child {
margin-bottom: 6px;
}
.client-message {
@extend .message;
align-items: flex-end;
}
.client-message {
@extend .message;
align-items: flex-end;
}
.ai-message {
@extend .message;
align-items: flex-start;
}
.context {
position: relative;
display: flex;
align-items: center;
font-family: "SF Compact Display";
font-size: 12px;
font-weight: bold;
margin-top: 5px;
margin-right: 15px;
margin-left: 15px;
}
.avatar {
margin-right: 5px;
width: 30px;
height: 30px;
background-color: white;
border-radius: 15px;
}
.playing {
animation-name: message-playback-anim;
animation-duration: 2s;
animation-iteration-count: infinite;
}
@keyframes message-playback-anim {
0%,
100% {
box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.4), 0 0 0 0.25em rgba(195, 195, 195, 0.15);
}
25% {
box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.15), 0 0 0 0.4em rgba(195, 195, 195, 0.3);
}
50% {
box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.55), 0 0 0 0.15em rgba(195, 195, 195, 0.05);
}
75% {
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25), 0 0 0 0.55em rgba(195, 195, 195, 0.45);
}
}
.ai-message {
@extend .message;
align-items: flex-start;
}
</style>

View file

@ -20,7 +20,7 @@
<script lang="ts">
import { defineComponent, onMounted, onUnmounted } from "vue";
import { defineComponent } from "vue";
import InputItem from "@/render/components/inputItem.vue";
import Settings from "@/render/components/settings.vue";
import Message from "@/render/components/message.vue";

View file

@ -1,28 +1,32 @@
export default function useScroll(element: string) {
let isScrolledToBottom: boolean;
const view = document.getElementById(element)
export default function useScroll(elementId: string) {
// Update isScrolledToBottom
const updateScrollRef = () => {
if (view) isScrolledToBottom = view.scrollHeight - view.clientHeight <= view.scrollTop + 1;
return isScrolledToBottom;
const isScrolledToBottom = () => {
const el = document.getElementById(elementId);
if (el) {
return el.scrollHeight - el.clientHeight <= el.scrollTop + 30;
}
}
// Adjust scroll after we add content to the messenger.
const adjustScroll = () => {
if (view) {
view.scrollTo({
top: view.scrollHeight - view.clientHeight,
const el = document.getElementById(elementId);
if (el) {
el.scrollTo({
top: el.scrollHeight - el.clientHeight,
behavior: 'smooth'
});
}
}
return {
updateScrollRef,
isScrolledToBottom,
adjustScroll,
};

View file

@ -2,20 +2,31 @@
import { ref, Ref } from "vue";
import useScroll from "@/render/composables/useScroll";
const { isScrolledToBottom, adjustScroll } = useScroll("messenger");
export const messages: Ref<Array<Message>> = ref([]);
export const setMessages: IpcListenerCallback<Array<Message>> = (payload) => {
messages.value = payload as Array<Message>;
setTimeout(() => {
adjustScroll();
}, 1000);
}
export const addMessage: IpcListenerCallback<Message> = (payload) => {
const bottom = isScrolledToBottom();
messages.value.push(payload as Message);
if (bottom) {
setTimeout(() => {
adjustScroll();
}, 10);
}
}
export const updateMessage: IpcListenerCallback<Annotation> = (payload) => {
const annotation = payload as Annotation;
for (let i in messages.value) {
for (const i in messages.value) {
if (messages.value[i].uid == annotation.uid) {
@ -36,7 +47,7 @@ export const updateMessage: IpcListenerCallback<Annotation> = (payload) => {
export const deleteMessage: IpcListenerCallback<string> = (payload) => {
const uid = payload as string;
for (var i = 0; i < messages.value.length; i++) {
for (let i = 0; i < messages.value.length; i++) {
if (messages.value[i].uid === uid) {
messages.value.splice(i, 1);
break;