useDropdown hook, review requests
This commit is contained in:
parent
bcef200765
commit
ffe95a12f2
@ -31,7 +31,7 @@ module.exports = {
|
|||||||
// Best Practices
|
// Best Practices
|
||||||
eqeqeq: ["error", "always"], // Enforce '===' instead of '=='
|
eqeqeq: ["error", "always"], // Enforce '===' instead of '=='
|
||||||
curly: ["error", "multi-line", "consistent"], // Require curly braces for all control statements
|
curly: ["error", "multi-line", "consistent"], // Require curly braces for all control statements
|
||||||
"no-unused-vars": "warn", // Warn about variables that are declared but not used
|
"no-unused-vars": "off", // Not needed with TypeScript
|
||||||
|
|
||||||
// React Specific
|
// React Specific
|
||||||
"react/jsx-filename-extension": [1, { extensions: [".tsx"] }], // Allow jsx syntax in .tsx files
|
"react/jsx-filename-extension": [1, { extensions: [".tsx"] }], // Allow jsx syntax in .tsx files
|
||||||
|
@ -4,52 +4,103 @@ import { useCallback, useState } from "react";
|
|||||||
import { useCameraPermission } from "react-native-vision-camera";
|
import { useCameraPermission } from "react-native-vision-camera";
|
||||||
import { showAlert } from "../../lib/alert-messages";
|
import { showAlert } from "../../lib/alert-messages";
|
||||||
|
|
||||||
interface VideoFlowInputParams {
|
// TODO: #122 should decide on what values/labels go here.
|
||||||
sessionName?: string;
|
enum GameType {
|
||||||
gameType: string;
|
FreePlay = "freePlay",
|
||||||
tableSize: string;
|
StraightPool = "straightPool",
|
||||||
|
NineBall = "nineBall",
|
||||||
|
}
|
||||||
|
// TODO: #122 should be int -- inch value of table size.
|
||||||
|
enum TableSize {
|
||||||
|
NineFoot = "nineFoot",
|
||||||
|
EightFoot = "eightFoot",
|
||||||
|
SevenFoot = "sevenFoot",
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VideoUserInputMeta {
|
||||||
|
sessionName: string;
|
||||||
|
gameType: GameType | null;
|
||||||
|
tableSize: TableSize | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VideoFlowInputParams extends VideoUserInputMeta {
|
||||||
videoId?: number;
|
videoId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useVideoDetails = ({ mode, videoId, params, navigation }) => {
|
function useDropdown<T>(
|
||||||
|
initialValue: T | null,
|
||||||
|
options: Array<{ label: string; value: T }>,
|
||||||
|
closeOthers: () => void,
|
||||||
|
) {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [value, setValue] = useState<T | null>(initialValue);
|
||||||
|
const [optionsList, setOptionsList] = useState(options);
|
||||||
|
|
||||||
|
const toggleOpen = useCallback(() => {
|
||||||
|
if (!isOpen) {
|
||||||
|
closeOthers();
|
||||||
|
}
|
||||||
|
setIsOpen(!isOpen);
|
||||||
|
}, [isOpen, closeOthers]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isOpen,
|
||||||
|
toggleOpen,
|
||||||
|
value,
|
||||||
|
setValue,
|
||||||
|
optionsList,
|
||||||
|
setOptionsList,
|
||||||
|
setIsOpen,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useVideoDetails = ({
|
||||||
|
params: {
|
||||||
|
mode,
|
||||||
|
videoId,
|
||||||
|
sessionName: initialSessionName,
|
||||||
|
gameType: initialGameType,
|
||||||
|
tableSize: initialTableSize,
|
||||||
|
},
|
||||||
|
navigation,
|
||||||
|
}) => {
|
||||||
|
const initialState = {
|
||||||
|
sessionName: initialSessionName || "",
|
||||||
|
gameType: initialGameType || null,
|
||||||
|
tableSize: initialTableSize || null,
|
||||||
|
};
|
||||||
const { hasPermission, requestPermission } = useCameraPermission();
|
const { hasPermission, requestPermission } = useCameraPermission();
|
||||||
|
|
||||||
// Initial state setup
|
|
||||||
const initialState = mode === "save-video" && params ? params : {};
|
|
||||||
|
|
||||||
// Session name input
|
|
||||||
// Should session name be required?
|
|
||||||
const [sessionName, setSessionName] = useState<string>(
|
const [sessionName, setSessionName] = useState<string>(
|
||||||
initialState.sessionName || "",
|
initialState.sessionName || "",
|
||||||
);
|
);
|
||||||
|
|
||||||
// Game type dropdown
|
const closeAllDropdowns = useCallback(() => {
|
||||||
const [gameTypeOpen, setGameTypeOpen] = useState<boolean>(false);
|
gameType.setIsOpen(false);
|
||||||
const [gameType, setGameType] = useState<string | null>(
|
tableSize.setIsOpen(false);
|
||||||
initialState.gameType || null,
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const gameType = useDropdown<GameType | null>(
|
||||||
|
initialState.gameType,
|
||||||
|
[
|
||||||
|
{ label: "Free Play", value: GameType.FreePlay },
|
||||||
|
{ label: "Straight Pool", value: GameType.StraightPool },
|
||||||
|
{ label: "Nine Ball", value: GameType.NineBall },
|
||||||
|
],
|
||||||
|
closeAllDropdowns,
|
||||||
);
|
);
|
||||||
const [gameTypes, setGameTypes] = useState([
|
|
||||||
{ label: "Free Play", value: "freePlay" },
|
|
||||||
{ label: "Straight Pool", value: "straightPool" },
|
|
||||||
{ label: "Nine Ball", value: "nineBall" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Table size dropdown
|
const tableSize = useDropdown<TableSize | null>(
|
||||||
const [tableSizeOpen, setTableSizeOpen] = useState<boolean>(false);
|
initialState.tableSize,
|
||||||
const [tableSize, setTableSize] = useState<string>(
|
[
|
||||||
initialState.tableSize || "",
|
{ label: `9'`, value: TableSize.NineFoot },
|
||||||
|
{ label: `8'`, value: TableSize.EightFoot },
|
||||||
|
{ label: `7'`, value: TableSize.SevenFoot },
|
||||||
|
],
|
||||||
|
closeAllDropdowns,
|
||||||
);
|
);
|
||||||
const [tableSizes, setTableSizes] = useState([
|
|
||||||
{ label: `9'`, value: "nineFoot" },
|
|
||||||
{ label: `8'`, value: "eightFoot" },
|
|
||||||
{ label: `7'`, value: "sevenFoot" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Toggle dropdowns mutually exclusive
|
|
||||||
const onGameTypeOpen = useCallback(() => setTableSizeOpen(false), []);
|
|
||||||
const onTableSizeOpen = useCallback(() => setGameTypeOpen(false), []);
|
|
||||||
|
|
||||||
// GraphQL Mutation
|
|
||||||
const [TerminateUploadStream, { loading, error }] =
|
const [TerminateUploadStream, { loading, error }] =
|
||||||
gql.useTerminateUploadStreamMutation();
|
gql.useTerminateUploadStreamMutation();
|
||||||
|
|
||||||
@ -60,12 +111,21 @@ export const useVideoDetails = ({ mode, videoId, params, navigation }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode === "start-video") {
|
if (mode === "start-video") {
|
||||||
const params: VideoFlowInputParams = { sessionName, gameType, tableSize };
|
const params: VideoFlowInputParams = {
|
||||||
|
sessionName,
|
||||||
|
gameType: gameType.value,
|
||||||
|
tableSize: tableSize.value,
|
||||||
|
};
|
||||||
navigation.push("Camera", params);
|
navigation.push("Camera", params);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
await TerminateUploadStream({
|
await TerminateUploadStream({
|
||||||
variables: { videoId, videoName: sessionName, tableSize, gameType },
|
variables: {
|
||||||
|
videoId,
|
||||||
|
videoName: sessionName,
|
||||||
|
tableSize: tableSize.value,
|
||||||
|
gameType: gameType.value,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
navigation.push("Tabs");
|
navigation.push("Tabs");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -78,19 +138,7 @@ export const useVideoDetails = ({ mode, videoId, params, navigation }) => {
|
|||||||
sessionName,
|
sessionName,
|
||||||
setSessionName,
|
setSessionName,
|
||||||
gameType,
|
gameType,
|
||||||
setGameType,
|
|
||||||
gameTypeOpen,
|
|
||||||
setGameTypeOpen,
|
|
||||||
gameTypes,
|
|
||||||
setGameTypes,
|
|
||||||
onGameTypeOpen,
|
|
||||||
tableSize,
|
tableSize,
|
||||||
setTableSize,
|
|
||||||
setTableSizes,
|
|
||||||
tableSizeOpen,
|
|
||||||
setTableSizeOpen,
|
|
||||||
tableSizes,
|
|
||||||
onTableSizeOpen,
|
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
|
@ -9,34 +9,20 @@ import {
|
|||||||
View,
|
View,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import DropDownPicker from "react-native-dropdown-picker";
|
import DropDownPicker from "react-native-dropdown-picker";
|
||||||
// @ts-ignore
|
|
||||||
import { useVideoDetails } from "../../component/video/use-video-details";
|
import { useVideoDetails } from "../../component/video/use-video-details";
|
||||||
|
|
||||||
import { globalInputStyles } from "../../styles";
|
import { globalInputStyles } from "../../styles";
|
||||||
import { recordStyles as styles } from "./styles";
|
import { recordStyles as styles } from "./styles";
|
||||||
|
|
||||||
export default function VideoDetails({ navigation, route }): React.JSX.Element {
|
export default function VideoDetails({ navigation, route }): React.JSX.Element {
|
||||||
const { mode, videoId } = route.params;
|
const { mode } = route.params;
|
||||||
const {
|
const {
|
||||||
sessionName,
|
sessionName,
|
||||||
setSessionName,
|
setSessionName,
|
||||||
gameType,
|
gameType,
|
||||||
setGameType,
|
|
||||||
tableSize,
|
tableSize,
|
||||||
setTableSize,
|
|
||||||
gameTypeOpen,
|
|
||||||
setGameTypeOpen,
|
|
||||||
tableSizeOpen,
|
|
||||||
setTableSizeOpen,
|
|
||||||
onGameTypeOpen,
|
|
||||||
onTableSizeOpen,
|
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
loading,
|
loading,
|
||||||
tableSizes,
|
} = useVideoDetails({ params: route.params, navigation });
|
||||||
gameTypes,
|
|
||||||
setGameTypes,
|
|
||||||
setTableSizes,
|
|
||||||
} = useVideoDetails({ mode, videoId, params: route.params, navigation });
|
|
||||||
|
|
||||||
const dropDownStyles = {
|
const dropDownStyles = {
|
||||||
style: globalInputStyles.dropdownStyle,
|
style: globalInputStyles.dropdownStyle,
|
||||||
@ -61,26 +47,24 @@ export default function VideoDetails({ navigation, route }): React.JSX.Element {
|
|||||||
<DropDownPicker
|
<DropDownPicker
|
||||||
zIndex={3000}
|
zIndex={3000}
|
||||||
zIndexInverse={1000}
|
zIndexInverse={1000}
|
||||||
open={gameTypeOpen}
|
open={gameType.isOpen}
|
||||||
value={gameType}
|
value={gameType.value}
|
||||||
items={gameTypes}
|
items={gameType.optionsList}
|
||||||
setOpen={setGameTypeOpen}
|
setOpen={gameType.toggleOpen}
|
||||||
setValue={setGameType}
|
setValue={gameType.setValue}
|
||||||
setItems={setGameTypes}
|
setItems={gameType.setOptionsList}
|
||||||
onOpen={onGameTypeOpen}
|
|
||||||
{...dropDownStyles}
|
{...dropDownStyles}
|
||||||
/>
|
/>
|
||||||
<Text style={globalInputStyles.dropdownTitle}>Table size</Text>
|
<Text style={globalInputStyles.dropdownTitle}>Table Size</Text>
|
||||||
<DropDownPicker
|
<DropDownPicker
|
||||||
zIndex={2000}
|
zIndex={2000}
|
||||||
zIndexInverse={2000}
|
zIndexInverse={2000}
|
||||||
open={tableSizeOpen}
|
open={tableSize.isOpen}
|
||||||
value={tableSize}
|
value={tableSize.value}
|
||||||
items={tableSizes}
|
items={tableSize.optionsList}
|
||||||
setOpen={setTableSizeOpen}
|
setOpen={tableSize.toggleOpen}
|
||||||
setValue={setTableSize}
|
setValue={tableSize.setValue}
|
||||||
setItems={setTableSizes}
|
setItems={tableSize.setOptionsList}
|
||||||
onOpen={onTableSizeOpen}
|
|
||||||
{...dropDownStyles}
|
{...dropDownStyles}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
Loading…
Reference in New Issue
Block a user