From cec2438f6a9c75a8a1dda1f52d813343d53db82a Mon Sep 17 00:00:00 2001 From: Samuel Newman <10959775+mozzius@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:57:09 +0100 Subject: [PATCH] click to steal active video --- .../util/post-embeds/ActiveVideoContext.tsx | 36 +++++++++++++++++-- src/view/com/util/post-embeds/VideoEmbed.tsx | 6 +++- .../com/util/post-embeds/VideoEmbed.web.tsx | 6 +++- .../com/util/post-embeds/VideoEmbedInner.tsx | 6 +++- .../util/post-embeds/VideoEmbedInner.web.tsx | 30 ++++++++++++++-- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/view/com/util/post-embeds/ActiveVideoContext.tsx b/src/view/com/util/post-embeds/ActiveVideoContext.tsx index 212b1bcd57..ddf4fa6615 100644 --- a/src/view/com/util/post-embeds/ActiveVideoContext.tsx +++ b/src/view/com/util/post-embeds/ActiveVideoContext.tsx @@ -22,6 +22,7 @@ const ActiveVideoContext = React.createContext<{ export function ActiveVideoProvider({children}: {children: React.ReactNode}) { const [activeViewId, setActiveViewId] = useState(null) const [source, setSource] = useState(null) + const [manuallySet, setManuallySet] = useState(false) const {height: windowHeight} = useWindowDimensions() const measurementCallbacks = useRef DOMRect | void>>({}) @@ -46,7 +47,37 @@ export function ActiveVideoProvider({children}: {children: React.ReactNode}) { const active = closestToMiddle(windowHeight, videosInView) if (active) { - setActiveViewId(active.id) + // change the active view if it's not already active + // if the user has manually set the active view, don't change it + // i.e. if the user clicks on a video at the bottom of the screen + // it takes precidence over the video that is closest to the middle + setActiveViewId(activeView => { + if (activeView !== active.id) { + if (manuallySet && videosInView.find(({id}) => id === activeView)) { + return activeView + } + setManuallySet(false) + return active.id + } + return activeView + }) + } else { + // if no videos are in view, unset the active view + // if the active view is partially in view, keep it active + setActiveViewId(activeView => { + const activeRect = locations.find(({id}) => id === activeView)?.rect + + if (activeRect) { + const topCond = activeRect.top + activeRect.height / 2 >= 0 + const bottomCond = + activeRect.bottom - activeRect.height / 2 <= windowHeight + if (topCond && bottomCond) { + return activeView + } + } + + return null + }) } } findAndActivateVideo() @@ -55,7 +86,7 @@ export function ActiveVideoProvider({children}: {children: React.ReactNode}) { return () => { clearInterval(interval) } - }, [activeViewId, windowHeight]) + }, [manuallySet, windowHeight]) const value = useMemo( () => ({ @@ -63,6 +94,7 @@ export function ActiveVideoProvider({children}: {children: React.ReactNode}) { setActiveView: (viewId: string, src: string) => { setActiveViewId(viewId) setSource(src) + setManuallySet(true) }, registerMeasurementCallback: (viewId: string, callback: () => void) => { measurementCallbacks.current[viewId] = callback diff --git a/src/view/com/util/post-embeds/VideoEmbed.tsx b/src/view/com/util/post-embeds/VideoEmbed.tsx index 44be475543..884fd38dfa 100644 --- a/src/view/com/util/post-embeds/VideoEmbed.tsx +++ b/src/view/com/util/post-embeds/VideoEmbed.tsx @@ -27,7 +27,11 @@ export function VideoEmbed({source}: {source: string}) { a.my_xs, ]}> {active ? ( - + ) : (