fix: support mouse dragging on home channel bar
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user