@adminforth/agent 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -24,11 +24,13 @@ const props = withDefaults(defineProps<{
|
|
|
24
24
|
wrapperStyle?: Record<string, string>
|
|
25
25
|
contentStyle?: Record<string, string>
|
|
26
26
|
scrollBarAutoHide?: boolean
|
|
27
|
+
scrollToBottomOnMount?: boolean
|
|
27
28
|
}>(), {
|
|
28
29
|
enabled: true,
|
|
29
30
|
threshold: 50,
|
|
30
31
|
behavior: 'instant',
|
|
31
|
-
scrollBarAutoHide: true
|
|
32
|
+
scrollBarAutoHide: true,
|
|
33
|
+
scrollToBottomOnMount: true
|
|
32
34
|
})
|
|
33
35
|
|
|
34
36
|
const containerRef = ref<HTMLDivElement | null>(null)
|
|
@@ -72,7 +74,7 @@ onMounted(() => {
|
|
|
72
74
|
scrollParams.value.scrollTop = containerRef.value.scrollEl.scrollTop
|
|
73
75
|
scrollParams.value.scrollHeight = containerRef.value.scrollEl.scrollHeight
|
|
74
76
|
scrollParams.value.clientHeight = containerRef.value.scrollEl.clientHeight
|
|
75
|
-
if (
|
|
77
|
+
if (!isUserScrolledUp.value && props.scrollToBottomOnMount) {
|
|
76
78
|
scrollToBottom()
|
|
77
79
|
}
|
|
78
80
|
})
|
|
@@ -102,6 +104,7 @@ function isNearBottom(customThreshold?: number): boolean {
|
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
function scrollToBottom(force = false): void {
|
|
107
|
+
console.log('scrollToBottom called with force:', force)
|
|
105
108
|
const container = containerRef.value?.scrollEl
|
|
106
109
|
if (!container) return
|
|
107
110
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<div ref="chatContainerRef" class="relative flex-1 min-h-0 overflow-hidden" @click="recalculateScroll()">
|
|
12
12
|
<CustomAutoScrollContainer
|
|
13
13
|
v-if="showScrollContainer"
|
|
14
|
-
:enabled="
|
|
14
|
+
:enabled="false"
|
|
15
15
|
class="relative h-full flex flex-col overflow-y-auto translate-x-[-50%] left-1/2"
|
|
16
16
|
ref="scrollContainer"
|
|
17
17
|
:threshold="THRESHOLD_TO_SHOW_BUTTON"
|
|
@@ -53,27 +53,49 @@
|
|
|
53
53
|
</div>
|
|
54
54
|
<div v-if="showBottomSpacer" class="w-full" :style="{ height: spacerHeight + 'px' }"></div>
|
|
55
55
|
</CustomAutoScrollContainer>
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
<Transition
|
|
57
|
+
enter-active-class="transition-all duration-250 ease-out"
|
|
58
|
+
enter-from-class="opacity-0 translate-y-3 scale-90"
|
|
59
|
+
enter-to-class="opacity-100 translate-y-0 scale-100"
|
|
60
|
+
leave-active-class="transition-all duration-200 ease-in"
|
|
61
|
+
leave-from-class="opacity-100 translate-y-0 scale-100"
|
|
62
|
+
leave-to-class="opacity-0 translate-y-3 scale-90"
|
|
63
|
+
>
|
|
64
|
+
<button
|
|
65
|
+
v-if="showScrollToBottomButton"
|
|
66
|
+
@click="scrollContainer.scrollToBottom();"
|
|
67
|
+
class="absolute z-10 bottom-8 left-1/2 -translate-x-1/2
|
|
68
|
+
bg-lightPrimary/20 dark:bg-darkPrimary/10
|
|
69
|
+
border border-lightPrimary dark:border-darkPrimary
|
|
70
|
+
text-lightPrimary dark:text-darkPrimary
|
|
71
|
+
backdrop-blur-sm rounded-full
|
|
72
|
+
w-10 h-10 flex items-center justify-center gap-0.5"
|
|
73
|
+
:class="{ 'w-12 h-8': showAnimationInScrollToBottomButton }"
|
|
74
|
+
>
|
|
75
|
+
<IconArrowDownOutline
|
|
76
|
+
v-if="!showAnimationInScrollToBottomButton"
|
|
77
|
+
class="p-2 w-10 h-10 transition-opacity duration-100 ease-in "
|
|
78
|
+
:disabled="!showScrollToBottomButton"
|
|
79
|
+
/>
|
|
80
|
+
<ThreeDotsAnimation
|
|
81
|
+
v-else
|
|
82
|
+
:disabled="!showScrollToBottomButton"
|
|
83
|
+
/>
|
|
84
|
+
</button>
|
|
85
|
+
</Transition>
|
|
65
86
|
</div>
|
|
66
87
|
</template>
|
|
67
88
|
|
|
68
89
|
|
|
69
90
|
<script setup lang="ts">
|
|
70
91
|
import type { IMessage } from '../types';
|
|
71
|
-
import { useTemplateRef, ref, onMounted, onUnmounted, watch, nextTick, defineAsyncComponent } from 'vue';
|
|
92
|
+
import { useTemplateRef, ref, onMounted, onUnmounted, watch, nextTick, defineAsyncComponent, computed } from 'vue';
|
|
72
93
|
import { IconArrowDownOutline } from '@iconify-prerendered/vue-flowbite';
|
|
73
94
|
import SessionsHistory from '../SessionsHistory.vue';
|
|
74
95
|
import { useAgentStore } from '../composables/useAgentStore';
|
|
75
96
|
import { useAgentTransitions } from '../composables/useAgentTransitions';
|
|
76
97
|
import MessageRenderer from './MessageRenderer.vue';
|
|
98
|
+
import ThreeDotsAnimation from './ThreeDotsAnimation.vue';
|
|
77
99
|
|
|
78
100
|
const CustomAutoScrollContainer = defineAsyncComponent(() => import('../CustomAutoScrollContainer.vue'));
|
|
79
101
|
|
|
@@ -114,6 +136,10 @@ let updateSpacerFrameId: number | null = null;
|
|
|
114
136
|
let pendingSpacerUpdate: Promise<void> | null = null;
|
|
115
137
|
let spacerUpdateQueued = false;
|
|
116
138
|
|
|
139
|
+
const showAnimationInScrollToBottomButton = computed(() => {
|
|
140
|
+
return agentStore.isResponseInProgress && showScrollToBottomButton.value;
|
|
141
|
+
});
|
|
142
|
+
|
|
117
143
|
onMounted(async () => {
|
|
118
144
|
messageResizeObserver = new ResizeObserver(() => {
|
|
119
145
|
scheduleSpacerHeightUpdate();
|
|
@@ -225,11 +251,11 @@ function scheduleSpacerHeightUpdate() {
|
|
|
225
251
|
pendingSpacerUpdate = null;
|
|
226
252
|
|
|
227
253
|
// Auto-scroll to bottom if response generation is in progress
|
|
228
|
-
if (agentStore.isResponseInProgress) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
254
|
+
// if (agentStore.isResponseInProgress) {
|
|
255
|
+
// nextTick(() => {
|
|
256
|
+
// scrollContainer.value?.scrollToBottom();
|
|
257
|
+
// });
|
|
258
|
+
// }
|
|
233
259
|
|
|
234
260
|
if (spacerUpdateQueued) {
|
|
235
261
|
scheduleSpacerHeightUpdate();
|
|
@@ -12,18 +12,18 @@
|
|
|
12
12
|
|
|
13
13
|
.bounce-dot2 {
|
|
14
14
|
animation: bounce 1.5s infinite;
|
|
15
|
-
animation-delay: 0.
|
|
15
|
+
animation-delay: 0.2s;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
.bounce-dot3 {
|
|
19
19
|
animation: bounce 1.5s infinite;
|
|
20
|
-
animation-delay: 0.
|
|
20
|
+
animation-delay: 0.4s;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
@keyframes bounce {
|
|
24
24
|
0%, 100% {
|
|
25
25
|
transform: translateY(20%);
|
|
26
|
-
opacity: 0.
|
|
26
|
+
opacity: 0.4;
|
|
27
27
|
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
|
28
28
|
}
|
|
29
29
|
50% {
|