about summary refs log tree commit diff
path: root/src/view/com/util/forms/Button.tsx
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2023-09-20 11:03:57 -0500
committerEric Bailey <git@esb.lol>2023-09-20 11:03:57 -0500
commit5665968f729b99509d54769f494bbbfc59b4b630 (patch)
treebfad6f82b613699ba3f206d460f0eac50dee6bd4 /src/view/com/util/forms/Button.tsx
parent63527493fd8dfb72d21bd50cd2404a5cf2c6e274 (diff)
parentcd96f8dcc8692aec4b9b165cc9f47d7e0b6257df (diff)
downloadvoidsky-5665968f729b99509d54769f494bbbfc59b4b630.tar.zst
Merge remote-tracking branch 'origin' into bnewbold/bump-api-dep
* origin:
  Allow touch at the top of the lightbox (#1489)
  Bump ios build number
  Feeds tab fixes (#1486)
  Nicer 'post processing status' in the composer (#1472)
  Inline createPanResponder (#1483)
  Tree view threads experiment (#1480)
  Make "double tap to zoom" precise across platforms (#1482)
  Onboarding recommended follows (#1457)
  Add thread sort settings (#1475)
Diffstat (limited to 'src/view/com/util/forms/Button.tsx')
-rw-r--r--src/view/com/util/forms/Button.tsx45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/view/com/util/forms/Button.tsx b/src/view/com/util/forms/Button.tsx
index 8049d2243..076fa1baa 100644
--- a/src/view/com/util/forms/Button.tsx
+++ b/src/view/com/util/forms/Button.tsx
@@ -7,6 +7,8 @@ import {
   Pressable,
   ViewStyle,
   PressableStateCallbackType,
+  ActivityIndicator,
+  View,
 } from 'react-native'
 import {Text} from '../text/Text'
 import {useTheme} from 'lib/ThemeContext'
@@ -48,17 +50,19 @@ export function Button({
   accessibilityHint,
   accessibilityLabelledBy,
   onAccessibilityEscape,
+  withLoading = false,
 }: React.PropsWithChildren<{
   type?: ButtonType
   label?: string
   style?: StyleProp<ViewStyle>
   labelStyle?: StyleProp<TextStyle>
-  onPress?: () => void
+  onPress?: () => void | Promise<void>
   testID?: string
   accessibilityLabel?: string
   accessibilityHint?: string
   accessibilityLabelledBy?: string
   onAccessibilityEscape?: () => void
+  withLoading?: boolean
 }>) {
   const theme = useTheme()
   const typeOuterStyle = choose<ViewStyle, Record<ButtonType, ViewStyle>>(
@@ -138,13 +142,16 @@ export function Button({
     },
   )
 
+  const [isLoading, setIsLoading] = React.useState(false)
   const onPressWrapped = React.useCallback(
-    (event: Event) => {
+    async (event: Event) => {
       event.stopPropagation()
       event.preventDefault()
-      onPress?.()
+      withLoading && setIsLoading(true)
+      await onPress?.()
+      withLoading && setIsLoading(false)
     },
-    [onPress],
+    [onPress, withLoading],
   )
 
   const getStyle = React.useCallback(
@@ -160,23 +167,35 @@ export function Button({
     [typeOuterStyle, style],
   )
 
+  const renderChildern = React.useCallback(() => {
+    if (!label) {
+      return children
+    }
+
+    return (
+      <View style={styles.labelContainer}>
+        {label && withLoading && isLoading ? (
+          <ActivityIndicator size={12} color={typeLabelStyle.color} />
+        ) : null}
+        <Text type="button" style={[typeLabelStyle, labelStyle]}>
+          {label}
+        </Text>
+      </View>
+    )
+  }, [children, label, withLoading, isLoading, typeLabelStyle, labelStyle])
+
   return (
     <Pressable
       style={getStyle}
       onPress={onPressWrapped}
+      disabled={isLoading}
       testID={testID}
       accessibilityRole="button"
       accessibilityLabel={accessibilityLabel}
       accessibilityHint={accessibilityHint}
       accessibilityLabelledBy={accessibilityLabelledBy}
       onAccessibilityEscape={onAccessibilityEscape}>
-      {label ? (
-        <Text type="button" style={[typeLabelStyle, labelStyle]}>
-          {label}
-        </Text>
-      ) : (
-        children
-      )}
+      {renderChildern}
     </Pressable>
   )
 }
@@ -187,4 +206,8 @@ const styles = StyleSheet.create({
     paddingVertical: 8,
     borderRadius: 24,
   },
+  labelContainer: {
+    flexDirection: 'row',
+    gap: 8,
+  },
 })