mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-08-22 00:42:04 +08:00
fix(glass): support pointer input in Safari (#599)
This commit is contained in:
@@ -263,6 +263,37 @@ describe('glass optical surface discovery', () => {
|
||||
scope.stop()
|
||||
})
|
||||
|
||||
it('routes desktop pointer input when the browser does not expose TouchEvent', () => {
|
||||
vi.stubGlobal('TouchEvent', undefined)
|
||||
const scrollListener = vi.fn()
|
||||
const scope = effectScope()
|
||||
scope.run(() => {
|
||||
const source = useGlassOpticalInteractionSource()
|
||||
source.subscribe('scroll', scrollListener)
|
||||
})
|
||||
|
||||
window.dispatchEvent(new MouseEvent('pointermove', { clientX: 400, clientY: 400 }))
|
||||
|
||||
expect(scrollListener).toHaveBeenCalledOnce()
|
||||
scope.stop()
|
||||
})
|
||||
|
||||
it('keeps touch ownership when the browser does not expose TouchEvent', () => {
|
||||
vi.stubGlobal('TouchEvent', undefined)
|
||||
const scrollListener = vi.fn()
|
||||
const scope = effectScope()
|
||||
scope.run(() => {
|
||||
const source = useGlassOpticalInteractionSource()
|
||||
source.subscribe('scroll', scrollListener)
|
||||
})
|
||||
|
||||
dispatchTouchEvent('touchstart', [{ clientX: 400, clientY: 400, identifier: 7 }])
|
||||
dispatchTouchEvent('touchmove', [{ clientX: 420, clientY: 420, identifier: 7 }])
|
||||
|
||||
expect(scrollListener).toHaveBeenCalledTimes(2)
|
||||
scope.stop()
|
||||
})
|
||||
|
||||
it('detects a target surface added directly', () => {
|
||||
const surface = document.createElement('section')
|
||||
surface.dataset.glassOpticalSurface = ''
|
||||
|
||||
@@ -193,15 +193,17 @@ export function useGlassOpticalInteractionSource(): GlassOpticalInteractionSourc
|
||||
return touchOwners.get(changedTouch.identifier) ?? null
|
||||
}
|
||||
|
||||
const isTouchInteractionEvent = (event: PointerEvent | TouchEvent): event is TouchEvent =>
|
||||
event.type.startsWith('touch')
|
||||
|
||||
const dispatch = (event: PointerEvent | TouchEvent) => {
|
||||
const owner =
|
||||
event instanceof TouchEvent
|
||||
? resolveTouchOwner(event)
|
||||
: resolvePointOwner((event as PointerEvent).clientX, (event as PointerEvent).clientY)
|
||||
const owner = isTouchInteractionEvent(event)
|
||||
? resolveTouchOwner(event)
|
||||
: resolvePointOwner(event.clientX, event.clientY)
|
||||
if (!owner) return
|
||||
|
||||
for (const listener of listeners[owner]) listener(event)
|
||||
if (event instanceof TouchEvent && (event.type === 'touchend' || event.type === 'touchcancel')) {
|
||||
if (isTouchInteractionEvent(event) && (event.type === 'touchend' || event.type === 'touchcancel')) {
|
||||
for (const touch of Array.from(event.changedTouches)) touchOwners.delete(touch.identifier)
|
||||
}
|
||||
}
|
||||
@@ -1901,8 +1903,7 @@ export function useGlassOpticalRenderer(options: UseGlassOpticalRendererOptions)
|
||||
? candidates.findIndex(candidate => candidate.key === activeInteractionClip)
|
||||
: -1
|
||||
if (activeIndex > 0) candidates.unshift(...candidates.splice(activeIndex, 1))
|
||||
const maxCount =
|
||||
window.innerWidth <= 600 ? GLASS_OPTICAL_MAX_SURFACES_MOBILE : GLASS_OPTICAL_MAX_SURFACES_DESKTOP
|
||||
const maxCount = window.innerWidth <= 600 ? GLASS_OPTICAL_MAX_SURFACES_MOBILE : GLASS_OPTICAL_MAX_SURFACES_DESKTOP
|
||||
interactionClips = candidates.slice(0, maxCount)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user