fix: support mouse dragging on home channel bar

This commit is contained in:
hajimi
2026-08-02 00:55:45 +08:00
parent 41aeaa5163
commit 8593958283
+49 -1
View File
@@ -14,7 +14,10 @@
</view>
<view class="channel-bar">
<scroll-view scroll-x class="channel-bar__scroll" show-scrollbar="false">
<scroll-view scroll-x class="channel-bar__scroll"
:class="{ 'channel-bar__scroll--dragging': channelDragging }" :scroll-left="channelScrollLeft"
show-scrollbar="false" @scroll="handleChannelScroll" @mousedown="startChannelDrag"
@mousemove="moveChannelDrag" @mouseup="endChannelDrag" @mouseleave="endChannelDrag">
<view class="channel-bar__list">
<view v-for="item in primaryChannels" :key="item.channelKey" class="channel-bar__item"
:class="{ 'channel-bar__item--active': currentChannel === item.index }" @tap="switchChannel(item.index)">
@@ -177,6 +180,12 @@ const loading = ref(false)
const noMore = ref(false)
const pageNo = ref(1)
const pageSize = 10
const channelScrollLeft = ref(0)
const channelDragging = ref(false)
let channelDragStartX = 0
let channelDragStartScrollLeft = 0
let channelDragMoved = false
let channelDragBlockedUntil = 0
const primaryChannels = computed(() => {
return allChannels.value
@@ -241,7 +250,40 @@ const loadFocusMatches = async () => {
}
}
const handleChannelScroll = (event: any) => {
const nextScrollLeft = Number(event?.detail?.scrollLeft ?? event?.target?.scrollLeft ?? 0)
if (Number.isFinite(nextScrollLeft)) {
channelScrollLeft.value = nextScrollLeft
}
}
const startChannelDrag = (event: any) => {
if (typeof event?.button === 'number' && event.button !== 0) return
channelDragging.value = true
channelDragMoved = false
channelDragStartX = Number(event?.clientX ?? 0)
channelDragStartScrollLeft = channelScrollLeft.value
}
const moveChannelDrag = (event: any) => {
if (!channelDragging.value) return
const offsetX = Number(event?.clientX ?? channelDragStartX) - channelDragStartX
if (Math.abs(offsetX) < 3) return
channelDragMoved = true
event?.preventDefault?.()
channelScrollLeft.value = Math.max(0, channelDragStartScrollLeft - offsetX)
}
const endChannelDrag = () => {
if (!channelDragging.value) return
channelDragging.value = false
if (channelDragMoved) {
channelDragBlockedUntil = Date.now() + 250
}
}
const switchChannel = (index: number) => {
if (Date.now() < channelDragBlockedUntil) return
if (currentChannel.value === index) return
currentChannel.value = index
reloadFeed()
@@ -494,6 +536,12 @@ onUnload(() => uni.$off('channelChanged', onChannelChanged))
min-width: 0;
height: 86rpx;
white-space: nowrap;
cursor: grab;
user-select: none;
&--dragging {
cursor: grabbing;
}
}
&__list {