mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 15:48:05 +00:00
Some checks failed
🤖 Android APK Build (Phone + TV) / 🏗️ Build Android APK (phone) (push) Has been cancelled
🤖 Android APK Build (Phone + TV) / 🏗️ Build Android APK (tv) (push) Has been cancelled
🤖 iOS IPA Build (Phone + TV) / 🏗️ Build iOS IPA (phone) (push) Has been cancelled
🔒 Lockfile Consistency Check / 🔍 Check bun.lock and package.json consistency (push) Has been cancelled
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (actions) (push) Has been cancelled
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (javascript-typescript) (push) Has been cancelled
🏷️🔀Merge Conflict Labeler / 🏷️ Labeling Merge Conflicts (push) Has been cancelled
🚦 Security & Quality Gate / 📝 Validate PR Title (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Vulnerable Dependencies (push) Has been cancelled
🚦 Security & Quality Gate / 🚑 Expo Doctor Check (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (check) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (format) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (lint) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (typecheck) (push) Has been cancelled
🕒 Handle Stale Issues / 🗑️ Cleanup Stale Issues (push) Has been cancelled
132 lines
2.8 KiB
TypeScript
132 lines
2.8 KiB
TypeScript
import { BottomSheetTextInput } from "@gorhom/bottom-sheet";
|
|
import React, { useCallback, useImperativeHandle, useRef } from "react";
|
|
import {
|
|
type StyleProp,
|
|
StyleSheet,
|
|
Text,
|
|
type TextInputProps,
|
|
View,
|
|
type ViewStyle,
|
|
} from "react-native";
|
|
|
|
interface PinInputProps
|
|
extends Omit<TextInputProps, "value" | "onChangeText" | "style"> {
|
|
value: string;
|
|
onChangeText: (text: string) => void;
|
|
length?: number;
|
|
autoFocus?: boolean;
|
|
style?: StyleProp<ViewStyle>;
|
|
}
|
|
|
|
export interface PinInputRef {
|
|
focus: () => void;
|
|
}
|
|
|
|
const PinInputComponent = React.forwardRef<PinInputRef, PinInputProps>(
|
|
(props, ref) => {
|
|
const {
|
|
value,
|
|
onChangeText,
|
|
length = 6,
|
|
style,
|
|
autoFocus,
|
|
...rest
|
|
} = props;
|
|
|
|
const inputRef = useRef<any>(null);
|
|
const activeIndex = value.length;
|
|
|
|
const handlePress = useCallback(() => {
|
|
inputRef.current?.focus();
|
|
}, []);
|
|
|
|
useImperativeHandle(
|
|
ref,
|
|
() => ({
|
|
focus: () => inputRef.current?.focus(),
|
|
}),
|
|
[],
|
|
);
|
|
|
|
return (
|
|
<View style={[styles.container, style]}>
|
|
<BottomSheetTextInput
|
|
ref={inputRef}
|
|
value={value}
|
|
onChangeText={onChangeText}
|
|
keyboardType='number-pad'
|
|
maxLength={length}
|
|
style={styles.hiddenInput}
|
|
autoFocus={autoFocus}
|
|
{...rest}
|
|
/>
|
|
<View style={styles.cells} onTouchStart={handlePress}>
|
|
{Array(length)
|
|
.fill(0)
|
|
.map((_, i) => (
|
|
<View
|
|
key={i}
|
|
style={[
|
|
styles.cell,
|
|
i === activeIndex && styles.activeCell,
|
|
i === activeIndex - 1 && styles.filledCell,
|
|
]}
|
|
>
|
|
<Text style={styles.digit}>{value[i]}</Text>
|
|
{i === activeIndex && <View style={styles.cursor} />}
|
|
</View>
|
|
))}
|
|
</View>
|
|
</View>
|
|
);
|
|
},
|
|
);
|
|
|
|
PinInputComponent.displayName = "PinInput";
|
|
|
|
export const PinInput = PinInputComponent;
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
width: "100%",
|
|
},
|
|
hiddenInput: {
|
|
position: "absolute",
|
|
width: 1,
|
|
height: 1,
|
|
opacity: 0,
|
|
},
|
|
cells: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
width: "100%",
|
|
},
|
|
cell: {
|
|
width: 40,
|
|
height: 48,
|
|
borderWidth: 1,
|
|
borderColor: "#374151",
|
|
borderRadius: 8,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
backgroundColor: "#1F2937",
|
|
},
|
|
activeCell: {
|
|
borderColor: "#6366F1",
|
|
},
|
|
filledCell: {
|
|
borderColor: "#4B5563",
|
|
},
|
|
digit: {
|
|
fontSize: 24,
|
|
color: "white",
|
|
fontWeight: "500",
|
|
},
|
|
cursor: {
|
|
position: "absolute",
|
|
width: 2,
|
|
height: 24,
|
|
backgroundColor: "#6366F1",
|
|
},
|
|
});
|