From b8dbb71781997c9b8d595e7760f99b30a5e199e5 Mon Sep 17 00:00:00 2001
From: dan <dan.abramov@gmail.com>
Date: Thu, 22 Aug 2024 23:27:33 +0100
Subject: Fix fixed footer experiment (#4969)

* Split minimal shell mode into headerMode and footerMode

For now, we'll always write them in sync. When we read them, we'll use headerMode as source of truth. This will let us keep footerMode independent in a future commit.

* Remove fixed_bottom_bar special cases during calculation

This isn't the right time to determine special behavior. Instead we'll adjust footerMode itself conditionally on the gate.

* Copy-paste setMode into MainScrollProvider

This lets us fork the implementation later just for this case.

* Gate footer adjustment in MainScrollProvider

This is the final piece. Normal calls to setMode() keep setting both header and footer, but MainScrollProvider adjusts the footer conditionally.
---
 src/state/shell/minimal-mode.tsx | 43 ++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

(limited to 'src/state/shell/minimal-mode.tsx')

diff --git a/src/state/shell/minimal-mode.tsx b/src/state/shell/minimal-mode.tsx
index 69ce13062..9230339dd 100644
--- a/src/state/shell/minimal-mode.tsx
+++ b/src/state/shell/minimal-mode.tsx
@@ -6,32 +6,55 @@ import {
   withSpring,
 } from 'react-native-reanimated'
 
-type StateContext = SharedValue<number>
+type StateContext = {
+  headerMode: SharedValue<number>
+  footerMode: SharedValue<number>
+}
 type SetContext = (v: boolean) => void
 
 const stateContext = React.createContext<StateContext>({
-  value: 0,
-  addListener() {},
-  removeListener() {},
-  modify() {},
+  headerMode: {
+    value: 0,
+    addListener() {},
+    removeListener() {},
+    modify() {},
+  },
+  footerMode: {
+    value: 0,
+    addListener() {},
+    removeListener() {},
+    modify() {},
+  },
 })
 const setContext = React.createContext<SetContext>((_: boolean) => {})
 
 export function Provider({children}: React.PropsWithChildren<{}>) {
-  const mode = useSharedValue(0)
+  const headerMode = useSharedValue(0)
+  const footerMode = useSharedValue(0)
   const setMode = React.useCallback(
     (v: boolean) => {
       'worklet'
       // Cancel any existing animation
-      cancelAnimation(mode)
-      mode.value = withSpring(v ? 1 : 0, {
+      cancelAnimation(headerMode)
+      headerMode.value = withSpring(v ? 1 : 0, {
+        overshootClamping: true,
+      })
+      cancelAnimation(footerMode)
+      footerMode.value = withSpring(v ? 1 : 0, {
         overshootClamping: true,
       })
     },
-    [mode],
+    [headerMode, footerMode],
+  )
+  const value = React.useMemo(
+    () => ({
+      headerMode,
+      footerMode,
+    }),
+    [headerMode, footerMode],
   )
   return (
-    <stateContext.Provider value={mode}>
+    <stateContext.Provider value={value}>
       <setContext.Provider value={setMode}>{children}</setContext.Provider>
     </stateContext.Provider>
   )
-- 
cgit 1.4.1

