330 lines
5.2 KiB
Vue
330 lines
5.2 KiB
Vue
<template>
|
|
<div :class="`${type}-message`">
|
|
|
|
<!-- message bubble -->
|
|
<div :class="`${type}-${child}-bubble`">
|
|
<div class="notification-dot"/>
|
|
<div class="error-dot"/>
|
|
{{ text }}
|
|
</div>
|
|
|
|
<!-- message context -->
|
|
<span class="context">
|
|
<div :class="`${type}-icon`">
|
|
{{ context }}
|
|
</span>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script lang='ts'>
|
|
|
|
import { defineComponent, ref, onMounted } from 'vue';
|
|
|
|
export default defineComponent({
|
|
name: "MessageItem",
|
|
|
|
props: ["text", "context", "type", "position"],
|
|
|
|
setup() {
|
|
|
|
/* initialize seen state */
|
|
const seen = ref(() => {
|
|
if (document.visibilityState === "visible") {
|
|
return true;
|
|
} else return false;
|
|
});
|
|
|
|
onMounted(() => {
|
|
|
|
if (!seen)
|
|
document.addEventListener("visibilitychange", () => seen = true);
|
|
|
|
});
|
|
|
|
return {
|
|
seen
|
|
};
|
|
|
|
}
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.message {
|
|
width: 100vw;
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding-top: 9px;
|
|
padding-bottom: 9px;
|
|
}
|
|
|
|
.message:first-child {
|
|
margin-top: 55px;
|
|
}
|
|
|
|
.message:last-child {
|
|
margin-bottom: 18px;
|
|
}
|
|
|
|
.sf-message {
|
|
@extend .message;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.ai-message, .fr-message {
|
|
@extend .message;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.bubble {
|
|
position: relative;
|
|
max-width: 66vw;
|
|
font-family: "SF Pro Text";
|
|
font-size: 14px;
|
|
padding: 10px;
|
|
border-radius: 18px;
|
|
}
|
|
|
|
.sf-bubble {
|
|
@extend .bubble;
|
|
background-color: #58c4fd;
|
|
color: white;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.firstChildMessage {
|
|
padding-bottom: 2px;
|
|
}
|
|
|
|
.middleChildMessage {
|
|
padding-top: 2px;
|
|
padding-bottom: 2px;
|
|
}
|
|
|
|
.lastChildMessage {
|
|
padding-top: 2px;
|
|
}
|
|
|
|
#aiMessage {
|
|
align-items: flex-start;
|
|
}
|
|
|
|
#sfMessage {
|
|
align-items: flex-end;
|
|
}
|
|
|
|
#frMessage {
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.messageBox {
|
|
position: relative;
|
|
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
// Animate on render.
|
|
animation-name: appear;
|
|
animation-duration: 0.25s;
|
|
}
|
|
|
|
#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 {
|
|
position: relative;
|
|
|
|
max-width: 66vw;
|
|
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
font-family: "SF Pro Text";
|
|
font-size: 14px;
|
|
|
|
padding: 10px;
|
|
|
|
border-radius: 18px;
|
|
}
|
|
|
|
@keyframes appear {
|
|
10% {
|
|
transform: scale(0.3);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
#aiBubble {
|
|
background-color: white;
|
|
}
|
|
|
|
#sfBubble {
|
|
background-color: #58c4fd;
|
|
color: white;
|
|
}
|
|
|
|
#frBubble {
|
|
background-color: white;
|
|
}
|
|
|
|
.sf-firstChildBubble {
|
|
border-bottom-right-radius: 9px;
|
|
}
|
|
|
|
.sf-middleChildBubble {
|
|
border-top-right-radius: 9px;
|
|
border-bottom-right-radius: 9px;
|
|
}
|
|
|
|
.sf-lastChildBubble {
|
|
border-top-right-radius: 9px;
|
|
}
|
|
|
|
.ai-firstChildBubble, .fr-firstChildBubble {
|
|
border-bottom-left-radius: 9px;
|
|
}
|
|
|
|
.ai-middleChildBubble, .fr-middleChildBubble {
|
|
border-top-left-radius: 9px;
|
|
border-bottom-left-radius: 9px;
|
|
}
|
|
|
|
.ai-lastChildBubble, .fr-lastChildBubble {
|
|
border-top-left-radius: 9px;
|
|
}
|
|
|
|
.notify {
|
|
position: absolute;
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
background-color: #58D9FF;
|
|
top: -5px;
|
|
left: -5px;
|
|
border: 2px solid #EBEBEB;
|
|
transform: scale(0);
|
|
|
|
animation-name: notify-anim;
|
|
animation-duration: 5s;
|
|
}
|
|
|
|
@keyframes notify-anim {
|
|
0%, 90% {
|
|
transform: scale(1);
|
|
}
|
|
100% {
|
|
transform: scale(0);
|
|
}
|
|
}
|
|
|
|
.context {
|
|
position: relative;
|
|
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
font-family: "SF Compact Display";
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.photo {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
margin-right: 5px;
|
|
|
|
width: 30px;
|
|
height: 30px;
|
|
|
|
font-size: 14px;
|
|
|
|
background-color: white;
|
|
border-radius: 15px;
|
|
}
|
|
|
|
// Apply for audio message playback.
|
|
.playing {
|
|
animation-name: circle1;
|
|
animation-duration: 2s;
|
|
animation-iteration-count: infinite;
|
|
}
|
|
|
|
@keyframes circle1 {
|
|
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);
|
|
}
|
|
}
|
|
|
|
.contentLoader {
|
|
display: flex;
|
|
}
|
|
|
|
.contentLoaderDot {
|
|
width: 5px;
|
|
height: 5px;
|
|
|
|
margin: 2px;
|
|
border-radius: 2.5px;
|
|
background-color: #357CA2;
|
|
}
|
|
|
|
.questionMark {
|
|
font-weight: 900;
|
|
color: #357CA2;
|
|
}
|
|
|
|
// .divider {
|
|
// width: 100vw;
|
|
// display: flex;
|
|
// justify-content: center;
|
|
// align-items: center;
|
|
|
|
// font-family: "SF Compact Display";
|
|
// font-size: 12px;
|
|
// font-weight: bold;
|
|
// color: #9B9B9B;
|
|
|
|
// margin-bottom: 18px;
|
|
// }
|
|
|
|
|
|
</style>
|
|
|
|
|