Stores and restores settings to/from local AsyncStorage
This commit is contained in:
parent
53369bb0a4
commit
fbcbd67a1d
39
App.tsx
39
App.tsx
|
@ -55,13 +55,30 @@ export default function Main() {
|
||||||
const [sampleId, setSampleId] = useState<string>('');
|
const [sampleId, setSampleId] = useState<string>('');
|
||||||
const [barCodeId, setBarCodeId] = useState<string>('');
|
const [barCodeId, setBarCodeId] = useState<string>('');
|
||||||
const [sampleDate, setSampleDate] = useState<Date>(new Date());
|
const [sampleDate, setSampleDate] = useState<Date>(new Date());
|
||||||
const [locationStr, setLocationStr] = useState<string>('4321');
|
const [locationStr, setLocationStr] = useState<string>('0000');
|
||||||
const [errorMessage, setErrorMessage] = useState<string>('');
|
const [errorMessage, setErrorMessage] = useState<string>('');
|
||||||
const [samples, setSamples] = useState<Sample[]>([]);
|
const [samples, setSamples] = useState<Sample[]>([]);
|
||||||
const [lineCounts, setLineCounts] = useState<LineCount[]>([]);
|
const [lineCounts, setLineCounts] = useState<LineCount[]>([]);
|
||||||
const [cameraType, setCameraType] = useState<CameraType>('back');
|
const [cameraType, setCameraType] = useState<CameraType>('back');
|
||||||
|
const [numCopies, setNumCopies] = useState<number>(0);
|
||||||
|
|
||||||
|
const defaultsInitializers = {
|
||||||
|
'default.cameraType': (s: string) => setCameraType(s as CameraType),
|
||||||
|
'default.numCopies': (s: string) => setNumCopies(parseInt(s, 10)),
|
||||||
|
'default.locationStr': (s: string) => setLocationStr(s),
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
AsyncStorage.multiGet(Object.keys(defaultsInitializers)).then(storedDefaults => {
|
||||||
|
console.log('storedDefaults', storedDefaults);
|
||||||
|
storedDefaults.forEach(d => {
|
||||||
|
if (d[1] !== null) {
|
||||||
|
// @ts-ignore
|
||||||
|
defaultsInitializers[d[0]](d[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
BarCodeScanner.requestPermissionsAsync().then((value: PermissionResponse) => {
|
BarCodeScanner.requestPermissionsAsync().then((value: PermissionResponse) => {
|
||||||
if (value.granted) {
|
if (value.granted) {
|
||||||
setAppState(BarcodeScannerAppState.DEFAULT);
|
setAppState(BarcodeScannerAppState.DEFAULT);
|
||||||
|
@ -238,6 +255,7 @@ export default function Main() {
|
||||||
case BarcodeScannerAppState.PRINTING:
|
case BarcodeScannerAppState.PRINTING:
|
||||||
return <View style={styles.container}>
|
return <View style={styles.container}>
|
||||||
<PrintingMessage
|
<PrintingMessage
|
||||||
|
numCopies={numCopies}
|
||||||
onCancel={_printed}
|
onCancel={_printed}
|
||||||
id={sampleId}
|
id={sampleId}
|
||||||
barCodeId={barCodeId}
|
barCodeId={barCodeId}
|
||||||
|
@ -275,10 +293,27 @@ export default function Main() {
|
||||||
case BarcodeScannerAppState.SETTINGS:
|
case BarcodeScannerAppState.SETTINGS:
|
||||||
return <SettingsScreen
|
return <SettingsScreen
|
||||||
cameraType={cameraType}
|
cameraType={cameraType}
|
||||||
|
numCopies={numCopies}
|
||||||
locationStr={locationStr}
|
locationStr={locationStr}
|
||||||
onSave={(newCameraType: CameraType, newLocationStr: string) => {
|
onSave={(newCameraType: CameraType, newNumCopies: number, newLocationStr: string) => {
|
||||||
setCameraType(newCameraType);
|
setCameraType(newCameraType);
|
||||||
|
setNumCopies(newNumCopies);
|
||||||
setLocationStr(newLocationStr);
|
setLocationStr(newLocationStr);
|
||||||
|
|
||||||
|
console.log(newCameraType);
|
||||||
|
console.log(newLocationStr);
|
||||||
|
console.log(newNumCopies);
|
||||||
|
|
||||||
|
AsyncStorage.multiSet([
|
||||||
|
['default.cameraType', newCameraType as string],
|
||||||
|
['default.locationStr', newLocationStr],
|
||||||
|
['default.numCopies', newNumCopies.toString()],
|
||||||
|
]).then(() => {
|
||||||
|
console.log('New defaults stored.');
|
||||||
|
AsyncStorage.multiGet(Object.keys(defaultsInitializers)).then(storedDefaults => {
|
||||||
|
console.log('stored defaults after saving Settings:', storedDefaults);
|
||||||
|
});
|
||||||
|
});
|
||||||
_home();
|
_home();
|
||||||
}}
|
}}
|
||||||
onCancel={_home}
|
onCancel={_home}
|
||||||
|
|
|
@ -28,7 +28,7 @@ const _save = (props: PrintingProps): Promise<void> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const _print = async (props: PrintingProps): Promise<void> => {
|
const _print = async (props: PrintingProps): Promise<void> => {
|
||||||
const numCopies = 2; // Number of copies to print
|
const numCopies = props.numCopies; // Number of copies to print
|
||||||
const units = 'mm';
|
const units = 'mm';
|
||||||
const pageSize = 28.6;
|
const pageSize = 28.6;
|
||||||
const pageWidth = `${pageSize}${units}`;
|
const pageWidth = `${pageSize}${units}`;
|
||||||
|
@ -111,12 +111,7 @@ const _print = async (props: PrintingProps): Promise<void> => {
|
||||||
const pagesArray = [];
|
const pagesArray = [];
|
||||||
|
|
||||||
for (let i=0; i<numCopies; i++) {
|
for (let i=0; i<numCopies; i++) {
|
||||||
// TODO: Comment out these two lines, because this is just for testing.
|
const svgString = await qrcode.toString(props.id, {
|
||||||
const fakeBarcodeId = `${i}`.padStart(9, '0');
|
|
||||||
const fakeDate = new Date();
|
|
||||||
const fakeId = fakeBarcodeId + '-' + format(fakeDate, 'yyyyMMddHH') + '-' + `${i}`.padStart(2, '0') + '-' + props.location;
|
|
||||||
|
|
||||||
const svgString = await qrcode.toString(fakeId, {
|
|
||||||
width: 72, // 20mm
|
width: 72, // 20mm
|
||||||
height: 72,
|
height: 72,
|
||||||
margin: 10,
|
margin: 10,
|
||||||
|
@ -132,18 +127,18 @@ const _print = async (props: PrintingProps): Promise<void> => {
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<div class="circle"></div>
|
<div class="circle"></div>
|
||||||
${svgString}
|
${svgString}
|
||||||
<div class="date">${format(fakeDate, 'yyyy-MM-dd')}</div>
|
<div class="date">${format(props.date, 'yyyy-MM-dd')}</div>
|
||||||
<div class="time">
|
<div class="time">
|
||||||
T<br />
|
T<br />
|
||||||
${format(fakeDate, 'HH')}<br />
|
${format(props.date, 'HH')}<br />
|
||||||
${`${i}`.padStart(2, '0')}
|
${format(props.date, 'mm')}
|
||||||
</div>
|
</div>
|
||||||
<div class="location">
|
<div class="location">
|
||||||
L<br />
|
L<br />
|
||||||
${props.location.slice(0, 2)}<br />
|
${props.location.slice(0, 2)}<br />
|
||||||
${props.location.slice(2)}<br />
|
${props.location.slice(2)}<br />
|
||||||
</div>
|
</div>
|
||||||
<div class="barCodeId">#${fakeBarcodeId}</div>
|
<div class="barCodeId">#${props.barCodeId}</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ export const Scanner = (props: ScannerProps): ReactElement => {
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.centerMiddle}>
|
<View style={styles.centerMiddle}>
|
||||||
<View style={styles.captureBox}/>
|
<View style={styles.captureBox}/>
|
||||||
<Subheading style={styles.shadow}>
|
|
||||||
Place ID card with the barcode facing the camera. Keep the barcode in the green box.
|
|
||||||
</Subheading>
|
|
||||||
</View>
|
</View>
|
||||||
|
<Subheading style={styles.shadow}>
|
||||||
|
Instruct the patient to hold their card up with the barcode facing the camera. Keep the barcode in the orange box.
|
||||||
|
</Subheading>
|
||||||
<View style={styles.centerMiddle}>
|
<View style={styles.centerMiddle}>
|
||||||
<Button
|
<Button
|
||||||
mode="text"
|
mode="text"
|
||||||
|
@ -78,6 +78,7 @@ export const IdNumberInput = (props: ScannerProps): ReactElement => {
|
||||||
onChangeText={inputStr => setInputStr(inputStr)}
|
onChangeText={inputStr => setInputStr(inputStr)}
|
||||||
mode="outlined"
|
mode="outlined"
|
||||||
theme={DefaultTheme}
|
theme={DefaultTheme}
|
||||||
|
keyboardType="numeric"
|
||||||
/>
|
/>
|
||||||
<HelperText type="error" visible={hasErrors()}>
|
<HelperText type="error" visible={hasErrors()}>
|
||||||
ID number must be exactly 9 digits. No other characters are allowed.
|
ID number must be exactly 9 digits. No other characters are allowed.
|
||||||
|
|
|
@ -4,13 +4,27 @@ import {DefaultTheme, Subheading, Title, RadioButton, Paragraph, TextInput, Help
|
||||||
import {CameraType, SettingsScreenProps} from '../models/ElementProps';
|
import {CameraType, SettingsScreenProps} from '../models/ElementProps';
|
||||||
import {colors, styles} from './Styles';
|
import {colors, styles} from './Styles';
|
||||||
|
|
||||||
|
const _stringToInt = (inputStr: string): number => {
|
||||||
|
const num = parseInt(inputStr || '0', 10);
|
||||||
|
if (!isNaN(num)) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
export const SettingsScreen = (props: SettingsScreenProps): ReactElement => {
|
export const SettingsScreen = (props: SettingsScreenProps): ReactElement => {
|
||||||
const [newCameraType, setNewCameraType] = useState<CameraType>(props.cameraType);
|
const [newCameraType, setNewCameraType] = useState<CameraType>(props.cameraType);
|
||||||
|
const [newNumCopies, setNewNumCopies] = useState<number>(props.numCopies);
|
||||||
const [newLocationStr, setNewLocationStr] = useState<string>(props.locationStr);
|
const [newLocationStr, setNewLocationStr] = useState<string>(props.locationStr);
|
||||||
|
|
||||||
const pattern = /^[\d]{4}$/;
|
const _numCopiesHasErrors = () => {
|
||||||
const hasErrors = () => {
|
return newNumCopies <= 0 || newNumCopies > 10;
|
||||||
return !pattern.test(newLocationStr);
|
};
|
||||||
|
|
||||||
|
const locPattern = /^[\d]{4}$/;
|
||||||
|
const _locHasErrors = () => {
|
||||||
|
return !locPattern.test(newLocationStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
return <View style={styles.settings}>
|
return <View style={styles.settings}>
|
||||||
|
@ -34,6 +48,24 @@ export const SettingsScreen = (props: SettingsScreenProps): ReactElement => {
|
||||||
</RadioButton.Group>
|
</RadioButton.Group>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<View style={{marginBottom: 40}}>
|
||||||
|
<Subheading style={{color: DefaultTheme.colors.text}}>Copies of labels</Subheading>
|
||||||
|
<Paragraph style={{color: DefaultTheme.colors.text}}>
|
||||||
|
Input the number of sets of labels to print for each patient
|
||||||
|
</Paragraph>
|
||||||
|
<TextInput
|
||||||
|
label="# of copies"
|
||||||
|
value={newNumCopies.toString()}
|
||||||
|
onChangeText={inputStr => setNewNumCopies(_stringToInt(inputStr))}
|
||||||
|
mode="outlined"
|
||||||
|
theme={DefaultTheme}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
<HelperText type="error" visible={_numCopiesHasErrors()}>
|
||||||
|
Please enter a number from 1 to 10.
|
||||||
|
</HelperText>
|
||||||
|
</View>
|
||||||
|
|
||||||
<View style={{marginBottom: 10}}>
|
<View style={{marginBottom: 10}}>
|
||||||
<Subheading style={{color: DefaultTheme.colors.text}}>Location Code</Subheading>
|
<Subheading style={{color: DefaultTheme.colors.text}}>Location Code</Subheading>
|
||||||
<Paragraph style={{color: DefaultTheme.colors.text}}>
|
<Paragraph style={{color: DefaultTheme.colors.text}}>
|
||||||
|
@ -46,8 +78,9 @@ export const SettingsScreen = (props: SettingsScreenProps): ReactElement => {
|
||||||
onChangeText={inputStr => setNewLocationStr(inputStr)}
|
onChangeText={inputStr => setNewLocationStr(inputStr)}
|
||||||
mode="outlined"
|
mode="outlined"
|
||||||
theme={DefaultTheme}
|
theme={DefaultTheme}
|
||||||
|
keyboardType="numeric"
|
||||||
/>
|
/>
|
||||||
<HelperText type="error" visible={hasErrors()}>
|
<HelperText type="error" visible={_locHasErrors()}>
|
||||||
Location number must be exactly 4 digits. No other characters are allowed.
|
Location number must be exactly 4 digits. No other characters are allowed.
|
||||||
</HelperText>
|
</HelperText>
|
||||||
<Button
|
<Button
|
||||||
|
@ -55,8 +88,8 @@ export const SettingsScreen = (props: SettingsScreenProps): ReactElement => {
|
||||||
mode="contained"
|
mode="contained"
|
||||||
color={colors.primary}
|
color={colors.primary}
|
||||||
style={{marginBottom: 10}}
|
style={{marginBottom: 10}}
|
||||||
disabled={hasErrors()}
|
disabled={_locHasErrors() || _numCopiesHasErrors()}
|
||||||
onPress={() => props.onSave(newCameraType, newLocationStr)}
|
onPress={() => props.onSave(newCameraType, newNumCopies, newLocationStr)}
|
||||||
>Save</Button>
|
>Save</Button>
|
||||||
<Button
|
<Button
|
||||||
icon="cancel"
|
icon="cancel"
|
||||||
|
|
|
@ -36,9 +36,9 @@ const _common = StyleSheet.create({
|
||||||
export const styles = StyleSheet.create({
|
export const styles = StyleSheet.create({
|
||||||
captureBox: {
|
captureBox: {
|
||||||
borderStyle: 'solid',
|
borderStyle: 'solid',
|
||||||
borderColor: 'green',
|
borderColor: colors.accent,
|
||||||
borderWidth: 10,
|
borderWidth: 10,
|
||||||
height: '30%',
|
height: '40%',
|
||||||
width: '90%',
|
width: '90%',
|
||||||
borderRadius: 20,
|
borderRadius: 20,
|
||||||
},
|
},
|
||||||
|
@ -77,7 +77,8 @@ export const styles = StyleSheet.create({
|
||||||
color: colors.onBackground,
|
color: colors.onBackground,
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
marginHorizontal: '15%',
|
marginHorizontal: '15%',
|
||||||
marginVertical: 40,
|
marginTop: 0,
|
||||||
|
marginBottom: 40,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
textShadowOffset: {width: 0, height: 0},
|
textShadowOffset: {width: 0, height: 0},
|
||||||
textShadowRadius: 4,
|
textShadowRadius: 4,
|
||||||
|
|
|
@ -30,8 +30,9 @@ export interface InputLineCountScreenProps extends ElementProps {
|
||||||
|
|
||||||
export interface SettingsScreenProps extends ElementProps {
|
export interface SettingsScreenProps extends ElementProps {
|
||||||
cameraType: CameraType;
|
cameraType: CameraType;
|
||||||
|
numCopies: number;
|
||||||
locationStr: string;
|
locationStr: string;
|
||||||
onSave: (newCameraType: CameraType, newLocationStr: string) => void;
|
onSave: (newCameraType: CameraType, newNumCopies: number, newLocationStr: string) => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,5 +43,6 @@ export interface ScannerProps extends ElementProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PrintingProps extends BarCodeProps {
|
export interface PrintingProps extends BarCodeProps {
|
||||||
|
numCopies: number;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue