fix some bugs

This commit is contained in:
2026-06-27 13:49:00 +03:30
parent c3b47e33e1
commit 4d004c3515
13 changed files with 331 additions and 57 deletions
+93 -16
View File
@@ -2,7 +2,7 @@
<div
ref="headerRef"
class="app-header px-4 py-2 top-0 z-30 wrap-fix background-color-transition"
:class="{ 'app-header--scrolled': scrollY > 50 }"
:class="{ 'app-header--scrolled': isHeaderScrolled }"
>
<div class="flex justify-between my-2 items-center">
<div v-if="isBoursecuProject()" class="flex items-center gap-2">
@@ -40,47 +40,126 @@
</template>
<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { useUserStore } from '@/store/userStore'
import router from '@/router'
import Icon from '@/components/BasicPacks/BasicIcon.vue'
import { getProjectMobileNavLogo, isBoursecuProject } from '@/utils/config'
const headerRef = ref<HTMLElement | null>(null)
const scrollY = ref(0)
const isHeaderScrolled = ref(false)
const userStore = useUserStore()
const projectLogo = computed(() => getProjectMobileNavLogo())
let intersectionObserver: IntersectionObserver | null = null
let scrollTarget: HTMLElement | Window | null = null
function isScrollableOverflow(value: string) {
return value === 'auto' || value === 'scroll' || value === 'overlay'
}
function findScrollParent(el: HTMLElement | null): HTMLElement | null {
let node = el?.parentElement ?? null
while (node) {
const { overflowY } = getComputedStyle(node)
if (overflowY === 'auto' || overflowY === 'scroll') {
const style = getComputedStyle(node)
const overflowY = style.overflowY
const overflow = style.overflow
if (isScrollableOverflow(overflowY) || isScrollableOverflow(overflow)) {
return node
}
node = node.parentElement
}
return null
}
function updateScrollY() {
if (!scrollTarget) return
scrollY.value = scrollTarget instanceof Window ? scrollTarget.scrollY : scrollTarget.scrollTop
function resolveScrollRoot(): HTMLElement | null {
const header = headerRef.value
if (!header) return null
const chromeInner = header.closest('.main-with-bottom-chrome-inner')
if (chromeInner instanceof HTMLElement) {
return chromeInner
}
const fromParent = findScrollParent(header)
if (fromParent) {
return fromParent
}
const global = document.querySelector('.main-with-bottom-chrome-inner')
return global instanceof HTMLElement ? global : null
}
onMounted(() => {
scrollTarget = findScrollParent(headerRef.value) ?? window
scrollTarget.addEventListener('scroll', updateScrollY, { passive: true })
updateScrollY()
function resolveScrollSentinel(scrollRoot: HTMLElement | null): HTMLElement | null {
if (!scrollRoot) return null
const local = scrollRoot.querySelector('.app-header-scroll-sentinel')
if (local instanceof HTMLElement) {
return local
}
return null
}
function updateScrollStateFromPosition() {
if (!scrollTarget) return
const next =
scrollTarget instanceof Window
? scrollTarget.scrollY > 50
: scrollTarget.scrollTop > 50
isHeaderScrolled.value = next
}
function teardownScrollTracking() {
intersectionObserver?.disconnect()
intersectionObserver = null
scrollTarget?.removeEventListener('scroll', updateScrollStateFromPosition)
scrollTarget = null
}
function setupScrollTracking() {
teardownScrollTracking()
const scrollRoot = resolveScrollRoot()
const sentinel = resolveScrollSentinel(scrollRoot)
if (scrollRoot && sentinel && typeof IntersectionObserver !== 'undefined') {
intersectionObserver = new IntersectionObserver(
([entry]) => {
isHeaderScrolled.value = !entry?.isIntersecting
},
{
root: scrollRoot,
threshold: 0,
rootMargin: '-1px 0px 0px 0px',
},
)
intersectionObserver.observe(sentinel)
return
}
scrollTarget = scrollRoot ?? window
scrollTarget.addEventListener('scroll', updateScrollStateFromPosition, { passive: true })
updateScrollStateFromPosition()
}
onMounted(async () => {
setupScrollTracking()
await nextTick()
setupScrollTracking()
requestAnimationFrame(() => setupScrollTracking())
})
onUnmounted(() => {
scrollTarget?.removeEventListener('scroll', updateScrollY)
teardownScrollTracking()
})
defineEmits<{
@@ -93,10 +172,8 @@ defineEmits<{
background-color: transparent;
}
/* عین bg-white shadow opacity-95 قبلی */
.app-header--scrolled {
background-color: #fff;
opacity: 0.95;
background-color: rgba(255, 255, 255, 0.92);
box-shadow:
0 1px 3px 0 rgb(0 0 0 / 0.1),
0 1px 2px -1px rgb(0 0 0 / 0.1);
@@ -3,7 +3,7 @@
class="w-full flex justify-evenly rounded-lg py-2 home_appear_fade_in"
:class="[
isBoursecuLayout ? 'mt-8 pt-2' : 'mt-6',
variant === 'mobile' ? 'pb-45' : 'mt-0 pb-0',
variant === 'mobile' ? 'pb-20' : 'mt-0 pb-0',
]"
>
<div class="text-center w-full">
+1 -1
View File
@@ -356,7 +356,7 @@
</div>
</div>
</div>
<div class=" w-full flex justify-evenly rounded-lg py-2 home_appear_fade_in mt-6 pb-45">
<div class=" w-full flex justify-evenly rounded-lg py-2 home_appear_fade_in mt-6 pb-20">
<div class="text-center w-full">
<div>بالاترین قیمت امروز</div>
<div v-if="lastPrice" class="flex flex-col items-center mt-3">
+14 -1
View File
@@ -1,5 +1,6 @@
<template>
<div class="mt-10 p-5">
<div class="mt-10 p-5 home-mobile-root">
<div class="app-header-scroll-sentinel" aria-hidden="true" />
<component :is="layoutComponent" :layout-config="layoutConfig" />
<AppHeader @logout="$emit('logout')" />
</div>
@@ -21,3 +22,15 @@ defineEmits<{
const layoutComponent = computed(() => resolveHomeLayoutComponent())
const layoutConfig = computed(() => getHomeLayoutConfig(getHomeLayoutId()))
</script>
<style scoped>
.home-mobile-root {
position: relative;
}
.app-header-scroll-sentinel {
height: 1px;
width: 100%;
pointer-events: none;
}
</style>