render video detail inputs conditionally, terminateUpload on save

working, needs testing

wip: sync styles for inputs, remove notes/tags for now

wip: use single screen and switch on mode

need to rebase

working, needs testing

wip: sync styles for inputs, remove notes/tags for now

wip: use single screen and switch on mode

need to rebase

working, needs testing

add game type and table size to terminateUpload
This commit is contained in:
Loewy
2024-02-12 10:28:42 -08:00
parent b05e354459
commit b04c6aa345
13 changed files with 264 additions and 206 deletions

View File

@@ -1,161 +0,0 @@
import React, { useCallback, useState } from "react";
import {
Keyboard,
Text,
TextInput,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from "react-native";
import DropDownPicker from "react-native-dropdown-picker";
// @ts-ignore
import { useCameraPermission } from "react-native-vision-camera";
import { showAlert } from "../../lib/alert-messages";
import { recordStyles as styles } from "./styles";
interface CameraScreenParams {
gameType: string;
tableSize: string;
tags: Array<string>;
location: string;
}
export default function RecordScreen({ navigation }): React.JSX.Element {
// Permissions
const { hasPermission, requestPermission } = useCameraPermission();
if (!hasPermission) {
requestPermission();
}
// Game type dropdown
const [gameTypeOpen, setGameTypeOpen] = useState<boolean>(false);
const [gameType, setGameType] = useState<string | null>(null); // This is a dropdown
const [gameTypes, setGameTypes] = useState([
{ label: "Free Play", value: "freePlay" },
{ label: "Straight Pool", value: "straightPool" },
{ label: "Nine Ball", value: "nineBall" },
]);
const onGameTypeOpen = useCallback(() => {
setTableSizeOpen(false);
setTagsOpen(false);
}, []);
// Table size dropdown
const [tableSizeOpen, setTableSizeOpen] = useState<boolean>(false);
const [tableSize, setTableSize] = useState<string>("");
const [tableSizes, setTableSizes] = useState([
{ label: `9'`, value: "nineFoot" },
{ label: `8'`, value: "eightFoot" },
{ label: "7", value: "sevenFoot" },
]);
const onTableSizeOpen = useCallback(() => {
setGameTypeOpen(false);
setTagsOpen(false);
}, []);
// Tags multi-select dropdown
const [tagsOpen, setTagsOpen] = useState<boolean>(false);
const [tags, setTags] = useState<Array<string>>([]);
const [tagsList, setTagsList] = useState([
{ label: `Tag1`, value: "tag1" },
{ label: `Tag2`, value: "tag2" },
{ label: "Tag3", value: "tag3" },
]);
const onTagsOpen = useCallback(() => {
setTableSizeOpen(false);
setGameTypeOpen(false);
}, []);
// Location
const [location, setLocation] = useState<string>("");
const handleSubmit = () => {
if (!hasPermission) {
return showAlert("camera");
}
// needs to pass info as params or store in a context/state provider
const params: CameraScreenParams = {
gameType: gameType,
tableSize: tableSize,
tags: tags,
location: location,
};
navigation.push("Camera", params);
};
const dropDownStyles = {
style: styles.dropdownStyle,
};
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.container}>
<View style={styles.dropdownContainer}>
<Text style={styles.dropdownTitle}>Game Type</Text>
<DropDownPicker
zIndex={3000}
zIndexInverse={1000}
open={gameTypeOpen}
value={gameType}
items={gameTypes}
setOpen={setGameTypeOpen}
setValue={setGameType}
setItems={setGameTypes}
onOpen={onGameTypeOpen}
{...dropDownStyles}
/>
<Text style={styles.dropdownTitle}>Table size</Text>
<DropDownPicker
zIndex={2000}
zIndexInverse={2000}
open={tableSizeOpen}
value={tableSize}
items={tableSizes}
setOpen={setTableSizeOpen}
setValue={setTableSize}
setItems={setTableSizes}
onOpen={onTableSizeOpen}
{...dropDownStyles}
/>
<Text style={styles.dropdownTitle}>Tags</Text>
<DropDownPicker
zIndex={1000}
zIndexInverse={3000}
multiple
min={0}
max={5}
open={tagsOpen}
value={tags}
items={tagsList}
setOpen={setTagsOpen}
setValue={setTags}
setItems={setTagsList}
onOpen={onTagsOpen}
{...dropDownStyles}
/>
</View>
<Text style={styles.dropdownTitle}>Location</Text>
<TextInput
style={styles.input}
placeholder="Location"
value={location}
onChangeText={(value) => setLocation(value)}
/>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.buttonStyle}
onPress={() => navigation.goBack()}
>
<Text style={styles.buttonText}>Back</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonStyle} onPress={handleSubmit}>
<Text style={styles.buttonText}>Next</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
);
}

View File

@@ -7,26 +7,13 @@ export const recordStyles = StyleSheet.create({
justifyContent: "center",
padding: 20,
},
dropdownContainer: {
width: "100%",
marginBottom: 20,
zIndex: 50,
},
dropdownTitle: {
fontSize: 16,
headerText: {
fontSize: 22,
fontWeight: "500",
marginBottom: 5,
alignSelf: "flex-start",
},
input: {
width: "100%",
marginBottom: 20,
borderWidth: 1,
borderColor: "grey",
borderRadius: 5,
padding: 10,
paddingBottom: "10%",
},
buttonContainer: {
marginTop: 10,
flexDirection: "row",
justifyContent: "space-between",
width: "100%",
@@ -42,16 +29,4 @@ export const recordStyles = StyleSheet.create({
color: "white",
textAlign: "center",
},
dropdownStyle: {
backgroundColor: "#ffffff",
borderColor: "#D1D1D1",
borderWidth: 1,
borderRadius: 4,
},
dropdownContainerStyle: {
marginBottom: 10,
borderColor: "#D1D1D1",
borderWidth: 1,
borderRadius: 4,
},
});

View File

@@ -0,0 +1,179 @@
import * as gql from "railbird-gql";
import React, { useCallback, useState } from "react";
import {
ActivityIndicator,
Keyboard,
Text,
TextInput,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from "react-native";
import DropDownPicker from "react-native-dropdown-picker";
// @ts-ignore
import { useCameraPermission } from "react-native-vision-camera";
import { showAlert } from "../../lib/alert-messages";
import { globalInputStyles } from "../../styles";
import { recordStyles as styles } from "./styles";
import { VideoFlowInputParams } from "./video-stack-types";
// TerminateUploadStream
interface VideoDetailsProps {
navigation: any;
route?: any;
}
export default function VideoDetails({
navigation,
route,
}: VideoDetailsProps): React.JSX.Element {
const { hasPermission, requestPermission } = useCameraPermission();
const { mode, videoId } = route.params;
if (mode === "start-video" && !hasPermission) {
requestPermission();
}
// Initial state values based on mode
const initialState =
mode === "save-video" && route.params ? route.params : {};
// Session name input
// Should session name be required?
const [sessionName, setSessionName] = useState<string>(
initialState.sessionName || "",
);
// Game type dropdown
const [gameTypeOpen, setGameTypeOpen] = useState<boolean>(false);
const [gameType, setGameType] = useState<string | null>(
initialState.gameType || null,
);
const [gameTypes, setGameTypes] = useState([
{ label: "Free Play", value: "freePlay" },
{ label: "Straight Pool", value: "straightPool" },
{ label: "Nine Ball", value: "nineBall" },
]);
const onGameTypeOpen = useCallback(() => {
setTableSizeOpen(false);
}, []);
// Table size dropdown
const [tableSizeOpen, setTableSizeOpen] = useState<boolean>(false);
const [tableSize, setTableSize] = useState<string>(
initialState.tableSize || "",
);
const [tableSizes, setTableSizes] = useState([
{ label: `9'`, value: "nineFoot" },
{ label: `8'`, value: "eightFoot" },
{ label: "7", value: "sevenFoot" },
]);
const onTableSizeOpen = useCallback(() => {
setGameTypeOpen(false);
}, []);
const [TerminateUploadStream, { loading, error }] =
gql.useTerminateUploadStreamMutation();
const handleSubmit = async () => {
if (mode === "start-video" && !hasPermission) {
return showAlert("camera");
}
if (mode === "start-video") {
const params: VideoFlowInputParams = {
sessionName: sessionName,
gameType: gameType,
tableSize: tableSize,
};
navigation.push("Camera", params);
} else {
try {
console.log(videoId, sessionName, tableSize, gameType);
const res = await TerminateUploadStream({
variables: {
videoId: videoId,
videoName: sessionName,
tableSize: tableSize,
gameType: gameType,
},
});
console.log(res);
navigation.push("Tabs");
} catch (err) {
console.error(error);
return showAlert("terminateUpload");
}
}
};
const dropDownStyles = {
style: globalInputStyles.dropdownStyle,
};
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.container}>
<Text style={styles.headerText}>
{mode === "start-video" ? "Record Session" : "Save Session"}
</Text>
<View style={globalInputStyles.dropdownContainer}>
<Text style={globalInputStyles.dropdownTitle}>Session Name</Text>
<TextInput
style={globalInputStyles.input}
placeholder="Session name"
autoCapitalize="none"
value={sessionName}
onChangeText={setSessionName}
/>
<Text style={globalInputStyles.dropdownTitle}>Game Type</Text>
<DropDownPicker
zIndex={3000}
zIndexInverse={1000}
open={gameTypeOpen}
value={gameType}
items={gameTypes}
setOpen={setGameTypeOpen}
setValue={setGameType}
setItems={setGameTypes}
onOpen={onGameTypeOpen}
{...dropDownStyles}
/>
<Text style={globalInputStyles.dropdownTitle}>Table size</Text>
<DropDownPicker
zIndex={2000}
zIndexInverse={2000}
open={tableSizeOpen}
value={tableSize}
items={tableSizes}
setOpen={setTableSizeOpen}
setValue={setTableSize}
setItems={setTableSizes}
onOpen={onTableSizeOpen}
{...dropDownStyles}
/>
</View>
<View style={styles.buttonContainer}>
{mode === "start-video" && (
<TouchableOpacity
style={styles.buttonStyle}
onPress={() => navigation.goBack()}
>
<Text style={styles.buttonText}>Back</Text>
</TouchableOpacity>
)}
<TouchableOpacity style={styles.buttonStyle} onPress={handleSubmit}>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>
{mode === "start-video" ? "Next" : "Save"}
</Text>
)}
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
);
}

View File

@@ -0,0 +1,6 @@
export interface VideoFlowInputParams {
sessionName?: string;
gameType: string;
tableSize: string;
videoId?: number;
}