Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions custom/ChatSurface.vue
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ import { IconChatBubbleLeft20Solid, IconSparklesSolid, IconArrowsPointingOut, Ic
import { IconCloseOutline, IconBarsOutline, IconArrowUpOutline, IconCloseSidebarSolid, IconOpenSidebarSolid, IconAngleDownOutline } from '@iconify-prerendered/vue-flowbite';
import { useTemplateRef, onMounted, ref,computed } from 'vue';
import { onClickOutside } from '@vueuse/core'
import ConversationArea from './ConversationArea.vue';
import ConversationArea from './conversation_area/ConversationArea.vue';
import { useAgentStore } from './composables/useAgentStore';
import { useAgentTransitions } from './composables/useAgentTransitions';
import { Button } from '@/afcl';
Expand Down Expand Up @@ -246,7 +246,7 @@ onMounted(async () => {
agentStore.setAvailableModes(props.meta.modes, props.meta.defaultModeName);
agentStore.regisrerTextInput(textInput.value);
textInput.value?.focus();
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true';
const isTeleportedToBodyFromLocalStorage = agentStore.getLocalStorageItem('isTeleportedToBody') === 'true' || agentStore.getLocalStorageItem('isTeleportedToBodyBeforeFullScreen') === 'true';
if( coreStore.isMobile ) {
agentStore.setIsTeleportedToBody(false);
} else {
Expand Down
198 changes: 0 additions & 198 deletions custom/ConversationArea.vue

This file was deleted.

127 changes: 127 additions & 0 deletions custom/CustomAutoScrollContainer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted, nextTick } from 'vue'
import vueCustomScrollbar from 'vue-custom-scrollbar'

const props = withDefaults(defineProps<{
enabled?: boolean
threshold?: number
behavior?: ScrollBehavior
}>(), {
enabled: true,
threshold: 50,
behavior: 'instant'
})

const containerRef = ref<HTMLDivElement | null>(null)
const isUserScrolledUp = ref(false)

let lastScrollTop = 0
let lastScrollHeight = 0

function isNearBottom(): boolean {
const container = containerRef.value
if (!container) return true

const { scrollTop, scrollHeight, clientHeight } = container
return scrollHeight - scrollTop - clientHeight <= props.threshold
}

function scrollToBottom(force = false): void {
const container = containerRef.value
if (!container) return

if (isUserScrolledUp.value && !force) return

container.scrollTo({
top: container.scrollHeight,
behavior: props.behavior
})
}


function hasScrollbar(): boolean {
const container = containerRef.value
if (!container) return false
return container.scrollHeight > container.clientHeight
}


function handleScroll(): void {
const container = containerRef.value
if (!container) return

const { scrollTop, scrollHeight, clientHeight } = container

if (scrollHeight <= clientHeight) {
isUserScrolledUp.value = false
lastScrollTop = 0
lastScrollHeight = scrollHeight
return
}

if (isNearBottom()) {
isUserScrolledUp.value = false
} else {
const isScrollingUp = scrollTop < lastScrollTop
const isContentUnchanged = scrollHeight === lastScrollHeight

if (isScrollingUp && isContentUnchanged) {
isUserScrolledUp.value = true
}
}

lastScrollTop = scrollTop
lastScrollHeight = scrollHeight
}

let observer: MutationObserver | null = null

onMounted(() => {
if (!containerRef.value) return

lastScrollTop = containerRef.value.scrollTop
lastScrollHeight = containerRef.value.scrollHeight

observer = new MutationObserver(() => {
nextTick(() => {
if (!containerRef.value) return

if (!hasScrollbar()) {
isUserScrolledUp.value = false
}

lastScrollHeight = containerRef.value.scrollHeight

if (props.enabled && !isUserScrolledUp.value) {
scrollToBottom()
}
})
})

observer.observe(containerRef.value, {
childList: true,
subtree: true,
characterData: true
})
})

onUnmounted(() => {
observer?.disconnect()
})

defineExpose({
scrollToBottom: () => scrollToBottom(true),
isUserScrolledUp: () => isUserScrolledUp.value,
container: containerRef
})
</script>

<template>
<div
ref="containerRef"
class="auto-scroll-container h-full"
@scroll="handleScroll"
>
<slot />
</div>
</template>
Loading