react-native#Keyboard TypeScript Examples

The following examples show how to use react-native#Keyboard. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: machine.context.ts    From companion-kit with MIT License 6 votes vote down vote up
initKeyboardEvents() {
        Keyboard.addListener(
            'keyboardDidHide',
            event => this._keyboardProps = { ...event.endCoordinates, isOpened: false },
        );
        Keyboard.addListener(
            'keyboardDidShow',
            event => this._keyboardProps = { ...event.endCoordinates, isOpened: true },
        );
    }
Example #2
Source File: AddKey.tsx    From hive-keychain-mobile with MIT License 6 votes vote down vote up
AddKey = ({addKey, name, type}: Props) => {
  console.log(name, type);
  const [key, setKey] = useState('');
  return (
    <Operation
      title={translate('settings.keys.add')}
      logo={<KeychainLogo width={40} />}>
      <>
        <Separator />
        <OperationInput
          placeholder={translate('common.privateKey').toUpperCase()}
          leftIcon={<KeyIcon />}
          autoCapitalize="none"
          value={key}
          onChangeText={setKey}
        />

        <Separator height={40} />
        <EllipticButton
          title={translate('common.save')}
          onPress={() => {
            console.log('key', key);
            addKey(name, type, key);
            Keyboard.dismiss();
            goBack();
          }}
          style={styles.button}
        />
      </>
    </Operation>
  );
}
Example #3
Source File: KeyboardEvents.ts    From nyxo-app with GNU General Public License v3.0 6 votes vote down vote up
useKeyboardEvents = ({
  handleKeyboardWillShow,
  handleKeyboardDidShow,
  handleKeyboardDidHide,
  handleKeyboardWillHide
}: Params): void => {
  const isAndroid = Platform.OS === 'android'
  useEffect(() => {
    if (isAndroid) {
      handleKeyboardDidShow &&
        Keyboard.addListener('keyboardDidShow', handleKeyboardDidShow)
      handleKeyboardDidHide &&
        Keyboard.addListener('keyboardDidHide', handleKeyboardDidHide)
    } else {
      handleKeyboardWillShow &&
        Keyboard.addListener('keyboardWillShow', handleKeyboardWillShow)
      handleKeyboardWillHide &&
        Keyboard.addListener('keyboardWillHide', handleKeyboardWillHide)
    }

    return () => {
      handleKeyboardDidShow &&
        Keyboard.removeListener('keyboardDidShow', handleKeyboardDidShow)
      handleKeyboardDidHide &&
        Keyboard.removeListener('keyboardDidHide', handleKeyboardDidHide)
      handleKeyboardWillShow &&
        Keyboard.removeListener('keyboardWillShow', handleKeyboardWillShow)
      handleKeyboardWillHide &&
        Keyboard.removeListener('keyboardWillHide', handleKeyboardWillHide)
    }
  }, [
    handleKeyboardDidHide,
    handleKeyboardDidShow,
    handleKeyboardWillHide,
    handleKeyboardWillShow,
    isAndroid
  ])
}
Example #4
Source File: KeyboardManager.tsx    From nlw2-proffy with MIT License 6 votes vote down vote up
private handlePageChangeConfirm = () => {
    if (!this.props.enabled) {
      return;
    }

    this.clearKeyboardTimeout();

    const input = this.previouslyFocusedTextInput;

    if (Platform.OS === 'android') {
      Keyboard.dismiss();
    } else if (input) {
      TextInput.State.blurTextInput(input);
    }

    // Cleanup the ID on successful page change
    this.previouslyFocusedTextInput = null;
  };
Example #5
Source File: useKeyboardDidShow.ts    From react-native-crypto-wallet-app with MIT License 6 votes vote down vote up
useKeyboardDidShow = () => {
  const [keyboardDidShow, setKeyboardDidShow] = useState<boolean>(false);

  useEffect(() => {
    Keyboard.addListener('keyboardDidShow', _onKeyboardDidShow);
    Keyboard.addListener('keyboardDidHide', _onKeyboardDidHide);

    return () => {
      Keyboard.removeListener('keyboardDidShow', _onKeyboardDidShow);
      Keyboard.removeListener('keyboardDidHide', _onKeyboardDidHide);
    };
  }, []);

  const _onKeyboardDidShow = () => {
    setKeyboardDidShow(true);
  };

  const _onKeyboardDidHide = () => {
    setKeyboardDidShow(false);
  };

  return keyboardDidShow;
}
Example #6
Source File: PickLeaveRequestDaysCalendar.tsx    From orangehrm-os-mobile with GNU General Public License v3.0 6 votes vote down vote up
componentDidMount() {
    if (this.props.holidays === undefined) {
      this.props.fetchHolidays();
    }
    if (this.props.workWeek === undefined) {
      this.props.fetchWorkWeek();
    }
    this.props.setPickedState('pickedLeaveDates', false);
    Keyboard.dismiss();
  }
Example #7
Source File: index.tsx    From react-native-bottomsheet-reanimated with MIT License 6 votes vote down vote up
useKeyboard = (isEnable = true): [number] => {
  const showSubscription = useRef<EmitterSubscription>();
  const hideSubscription = useRef<EmitterSubscription>();
  const [keyboardHeight, setKeyboardHeight] = useState(0);

  function onKeyboardWillShow(e: KeyboardEvent): void {
    setKeyboardHeight(e.endCoordinates.height);
  }

  function onKeyboardWillHide(): void {
    setKeyboardHeight(0);
  }

  useEffect(() => {
    if (isEnable) {
      const keyboardShowEvent =
        Platform.OS === 'android' ? 'keyboardDidShow' : 'keyboardWillShow';
      const keyboardHideEvent =
        Platform.OS === 'android' ? 'keyboardDidHide' : 'keyboardWillHide';
      showSubscription.current = Keyboard.addListener(
        keyboardShowEvent,
        onKeyboardWillShow
      );
      hideSubscription.current = Keyboard.addListener(
        keyboardHideEvent,
        onKeyboardWillHide
      );
    }
    return (): void => {
      showSubscription.current?.remove();
      hideSubscription.current?.remove();
    };
  }, [isEnable]);

  return [keyboardHeight];
}
Example #8
Source File: useKeyboardContentInset.ts    From vsinder with Apache License 2.0 6 votes vote down vote up
useKeyboardContentInset = (onKeyboardOpen?: () => void) => {
  const [keyboardHeight, setKeyboardHeight] = useState(0);
  const fn = useRef(() => {});
  if (onKeyboardOpen) {
    fn.current = onKeyboardOpen;
  }
  useEffect(() => {
    const x = Keyboard.addListener("keyboardDidShow", (e) => {
      setKeyboardHeight(e.endCoordinates.height);
      fn.current();
    });
    return () => {
      x.remove();
    };
  }, []);

  useEffect(() => {
    const x = Keyboard.addListener("keyboardDidHide", () => {
      setKeyboardHeight(0);
    });
    return () => {
      x.remove();
    };
  }, []);

  return { bottom: keyboardHeight };
}
Example #9
Source File: index.tsx    From react-native-actions-sheet with MIT License 6 votes vote down vote up
componentDidMount() {
    this.props.id && SheetManager.add(this.props.id);

    this.keyboardShowSubscription = Keyboard.addListener(
      Platform.OS === "android" ? "keyboardDidShow" : "keyboardWillShow",
      this._onKeyboardShow
    );

    this.KeyboardHideSubscription = Keyboard.addListener(
      Platform.OS === "android" ? "keyboardDidHide" : "keyboardWillHide",
      this._onKeyboardHide
    );
    if (this.props.id) {
      this.sheetManagerShowEvent = DeviceEventEmitter.addListener(
        `show_${this.props.id}`,
        this.onSheetManagerShow
      );
      this.sheetManagerHideEvent = DeviceEventEmitter.addListener(
        `hide_${this.props.id}`,
        this.onSheetMangerHide
      );
    }
  }
Example #10
Source File: useKeyboardHeight.ts    From jellyfin-audio-player with MIT License 6 votes vote down vote up
useKeyboardHeight = () => {
    const keyboardHeight = useRef(new Animated.Value(0)).current;
    const tabBarHeight = useBottomTabBarHeight();
    
    useEffect(() => {
        const keyboardWillShow = (e: KeyboardEvent) => {
            Animated.timing(keyboardHeight, {
                duration: e.duration,
                toValue: tabBarHeight - e.endCoordinates.height,
                useNativeDriver: true,
            }).start();
        };
        
        const keyboardWillHide = (e: KeyboardEvent) => {
            Animated.timing(keyboardHeight, {
                duration: e.duration,
                toValue: 0,
                useNativeDriver: true,
            }).start();
        };
        
        const keyboardWillShowSub = Keyboard.addListener(
            'keyboardWillShow',
            keyboardWillShow
        );
        const keyboardWillHideSub = Keyboard.addListener(
            'keyboardWillHide',
            keyboardWillHide
        );
        
        return () => {
            keyboardWillHideSub.remove();
            keyboardWillShowSub.remove();
        };
    }, [keyboardHeight, tabBarHeight]);
    
    return keyboardHeight;
}
Example #11
Source File: JoinScreen.tsx    From lets-fork-native with MIT License 6 votes vote down vote up
JoinScreen = React.memo((props: Props): React.ReactElement => {
  const { navigation, ws } = props
  const [value, setValue] = React.useState('')
  const headerHeight = useHeaderHeight()

  // joins an existing party
  const handleJoin = (): void => {
    if (value) {
      ws.send(JSON.stringify({ type: 'join', payload: { party_id: value } }))
      navigation.navigate('Party')
      Keyboard.dismiss()
    }
  }

  return (
    <KeyboardAvoidingView
      behavior="height"
      style={{
        ...styles.container,
        height: height - headerHeight,
      }}
    >
      <Text style={styles.text}>Please enter the party code</Text>
      <Input value={value} handleChange={setValue} keyboardType="phone-pad" />
      <Button size="sm" color="purple" onPress={(): void => handleJoin()}>
        JOIN
      </Button>
    </KeyboardAvoidingView>
  )
})
Example #12
Source File: keyboardListener.ts    From sellflow with MIT License 6 votes vote down vote up
export function useKeyboardListener(keyboardVerticalOffset = 0) {
  let keyboardHeight = useMemo(() => new Animated.Value(0), []);
  useEffect(() => {
    let keyboardWillShow = Keyboard.addListener('keyboardWillShow', (event) => {
      Animated.timing(keyboardHeight, {
        duration: event.duration,
        toValue: event.endCoordinates.height + keyboardVerticalOffset,
        useNativeDriver: true,
      }).start();
    });
    let keyboardWillHide = Keyboard.addListener('keyboardWillHide', (event) => {
      Animated.timing(keyboardHeight, {
        duration: event.duration,
        toValue: 0,
        useNativeDriver: true,
      }).start();
    });

    return () => {
      keyboardWillShow.remove();
      keyboardWillHide.remove();
    };
  }, [keyboardHeight, keyboardVerticalOffset]);

  return { keyboardHeight };
}
Example #13
Source File: passwordBase.tsx    From companion-kit with MIT License 6 votes vote down vote up
protected forgotPassword = () => this.runLongOperation(async () => {
        Keyboard.dismiss();

        const result: boolean | { result: boolean } | 'noInvitation' = await this.viewModel.forgotPassword();

        if (!result) {
            return;
        }

        if (process.appFeatures.USE_MAGIC_LINK) {
            // show modal with magic link stuff
            await this.showModal(magicLinkModal(this, this.onGoBack, { title: 'Check your email for a password reset link' }));
            return;
        }

        this.trigger(ScenarioTriggers.Secondary);
    })
Example #14
Source File: BottomMenu.tsx    From lexicon with MIT License 5 votes vote down vote up
export function BottomMenu(props: Props) {
  const styles = useStyles();
  const { colors } = useTheme();

  const { onInsertImage, onInsertLink, showLeftMenu = true } = props;

  const ios = Platform.OS === 'ios';

  const onHideKeyboard = () => {
    Keyboard.dismiss();
  };

  return (
    <View style={styles.container}>
      {showLeftMenu && (
        <View style={styles.leftMenu}>
          <View style={styles.row}>
            <Icon
              name="Photo"
              size="l"
              color={colors.textLighter}
              onPress={onInsertImage}
              style={styles.iconButton}
            />
            <Divider vertical />
            <Icon
              name="Link"
              size="l"
              color={colors.textLighter}
              onPress={onInsertLink}
              style={styles.iconButton}
            />
            <Divider vertical />
          </View>
        </View>
      )}

      <View style={styles.rightMenu}>
        <View style={styles.row}>
          <Divider vertical />
          {ios && (
            <Icon
              name="KeyboardHide"
              size="l"
              color={colors.textLighter}
              onPress={onHideKeyboard}
              style={styles.iconButton}
            />
          )}
        </View>
      </View>
    </View>
  );
}
Example #15
Source File: Modal.tsx    From save-food with MIT License 5 votes vote down vote up
Modal = ({ toggleModal, visible, title, onModalHide, buttons = [], children }: Props) => {
	return (
		<ModalBase
			avoidKeyboard
			statusBarTranslucent
			useNativeDriver={Platform.OS === 'android'}
			useNativeDriverForBackdrop={Platform.OS === 'android'}
			isVisible={visible}
			deviceHeight={height + STATUS_BAR_HEIGHT}
			onModalWillHide={Keyboard.dismiss}
			onModalHide={onModalHide}
			onBackButtonPress={() => {
				Keyboard.dismiss()
				toggleModal()
			}}
			onBackdropPress={() => {
				Keyboard.dismiss()
				toggleModal()
			}}
		>
			<View style={styles.contentWrapper}>
				<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
					<View style={styles.header}>
						<Text style={styles.title}>{title}</Text>
					</View>
				</TouchableWithoutFeedback>

				<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
					<View style={styles.content}>{children}</View>
				</TouchableWithoutFeedback>

				{!!buttons?.length && (
					<View style={styles.buttons}>
						{buttons.map((item) => (
							<Button
								buttonStyle={[styles.button, { width: MODAL_WIDTH / buttons.length }]}
								titleStyle={styles.buttonText}
								key={item.text}
								onPress={item.onPress}
								title={item.text}
							/>
						))}
					</View>
				)}
			</View>
		</ModalBase>
	)
}
Example #16
Source File: ApplyLeave.tsx    From orangehrm-os-mobile with GNU General Public License v3.0 5 votes vote down vote up
componentDidMount() {
    this.updateEntitlements();
    Keyboard.addListener('keyboardDidHide', this.hideCommentInput);
  }
Example #17
Source File: index.tsx    From react-native-paper-toast with MIT License 5 votes vote down vote up
ToastProvider: React.FC<ToastProviderProps> = ({ children, overrides }) => {
  const initialState = useMemo(() => ({ ...defaults, ...overrides }), [overrides]);
  const [state, dispatch] = useReducer(reducer, initialState);

  const insets = useSafeAreaInsets();

  const toast = useMemo(
    () => ({
      show(options: ToastOptions) {
        const newState: ToastParams = { ...initialState, ...options, visibility: true };
        newState.position === 'bottom' && Keyboard.dismiss();
        dispatch({ type: ToastActionType.SHOW, payload: newState });
      },
      hide() {
        dispatch({ type: ToastActionType.HIDE });
      },
    }),
    [initialState]
  );

  const computedStyle = useMemo(() => {
    const base: StyleProp<ViewStyle> = {
      position: 'absolute',
      left: insets.left,
      right: insets.right,
      width: undefined,
      alignItems: 'center',
    };
    let style: StyleProp<ViewStyle>;
    if (state.position === 'bottom') {
      style = {
        ...base,
        bottom: insets.bottom,
      };
      return style;
    }
    if (state.position === 'top') {
      style = {
        ...base,
        top: insets.top,
        bottom: undefined,
      };
      return style;
    }
    style = {
      ...base,
      top: insets.top,
      bottom: insets.bottom,
      justifyContent: 'center',
    };
    return style;
  }, [insets, state.position]);

  useEffect(() => {
    dispatch({ type: ToastActionType.HYDRATE, payload: initialState });
  }, [initialState]);

  return (
    <ToastContext.Provider value={toast}>
      <Portal.Host>{children}</Portal.Host>
      <Portal>
        <Snackbar
          onDismiss={toast.hide}
          style={types[state.type]}
          wrapperStyle={computedStyle}
          duration={state.duration}
          visible={state.visibility}
          action={state.action ? { label: state.actionLabel, onPress: state.action } : undefined}
        >
          <Icon size={20} name={icons[state.type]} color="#ffffff" />
          <Text style={styles.message}>{` ${state.message}`}</Text>
        </Snackbar>
      </Portal>
    </ToastContext.Provider>
  );
}
Example #18
Source File: AssignLeave.tsx    From orangehrm-os-mobile with GNU General Public License v3.0 5 votes vote down vote up
componentDidMount() {
    this.updateSubordinateList();
    Keyboard.addListener('keyboardDidHide', this.onKeyboardHide);
  }
Example #19
Source File: useBackgroundOverlay.tsx    From react-native-template with MIT License 5 votes vote down vote up
function useBackgroundOverlay(visible: boolean, onTouchStart: () => void) {
  const isFirstRender = useRef(true)
  const opacity = useMemo(
    () =>
      isFirstRender.current
        ? 0
        : timing({
            from: visible ? 0 : 0.2,
            to: visible ? 0.2 : 0,
          }),
    [visible]
  )

  useEffect(() => {
    isFirstRender.current = false
  }, [])

  useFocusEffect(
    React.useCallback(() => {
      const onBackPress = () => {
        if (visible) {
          onTouchStart()
          return true
        } else {
          return false
        }
      }
      BackHandler.addEventListener("hardwareBackPress", onBackPress)

      return () =>
        BackHandler.removeEventListener("hardwareBackPress", onBackPress)
    }, [onTouchStart, visible])
  )

  return (
    <>
      {visible && <StatusBar backgroundColor="grey" animated />}
      <Animated.View
        pointerEvents={visible ? "auto" : "none"}
        onTouchStart={() => {
          Keyboard.dismiss()
          onTouchStart()
        }}
        style={[
          styles.overlay,
          {
            opacity,
          },
        ]}
      />
    </>
  )
}
Example #20
Source File: MasloPage.tsx    From companion-kit with MIT License 5 votes vote down vote up
function wrapWithKeyboardDismiss(cb: () => any) {
    return () => {
        Keyboard.dismiss();
        safeCall(cb);
    };
}
Example #21
Source File: PowerUp.tsx    From hive-keychain-mobile with MIT License 5 votes vote down vote up
PowerUp = ({currency = 'HIVE', user, loadAccount}: Props) => {
  const [to, setTo] = useState(user.account.name);
  const [amount, setAmount] = useState('');
  const [loading, setLoading] = useState(false);

  const onPowerUp = async () => {
    Keyboard.dismiss();
    setLoading(true);

    try {
      await powerUp(user.keys.active!, {
        amount: sanitizeAmount(amount, currency),
        to: sanitizeUsername(to),
        from: user.account.name,
      });
      loadAccount(user.account.name, true);
      goBack();
      Toast.show(translate('toast.powerup_success'), Toast.LONG);
    } catch (e) {
      Toast.show(`Error: ${(e as any).message}`, Toast.LONG);
    } finally {
      setLoading(false);
    }
  };
  const {color} = getCurrencyProperties(currency);
  const styles = getDimensionedStyles(color);
  return (
    <Operation
      logo={<Hp />}
      title={translate('wallet.operations.powerup.title')}>
      <>
        <Separator />
        <Balance
          currency={currency}
          account={user.account}
          setMax={(value: string) => {
            setAmount(value);
          }}
        />

        <Separator />
        <OperationInput
          placeholder={translate('common.username').toUpperCase()}
          leftIcon={<AccountLogoDark />}
          autoCapitalize="none"
          value={to}
          onChangeText={setTo}
        />
        <Separator />
        <OperationInput
          placeholder={'0.000'}
          keyboardType="decimal-pad"
          rightIcon={<Text style={styles.currency}>{currency}</Text>}
          textAlign="right"
          value={amount}
          onChangeText={setAmount}
        />

        <Separator height={40} />
        <ActiveOperationButton
          title={translate('common.send')}
          onPress={onPowerUp}
          style={styles.button}
          isLoading={loading}
        />
      </>
    </Operation>
  );
}
Example #22
Source File: InputAutocomplete.tsx    From react-native-paper-form-builder with MIT License 5 votes vote down vote up
function InputAutocomplete(props: InputAutocompleteProps) {
  const {
    formState,
    field,
    textInputProps,
    options,
    CustomAutoComplete,
    CustomTextInput,
  } = props;
  const theme = useTheme();
  const errorMessage = formState.errors?.[field.name]?.message;
  const textColor = errorMessage ? theme.colors.error : theme.colors.text;
  const [visible, setVisible] = useState(false);
  const AUTOCOMPLETE = CustomAutoComplete ?? AutoComplete;
  const INPUT = CustomTextInput ?? TextInput;

  const styles = useMemo(
    () =>
      StyleSheet.create({
        textInputStyle: {
          color: textColor,
        },
      }),
    [textColor],
  );

  return (
    <Fragment>
      <TouchableRipple
        onPress={() => {
          Keyboard.dismiss();
          setVisible(true);
        }}>
        <View pointerEvents={'none'}>
          <INPUT
            ref={field.ref}
            mode={'outlined'}
            error={errorMessage ? true : false}
            onFocus={() => {
              Keyboard.dismiss();
              setVisible(true);
            }}
            {...textInputProps}
            value={
              options.find(({value}) => `${value}` === `${field.value}`)?.label
            }
            style={[styles.textInputStyle, textInputProps?.style]}
          />
        </View>
      </TouchableRipple>
      <AUTOCOMPLETE
        visible={visible}
        setVisible={setVisible}
        options={options}
        field={field}
        textInputProps={textInputProps}
      />
      {errorMessage && <HelperText type={'error'}>{errorMessage}</HelperText>}
    </Fragment>
  );
}
Example #23
Source File: index.tsx    From react-native-bottomsheet-reanimated with MIT License 4 votes vote down vote up
Index = forwardRef(
  (
    {
      isBackDropDismissByPress,
      initialPosition = { y: 0 },
      onChangeSnap,
      onChangeKeyboardAwareSnap,
      snapPoints,
      bottomSheerColor = '#FFFFFF',
      backDropColor = '#000000',
      isRoundBorderWithTipHeader = false,
      tipHeaderRadius = 12,
      header,
      body,
      isBackDrop = false,
      isModal,
      dragEnabled = true,
      isAnimatedYFromParent,
      animatedValueY,
      containerStyle,
      bodyContainerStyle = {},
      tipStyle,
      headerStyle,
      bodyStyle,
      onClose,
      bounce = 0.5,
      keyboardAware = false,
      keyboardAwareExtraSnapHeight = 0,
      keyboardAwareDrag = false,
      overDrag = true,
    }: BottomSheetProps,
    ref
  ) => {
    const [keyboardHeight] = useKeyboard(keyboardAware);
    const [headerHeight, setHeaderHeight] = useState(0);
    const [currentSnap, setCurrentSnap] = useState(initialPosition);
    const currentNomalizeSnap = useMemo(() => normalize(currentSnap), [
      currentSnap,
    ]);
    const normalizeSnap = useMemo(() => getNormalizeSnaps(snapPoints), [
      snapPoints,
    ]);
    const [_deltaY] = useState(new Animated.Value(Screen.height));
    const bottomPanel = useRef<any>();
    const _snapPoints = useMemo(() => getSnapPoints(normalizeSnap), [
      normalizeSnap,
    ]);
    const boundaries = useMemo(
      () =>
        overDrag
          ? { top: isModal ? 0 : -300, bounce: bounce }
          : getOverDragBoundries(normalizeSnap),
      [overDrag, isModal, bounce, normalizeSnap]
    );
    const _initialPosition = useMemo(
      () => getInitialPosition(initialPosition),
      [initialPosition]
    );
    const isDismissWithPress = isBackDropDismissByPress
      ? isBackDropDismissByPress
      : false;
    const [
      isBottomSheetDismissed,
      setIsBottomSheetDismissed,
    ] = useState<boolean>(initialPosition === 0 || initialPosition === '0%');

    const onDrawerSnap = (snap: any) => {
      const index = snap.nativeEvent.index;
      const value = snapPoints[index];
      setCurrentSnap(value); //
      if (value === 0 || value === '0%') {
        setIsBottomSheetDismissed(true);
        onClose && onClose();
      } else {
        setIsBottomSheetDismissed(false);
      }
      onChangeSnap && onChangeSnap({ index, value });
    };

    const dismissBottomSheet = () => {
      let index = snapPoints.findIndex(
        (x: number | string) => x === 0 || x === '0%'
      );
      if (index !== -1) {
        bottomPanel.current.snapTo({ index });
        onClose && onClose();
      }
      Keyboard.dismiss();
    };

    const snapTo = (index: number) => {
      if (snapPoints.findIndex((x) => x === 0 || x === '0%') !== -1) {
        Keyboard.dismiss();
      }
      bottomPanel.current.snapTo({ index });
      const value = snapPoints[index];
      onChangeSnap && onChangeSnap({ index, value });
    };

    useImperativeHandle(ref, () => ({
      snapTo,
      dismissBottomSheet,
    }));

    useEffect(() => {
      if (keyboardAware) {
        const currentSnapHeight = normalize(currentSnap);
        if (keyboardHeight) {
          const newSnapHeight = currentSnapHeight + keyboardHeight;
          if (newSnapHeight > Screen.height) {
            bottomPanel.current.snapToPosition({
              x: 0,
              y: 0 - keyboardAwareExtraSnapHeight,
            });
            onChangeKeyboardAwareSnap &&
              onChangeKeyboardAwareSnap({
                previousSnap: currentSnapHeight,
                nextSnap: 0,
                keyboardHeight,
              });
          } else {
            bottomPanel.current.snapToPosition({
              x: 0,
              y: Screen.height - newSnapHeight - keyboardAwareExtraSnapHeight,
            });
            onChangeKeyboardAwareSnap &&
              onChangeKeyboardAwareSnap({
                previousSnap: currentSnapHeight,
                nextSnap: newSnapHeight,
                keyboardHeight,
              });
          }
        } else {
          bottomPanel.current.snapToPosition({
            x: 0,
            y: Screen.height - currentSnapHeight,
          });
        }
      }
    }, [keyboardHeight]);

    const dragHandler = () => {
      if (dragEnabled) {
        if (!keyboardAwareDrag && keyboardHeight > 0) {
          return false;
        } else {
          return true;
        }
      }
      return false;
    };

    return (
      <View style={styles.panelContainer} pointerEvents={'box-none'}>
        {/* Backdrop */}
        {isBackDrop && (
          <Animated.View
            pointerEvents={!isBottomSheetDismissed ? 'auto' : 'box-none'}
            style={[
              styles.panelContainer,
              {
                backgroundColor: backDropColor,
                opacity: isAnimatedYFromParent
                  ? animatedValueY.interpolate({
                      inputRange: [0, Screen.height - 100],
                      outputRange: [1, 0],
                      extrapolateRight: Extrapolate.CLAMP,
                    })
                  : _deltaY.interpolate({
                      inputRange: [0, Screen.height - 100],
                      outputRange: [1, 0],
                      extrapolateRight: Extrapolate.CLAMP,
                    }),
              },
            ]}
          />
        )}

        <Interactable.View
          dragEnabled={isModal ? false : dragHandler()}
          verticalOnly={true}
          ref={bottomPanel}
          snapPoints={_snapPoints}
          initialPosition={_initialPosition}
          boundaries={boundaries}
          animatedValueY={isAnimatedYFromParent ? animatedValueY : _deltaY}
          onSnap={onDrawerSnap}
        >
          {!isModal && isDismissWithPress && !isBottomSheetDismissed && (
            <TapGestureHandler
              enabled={isBackDrop}
              onActivated={dismissBottomSheet}
            >
              <View
                style={{
                  height: Screen.height,
                  marginTop: -Screen.height,
                }}
              />
            </TapGestureHandler>
          )}

          <View
            style={[
              isModal ? styles.modal : styles.panel,
              { backgroundColor: bottomSheerColor },
              isRoundBorderWithTipHeader
                ? [
                    {
                      backgroundColor: '#FFFFFF',
                      shadowColor: '#000000',
                      shadowOffset: { width: 0, height: 0 },
                      shadowRadius: 5,
                      shadowOpacity: 0.4,
                    },
                    {
                      borderTopLeftRadius: tipHeaderRadius,
                      borderTopRightRadius: tipHeaderRadius,
                    },
                  ]
                : {},
              containerStyle,
            ]}
          >
            <View
              style={[
                isModal ? styles.modal : styles.panel,
                bodyContainerStyle,
              ]}
            >
              {!isModal && isRoundBorderWithTipHeader && (
                <View style={[styles.panelHandle, tipStyle]} />
              )}
              {!isModal && (
                <View
                  style={[styles.panelHeader, headerStyle]}
                  onLayout={(e) => setHeaderHeight(e.nativeEvent.layout.height)}
                >
                  {header}
                </View>
              )}
              <View style={bodyStyle}>
                {React.cloneElement(body, {
                  style: {
                    ...body?.props?.style,
                    height: currentNomalizeSnap - headerHeight + OFFSET,
                  },
                })}
              </View>
            </View>
          </View>
        </Interactable.View>
      </View>
    );
  }
)
Example #24
Source File: CalendarEdit.tsx    From react-native-paper-dates with MIT License 4 votes vote down vote up
function CalendarEdit({
  mode,
  state,
  label = '',
  startLabel = 'Start',
  endLabel = 'End',
  collapsed,
  onChange,
  validRange,
  locale,
}: {
  mode: ModeType
  label?: string
  startLabel?: string
  endLabel?: string
  state: LocalState
  collapsed: boolean
  onChange: (s: LocalState) => any
  validRange: ValidRangeType | undefined
  locale: string
}) {
  const dateInput = React.useRef<TextInputNative | null>(null)
  const startInput = React.useRef<TextInputNative | null>(null)
  const endInput = React.useRef<TextInputNative | null>(null)

  // when switching views focus, or un-focus text input
  React.useEffect(() => {
    // hide open keyboard
    if (collapsed) {
      Keyboard.dismiss()
    }

    const inputsToFocus = [dateInput.current, startInput.current].filter(
      (n) => n
    ) as TextInputNative[]

    const inputsToBlur = [
      dateInput.current,
      startInput.current,
      endInput.current,
    ].filter((n) => n) as TextInputNative[]

    if (collapsed) {
      inputsToBlur.forEach((ip) => ip.blur())
    } else {
      inputsToFocus.forEach((ip) => ip.focus())
    }
  }, [mode, startInput, endInput, dateInput, collapsed])

  const onSubmitStartInput = React.useCallback(() => {
    if (endInput.current) {
      endInput.current.focus()
    }
  }, [endInput])

  const onSubmitEndInput = React.useCallback(() => {
    // TODO: close modal and persist range
  }, [])

  const onSubmitInput = React.useCallback(() => {
    // TODO: close modal and persist range
  }, [])

  return (
    <View style={styles.root}>
      {mode === 'single' ? (
        <DatePickerInput
          inputMode="start"
          ref={dateInput}
          label={label}
          value={state.date}
          onChange={(date) => onChange({ ...state, date })}
          onSubmitEditing={onSubmitInput}
          validRange={validRange}
          locale={locale}
          withModal={false}
          autoComplete={'off'}
        />
      ) : null}
      {mode === 'range' ? (
        <View style={styles.inner}>
          <DatePickerInput
            inputMode="start"
            ref={startInput}
            label={startLabel}
            value={state.startDate}
            onChange={(startDate) => onChange({ ...state, startDate })}
            returnKeyType={'next'}
            onSubmitEditing={onSubmitStartInput}
            validRange={validRange}
            locale={locale}
            withModal={false}
            autoComplete={'off'}
          />
          <View style={styles.separator} />
          <DatePickerInput
            inputMode="end"
            ref={endInput}
            label={endLabel}
            value={state.endDate}
            onChange={(endDate) => onChange({ ...state, endDate })}
            onSubmitEditing={onSubmitEndInput}
            validRange={validRange}
            locale={locale}
            withModal={false}
            autoComplete="off"
          />
        </View>
      ) : null}
    </View>
  )
}
Example #25
Source File: App.tsx    From SQL-Play with GNU Affero General Public License v3.0 4 votes vote down vote up
App: React.FC = () => {
  const [tableData, setTableData] = useState<tableDataNode>({
    header: [],
    rows: [[]],
  }); // header rows with value

  const tableWidths = useRef<Array<number>>([]);
  const [inputValue, setInputValue] = useState<string>(
    'SELECT * FROM employees',
  );
  const [loaderVisibility, setLoaderVisibility] = useState<boolean>(false);
  const [isPremium, setIsPremium] = useState<boolean>(false);
  const [premiumModalOpen, setPremiumModalOpen] = useState<boolean>(false);
  const {load, adLoaded} = useInterstitialAd(getInterstitialId(), adConfig);
  const styles = useDynamicValue(dynamicStyles);

  const showAd = async () => {
    if (!shouldShowAd()) return;

    if (adLoaded) return;
    try {
      load();
    } catch (error) {
      console.log('failed to load ad', error);
    }
  };

  const runQuery = async () => {
    Keyboard.dismiss();
    setLoaderVisibility(true);
    await insertUserCommand(inputValue); // store the command in db
    try {
      /** Show add if user is not premium */
      if (!isPremium) {
        showAd();
      }
      // execute the query
      const res: any = await ExecuteUserQuery(inputValue);

      const len: number = res.rows.length;

      // console.log(res.rows);
      if (len === 0) {
        setLoaderVisibility(false);
        Snackbar.show({text: 'Query Executed!'});
        return;
      }
      const header: string[] = Object.keys(res.rows.item(0)).reverse();
      const rowsArr: any[] = [];

      for (let i = 0; i < len; i++) {
        let row = res.rows.item(i);
        rowsArr.push(Object.values(row).reverse());
      }
      // pass the header and result arr to get the largest widths of their respective column
      tableWidths.current = await getLargestWidths([header, ...rowsArr]);
      // console.log(([header, ...rowsArr]));

      setLoaderVisibility(false);
      // console.log(rowsArr);

      setTableData({header: header, rows: rowsArr});
    } catch (error) {
      setLoaderVisibility(false);
      Alert.alert('Error in DB', error?.message);
    }
  };

  useEffect(() => {
    const init = async () => {
      const isPremRes = await getIsPremium();
      setIsPremium(isPremRes);
      // Setup ad only when user is not premium
      if (!isPremRes) {
      }
      await SplashScreen.hide({fade: true});
    };
    init();
    // return () => {};
  }, []);

  return (
    <ColorSchemeProvider>
      <BottomSheetModalProvider>
        <SafeAreaProvider>
          <StatusBar
            barStyle="dark-content"
            backgroundColor="#c8b900"
            translucent
          />
          <GoPremium
            modalState={premiumModalOpen}
            setModalState={setPremiumModalOpen}
            isPremium={isPremium}
            setIsPremium={setIsPremium}
          />
          <KeyboardAvoidingView
            style={{flex: 1}}
            {...(Platform.OS === 'ios' && {behavior: 'padding'})}
            keyboardVerticalOffset={Platform.select({
              ios: 0,
              android: 500,
            })}
          >
            <View style={styles.statusBar} />

            <Modal visible={loaderVisibility} transparent={true}>
              <View style={styles.modalStyle}>
                <ActivityIndicator size={50} color="gold" />
              </View>
            </Modal>
            <View testID="query-runner" style={styles.outerContainer}>
              <AppBar
                premiumModalOpen={premiumModalOpen}
                setPremiumModalOpen={setPremiumModalOpen}
                setInputValue={setInputValue}
                isPremium={isPremium}
                setIsPremium={setIsPremium}
              />
              <View style={styles.innercontainer}>
                <InputContainer
                  setPremiumModalOpen={setPremiumModalOpen}
                  inputValue={inputValue}
                  setInputValue={setInputValue}
                  isPremium={isPremium}
                />
                {!!tableData.header.length && (
                  <Table {...tableData} tableWidths={tableWidths} />
                )}
              </View>

              <RunButton runQuery={runQuery} />
            </View>
          </KeyboardAvoidingView>
        </SafeAreaProvider>
      </BottomSheetModalProvider>
    </ColorSchemeProvider>
  );
}
Example #26
Source File: Restore.tsx    From BitcoinWalletMobile with MIT License 4 votes vote down vote up
Restore: React.FC<Props> = (props) => {

    const insets = useSafeAreaInsets()

    const [isValid, setIsValid] = useState(false)
    const [fieldsWithError, setFieldsWithError] = useState([-1])
    const [words, setWords] = useState(["", "", "", "", "", "", "", "", "", "", "", ""])

    const refs = [createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>(), createRef<TextInput>()]

    const updateWord = (word: string, index: number) => {

        if((index-1) >= 0) {
            fixWord(index-1)
        }

        let newWords = [...words]

        for (var i = 0; i < newWords.length; i++) {
            if (index == i) {
                newWords[i] = word
            }
        }

        let errorFields = [...fieldsWithError]

        if(bip39.wordlists.english.indexOf(word) == -1 && word != '') {
            errorFields.push(index)
        }
        else {
            if(fieldsWithError.indexOf(index) != -1) {
                errorFields = fieldsWithError.filter((f) => f != index)
            }
        }
        setFieldsWithError(errorFields)
        setWords(newWords)
    }

    const fixWord = (index : number) => {

        if (index < 0) {
            return
        }

        let newWords = [...words]
        newWords[index] = words[index].trim().toLowerCase()

        let errorFields = [...fieldsWithError]

        if(bip39.wordlists.english.indexOf(newWords[index]) == -1 && words[index] != '') {
            errorFields.push(index)
        }
        else {
            if(fieldsWithError.indexOf(index) != -1) {
                errorFields = fieldsWithError.filter((f) => f != index)
            }
        }
        setFieldsWithError(errorFields)
        setWords(newWords)
    }

    const nextTextInput = (index: number) => {
        fixWord(index-1)
        refs[index].current?.focus()
    }

    const dispatch = useDispatch()
    const languageSelector = (state: WalletState) => state.language
    const language = useSelector(languageSelector)

    useEffect(() => {
        setIsValid(bip39.validateMnemonic(words.join(" ")))
    }, [words])


    const restoreWallet = async () => {

        Keyboard.dismiss()

        if(!isValid) {
            return
        }

        try {
            //Store the seed in the keychain
            await RNSecureKeyStore.set("WALLET_SEED", words.join(" ").toLowerCase(), { accessible: ACCESSIBLE.ALWAYS_THIS_DEVICE_ONLY })

            // State change to indicate we are restoring so the main wallet screen knows to do a full sync
            dispatch(isRestoring(true))

            // Let's go back 
            props.navigation.goBack()
        }

        catch {

        }

    }

    return (
        <View style={{ flex: 1 }}>
            <View style={{ flex: 1 }}>
                <Header screen={getTranslated(language).restore_existing} action={() => { props.navigation.goBack() }} />
                <Screen>
                    <View style={{ flex: 1 }}>
                        <ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'space-between' }}>
                            <Text style={styles.subHeading}>{getTranslated(language).restore_notice}</Text>
                            <View style={{ flex: 1, marginTop: 20, flexDirection: 'row', flexWrap: 'wrap', marginHorizontal: 10, alignItems: 'flex-start' }}>
                                {words.map((word, index) => {
                                    return (
                                        <View key={index} style={{ flexDirection: 'row', alignItems: 'center', width: '50%', flexWrap: 'wrap', marginTop: 10, }}>
                                            <Text style={styles.numberedLabel}>{index + 1}.</Text>
                                            <TextInput
                                                style={[styles.recoveryField, fieldsWithError.filter((f) => f == index).length > 0 ? styles.recoveryErrorBorder : styles.recoveryNormalBorder]}
                                                ref={refs[index]}
                                                returnKeyType="next"
                                                keyboardType="ascii-capable"
                                                autoCorrect={false}
                                                autoCapitalize="none"
                                                value={word}
                                                onBlur={() => { fixWord(index) }}
                                                onChangeText={(text) => updateWord(text, index)}
                                                onSubmitEditing={() => { index < 11 ? nextTextInput(index + 1) : restoreWallet() }}
                                                blurOnSubmit={false}
                                            />
                                        </View>
                                    )
                                })
                                }
                            </View>
                            <View style={{ marginBottom: insets.bottom + 30, marginLeft: 16 }}>

                                {!isValid &&
                                    <ButtonPrimaryDisabled text={getTranslated(language).restore_button} action={restoreWallet} />
                                }
                                {isValid &&
                                    <ButtonPrimary text={getTranslated(language).restore_button} action={restoreWallet} />
                                }

                            </View>
                        </ScrollView>
                    </View>
                </Screen>
            </View>
        </View>
    );
}
Example #27
Source File: InputSelect.tsx    From react-native-paper-form-builder with MIT License 4 votes vote down vote up
function InputSelect(props: InputSelectProps) {
  const {
    formState,
    field,
    textInputProps,
    options,
    CustomTextInput,
    onDismiss = () => {},
  } = props;
  const theme = useTheme();
  const errorMessage = formState.errors?.[field.name]?.message;
  const textColor = errorMessage ? theme.colors.error : theme.colors.text;
  const [visible, setVisible] = useState(false);
  const [width, setWidth] = useState(0);
  const [height, setHeight] = useState(0);
  const INPUT = CustomTextInput ?? TextInput;

  const styles = useMemo(
    () =>
      StyleSheet.create({
        textInputStyle: {
          color: textColor,
        },
        menuStyle: {
          minWidth: width,
          width: width,
          marginTop: height,
        },
      }),
    [height, textColor, theme.colors.onSurface, theme.colors.surface, width],
  );

  const onLayout = useCallback((event: LayoutChangeEvent) => {
    const {width: _width, height: _height} = event.nativeEvent.layout;
    setWidth(_width);
    setHeight(_height);
  }, []);

  return (
    <Fragment>
      <Menu
        visible={visible}
        onDismiss={() => setVisible(false)}
        style={styles.menuStyle}
        anchor={
          <TouchableRipple
            onPress={() => {
              Keyboard.dismiss();
              if (!textInputProps.disabled) {
                setVisible(true);
              }
            }}>
            <View pointerEvents={'none'} onLayout={onLayout}>
              <INPUT
                ref={field.ref}
                mode={'outlined'}
                error={errorMessage ? true : false}
                {...textInputProps}
                value={
                  options.find(({value}) => `${value}` === `${field.value}`)
                    ?.label
                }
                onFocus={() => {
                  Keyboard.dismiss();
                  if (!textInputProps.disabled) {
                    setVisible(true);
                  }
                }}
                style={[styles.textInputStyle, textInputProps?.style]}
              />
            </View>
          </TouchableRipple>
        }>
        {options.map(({label: _label, value: _value}, _index) => {
          return (
            <Fragment key={_value}>
              <Menu.Item
                title={_label}
                style={{width, minWidth: width, maxWidth: width}}
                onPress={() => {
                  field.onChange(`${_value}`);
                  setVisible(false);
                  !!onDismiss && onDismiss();
                }}
                titleStyle={{
                  color:
                    `${_value}` === `${field.value}`
                      ? theme.colors.primary
                      : theme.colors.text,
                }}
              />
              {_index < options.length - 1 && <Divider />}
            </Fragment>
          );
        })}
      </Menu>
      {errorMessage && <HelperText type={'error'}>{errorMessage}</HelperText>}
    </Fragment>
  );
}
Example #28
Source File: CreditCardForm.tsx    From rn-credit-card with MIT License 4 votes vote down vote up
CreditCardForm: React.FC<LibraryProps> = (props) => {
  const {
    horizontalStart = true,
    translations: parentTranslations,
    overrides,
    requiresName = true,
  } = props
  const translations = getTranslations(parentTranslations)
  const { trigger, watch } = useFormContext()
  const cardNumber = watch('cardNumber')
  const { card } = cardValidator.number(cardNumber)
  const isAmex = card?.type === 'american-express'
  const cvvLength = isAmex ? 4 : 3

  const [isHorizontal, setIsHorizontal] = useState(
    horizontalStart && Platform.OS === 'ios',
  )

  const { width: windowWidth } = useWindowDimensions()
  // input has 36*2 padding
  const inputWidth = windowWidth - 72

  const scrollRef = useRef<ScrollView>(null)
  const holderNameRef = useRef<TextInput>(null)
  const cardNumberRef = useRef<TextInput>(null)
  const expirationRef = useRef<TextInput>(null)
  const cvvRef = useRef<TextInput>(null)

  const [focusedField, setFocusedField] = useState<CardFields | null>(null)

  useEffect(() => {
    if (cardNumberRef?.current) {
      cardNumberRef.current.focus()
    }
  }, [cardNumberRef])

  const textFieldStyle = isHorizontal
    ? [
        styles.textField,
        {
          width: inputWidth,
        },
      ]
    : styles.regularField

  async function goNext() {
    if (focusedField === null) return

    const field = ['cardNumber', 'holderName', 'expiration', 'cvv'][
      focusedField
    ]

    if (isHorizontal) {
      const result = await trigger(field)
      if (!result) return
      scrollRef.current?.scrollTo({ x: (focusedField + 1) * inputWidth })
    }

    if (focusedField === CardFields.CardNumber && !requiresName) {
      expirationRef.current.focus()
      return
    }

    if (focusedField === CardFields.CVV) {
      setFocusedField(null)
      setIsHorizontal(false)
      Keyboard.dismiss()
      return
    }

    const ref = [cardNumberRef, holderNameRef, expirationRef, cvvRef][
      focusedField + 1
    ]
    ref.current?.focus()
  }

  return (
    <LibraryContext.Provider
      value={{
        ...props,
        overrides: overrides || {},
        fonts: {
          regular: props.fonts?.regular || 'RobotoMono_400Regular',
          bold: props.fonts?.bold || 'RobotoMono_700Bold',
        },
        translations,
        requiresName,
      }}
    >
      <View style={styles.container}>
        <Conditional condition={!props.formOnly}>
          <FormCard cardType={card?.type} focusedField={focusedField} />
        </Conditional>
        <ScrollView
          ref={scrollRef}
          style={isHorizontal && { maxHeight: 120 }}
          pagingEnabled={isHorizontal}
          horizontal={isHorizontal}
          scrollEnabled={!isHorizontal}
          keyboardShouldPersistTaps="handled"
        >
          <FormTextField
            style={textFieldStyle}
            ref={cardNumberRef}
            name="cardNumber"
            label={translations.cardNumber}
            keyboardType="number-pad"
            autoCompleteType="cc-number"
            maxLength={19}
            validationLength={isAmex ? 18 : 19}
            rules={{
              required: translations.cardNumberRequired,
              validate: {
                isValid: (value: string) => {
                  return (
                    cardValidator.number(value).isValid ||
                    translations.cardNumberInvalid
                  )
                },
              },
            }}
            formatter={cardNumberFormatter}
            endEnhancer={<CardIcon cardNumber={cardNumber} />}
            onFocus={() => setFocusedField(CardFields.CardNumber)}
            onValid={goNext}
          />
          {requiresName && (
            <FormTextField
              style={textFieldStyle}
              ref={holderNameRef}
              name="holderName"
              autoCompleteType="name"
              label={translations.cardHolderName}
              rules={{
                required: translations.cardHolderNameRequired,
                validate: {
                  isValid: (value: string) => {
                    return (
                      cardValidator.cardholderName(value).isValid ||
                      translations.cardHolderNameInvalid
                    )
                  },
                },
              }}
              autoCorrect={false}
              onSubmitEditing={goNext}
              onFocus={() => setFocusedField(CardFields.CardHolderName)}
            />
          )}
          <View style={styles.row}>
            <FormTextField
              style={[
                textFieldStyle,
                {
                  marginRight: isHorizontal ? 0 : 24,
                },
              ]}
              ref={expirationRef}
              name="expiration"
              label={translations.expiration}
              keyboardType="number-pad"
              autoCompleteType="cc-exp"
              maxLength={5}
              validationLength={5}
              rules={{
                required: translations.expirationRequired,
                validate: {
                  isValid: (value: string) => {
                    return (
                      cardValidator.expirationDate(value).isValid ||
                      translations.expirationInvalid
                    )
                  },
                },
              }}
              formatter={expirationDateFormatter}
              onFocus={() => setFocusedField(CardFields.Expiration)}
              onValid={goNext}
            />
            <FormTextField
              style={textFieldStyle}
              ref={cvvRef}
              name="cvv"
              label={translations.securityCode}
              keyboardType="number-pad"
              autoCompleteType="cc-csc"
              maxLength={cvvLength}
              validationLength={cvvLength}
              rules={{
                required: translations.securityCodeRequired,
                validate: {
                  isValid: (value: string) => {
                    return (
                      cardValidator.cvv(value, cvvLength).isValid ||
                      translations.securityCodeInvalid
                    )
                  },
                },
              }}
              onFocus={() => setFocusedField(CardFields.CVV)}
              onValid={goNext}
            />
          </View>
        </ScrollView>
        <Conditional condition={isHorizontal}>
          <Button
            style={[styles.button, overrides?.button]}
            title={
              focusedField === CardFields.CVV
                ? translations.done
                : translations.next
            }
            onPress={goNext}
          />
        </Conditional>
      </View>
    </LibraryContext.Provider>
  )
}
Example #29
Source File: Convert.tsx    From hive-keychain-mobile with MIT License 4 votes vote down vote up
Convert = ({
  user,
  loadAccount,
  fetchConversionRequests,
  conversions,
  currency,
}: Props) => {
  console.log(conversions);
  const [amount, setAmount] = useState('');
  const [loading, setLoading] = useState(false);
  const [showConversionsList, setShowConversionsList] = useState(false);

  useEffect(() => {
    fetchConversionRequests(user.name!);
  }, [user.name, fetchConversionRequests]);

  const onConvert = async () => {
    Keyboard.dismiss();
    setLoading(true);
    try {
      if (currency === 'HBD') {
        await convert(user.keys.active!, {
          owner: user.account.name,
          amount: sanitizeAmount(amount, 'HBD'),
          requestid: Math.max(...conversions.map((e) => e.requestid), 0) + 1,
        });
      } else {
        await collateralizedConvert(user.keys.active!, {
          owner: user.account.name,
          amount: sanitizeAmount(amount, 'HIVE'),
          requestid: Math.max(...conversions.map((e) => e.requestid), 0) + 1,
        });
      }
      loadAccount(user.account.name, true);
      goBack();
      Toast.show(translate('toast.convert_success', {currency}), Toast.LONG);
    } catch (e) {
      Toast.show(`Error : ${(e as any).message}`, Toast.LONG);
    } finally {
      setLoading(false);
    }
  };
  const {color} = getCurrencyProperties(currency);
  const styles = getDimensionedStyles(color);
  return (
    <Operation
      logo={<Hive />}
      title={translate('wallet.operations.convert.title', {
        to: currency === 'HIVE' ? 'HBD' : 'HIVE',
      })}>
      <>
        <Separator />
        <Balance
          currency={currency}
          account={user.account}
          setMax={(value: string) => {
            setAmount(value);
          }}
        />
        <Separator />
        <Text style={styles.disclaimer}>
          {translate(
            `wallet.operations.convert.disclaimer_${currency.toLowerCase()}`,
          )}
        </Text>
        <Separator />
        <OperationInput
          placeholder={'0.000'}
          keyboardType="numeric"
          rightIcon={<Text style={styles.currency}>{currency}</Text>}
          textAlign="right"
          value={amount}
          onChangeText={setAmount}
        />
        <Separator />
        <TouchableOpacity
          onPress={() => {
            setShowConversionsList(!showConversionsList);
          }}>
          <Text
            style={
              styles.conversions
            }>{`${conversions.length} conversions`}</Text>
        </TouchableOpacity>
        <Separator />
        {showConversionsList ? (
          <FlatList
            data={conversions}
            style={styles.conversionContainer}
            renderItem={({item}) => {
              const [amt, currency] = item.amount.split(' ');
              return (
                <View style={styles.conversionRow}>
                  <Text>
                    {amt}{' '}
                    <Text
                      style={currency === 'HBD' ? styles.green : styles.red}>
                      {currency}
                    </Text>
                  </Text>
                  <Text>-</Text>
                  <Text>
                    {item.conversion_date
                      .replace('T', ' ')
                      .replace('-', '/')
                      .replace('-', '/')}
                  </Text>
                </View>
              );
            }}
            keyExtractor={(conversion) => conversion.id + ''}
          />
        ) : null}

        <Separator />
        <ActiveOperationButton
          title={translate('wallet.operations.convert.button')}
          onPress={onConvert}
          style={styles.button}
          isLoading={loading}
        />
      </>
    </Operation>
  );
}