2020-09-01 02:12:32 +00:00
|
|
|
import React, {ReactElement, useEffect, useState} from 'react';
|
|
|
|
import {Text, View} from 'react-native';
|
|
|
|
// @ts-ignore
|
2020-08-29 03:40:55 +00:00
|
|
|
import Barcode from 'react-native-barcode-builder';
|
2020-09-01 02:12:32 +00:00
|
|
|
import {Button} from 'react-native-paper';
|
2020-08-29 03:40:55 +00:00
|
|
|
import {BarCodeProps, ButtonProps, PrintingProps} from '../models/ElementProps';
|
2020-09-01 02:12:32 +00:00
|
|
|
import {colors, styles} from './Styles';
|
|
|
|
import AsyncStorage from '@react-native-community/async-storage';
|
|
|
|
import * as Print from 'expo-print';
|
|
|
|
|
|
|
|
enum PrintStatus {
|
|
|
|
SAVING = 'SAVING',
|
|
|
|
PRINTING = 'PRINTING',
|
|
|
|
DONE = 'DONE',
|
|
|
|
}
|
|
|
|
|
2020-09-01 03:33:49 +00:00
|
|
|
const _renderBarCodeRects = (props: PrintingProps): string => {
|
|
|
|
const dataStr = _propsToDataString(props);
|
|
|
|
const rects: string[] = [];
|
|
|
|
|
|
|
|
// TODO: set base width from label width in pixels
|
|
|
|
// 2 inches = 190 pixels
|
|
|
|
// for now, just guesstimate.
|
|
|
|
const baseWidth = 7;
|
|
|
|
|
|
|
|
for (let i = 0; i < dataStr.length; i++) {
|
|
|
|
// TODO: Convert dataStr to barcode rectangles with x, y, width, height
|
|
|
|
// barcodejs library has some useful stuff?
|
|
|
|
// Or maybe somehow use something in the guts of react-native-barcode-builder?
|
|
|
|
// For now, just put in some dummy x values and widths.
|
|
|
|
rects.push(`<rect width="${Math.floor(Math.random() * baseWidth)}" height="20" x="${baseWidth * i}" y="70" fill="black" />`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rects.join(' ')
|
|
|
|
}
|
|
|
|
|
2020-09-01 02:12:32 +00:00
|
|
|
const _propsToDataString = (props: BarCodeProps): string => {
|
|
|
|
return `${props.id}-${props.date.getTime()}-${props.location}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
const _save = (props: PrintingProps): Promise<void> => {
|
|
|
|
const storageKey = _propsToDataString(props);
|
|
|
|
const storageVal = {
|
|
|
|
id: props.id,
|
|
|
|
date: props.date,
|
|
|
|
location: props.location,
|
|
|
|
};
|
|
|
|
return AsyncStorage.setItem(storageKey, JSON.stringify(storageVal));
|
|
|
|
}
|
|
|
|
|
|
|
|
const _print = (props: PrintingProps): Promise<void> => {
|
2020-09-01 03:33:49 +00:00
|
|
|
const dataStr = _propsToDataString(props);
|
2020-09-01 02:12:32 +00:00
|
|
|
return Print.printAsync({
|
|
|
|
html: `
|
|
|
|
<style>
|
2020-09-01 03:33:49 +00:00
|
|
|
@media print {
|
|
|
|
@page {
|
|
|
|
size: 2in 1.25in;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
html, body {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
div.box {
|
|
|
|
width: 2in;
|
|
|
|
height: 1.25in;
|
|
|
|
color: #000;
|
|
|
|
text-align: center;
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
div.box p {
|
|
|
|
font-size: 10pt;
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
svg {
|
|
|
|
position: absolute;
|
|
|
|
bottom: 0;
|
|
|
|
left: 0;
|
|
|
|
}
|
2020-09-01 02:12:32 +00:00
|
|
|
}
|
|
|
|
</style>
|
2020-09-01 03:33:49 +00:00
|
|
|
<div class="box">
|
|
|
|
<p>ID#: ${props.id}</p>
|
|
|
|
<p>Date: ${props.date.toLocaleDateString()} ${props.date.toLocaleTimeString()}</p>
|
|
|
|
<p>Loc#: ${props.location}</p>
|
|
|
|
<svg width="190" height="90" id="barCode">
|
|
|
|
${_renderBarCodeRects(props)}
|
|
|
|
</svg>
|
|
|
|
<p>${dataStr}</p>
|
|
|
|
</div>
|
2020-09-01 02:12:32 +00:00
|
|
|
`,
|
|
|
|
});
|
|
|
|
}
|
2020-08-29 03:40:55 +00:00
|
|
|
|
|
|
|
export const PrintButton = (props: ButtonProps): ReactElement => {
|
|
|
|
return <Button
|
2020-09-01 02:12:32 +00:00
|
|
|
icon="printer"
|
|
|
|
mode="contained"
|
|
|
|
color={colors.accent}
|
2020-08-29 03:40:55 +00:00
|
|
|
onPress={props.onClicked}
|
2020-09-01 02:12:32 +00:00
|
|
|
style={styles.btnLg}
|
|
|
|
labelStyle={styles.btnLg}
|
|
|
|
>Print Labels</Button>;
|
2020-08-29 03:40:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const PrintingMessage = (props: PrintingProps): ReactElement => {
|
2020-09-01 02:12:32 +00:00
|
|
|
const [statusStr, setStatusStr] = useState<string>('Saving data...');
|
|
|
|
const [printStatus, setPrintStatus] = useState<PrintStatus>(PrintStatus.SAVING);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
_save(props).finally(() => {
|
|
|
|
setPrintStatus(PrintStatus.PRINTING);
|
|
|
|
setStatusStr('Data saved. Printing...')
|
|
|
|
_print(props).finally(() => {
|
|
|
|
setPrintStatus(PrintStatus.DONE);
|
|
|
|
setStatusStr('Data sent to printer.');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
const RetryButton = (): ReactElement | null => {
|
|
|
|
if (printStatus === PrintStatus.DONE) {
|
|
|
|
return <Button
|
|
|
|
icon="reload"
|
|
|
|
onPress={() => _print(props)}
|
|
|
|
color={colors.onBackground}
|
|
|
|
style={styles.btnLg}
|
|
|
|
labelStyle={styles.btnLg}
|
|
|
|
>Print again</Button>
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return <View style={styles.container}>
|
|
|
|
<View style={styles.preview}>
|
|
|
|
<BarCodeDisplay id={props.id} date={props.date} location={props.location} />
|
|
|
|
<BarCodeDisplay id={props.id} date={props.date} location={props.location} />
|
|
|
|
</View>
|
|
|
|
<View style={styles.container}>
|
|
|
|
<Text style={styles.heading}>{statusStr}</Text>
|
|
|
|
<RetryButton />
|
|
|
|
<Button
|
|
|
|
icon="cancel"
|
|
|
|
mode={printStatus === PrintStatus.DONE ? 'contained' : 'text'}
|
|
|
|
color={printStatus === PrintStatus.DONE ? colors.accent : colors.onBackground}
|
|
|
|
onPress={props.onCancel}
|
|
|
|
style={styles.btnLg}
|
|
|
|
labelStyle={styles.btnLg}
|
|
|
|
>{printStatus === PrintStatus.DONE ? 'Done' : 'Cancel'}</Button>
|
|
|
|
</View>
|
2020-08-29 03:40:55 +00:00
|
|
|
</View>;
|
|
|
|
}
|
|
|
|
|
2020-09-01 02:12:32 +00:00
|
|
|
|
2020-08-29 03:40:55 +00:00
|
|
|
export const BarCodeDisplay = (props: BarCodeProps): ReactElement => {
|
2020-09-01 02:12:32 +00:00
|
|
|
const data = _propsToDataString(props);
|
|
|
|
return <View style={styles.printPreview}>
|
2020-08-29 03:40:55 +00:00
|
|
|
<Text style={styles.label}>ID#: {props.id}</Text>
|
|
|
|
<Text style={styles.label}>Date: {props.date.toLocaleDateString()}, {props.date.toLocaleTimeString()}</Text>
|
|
|
|
<Text style={styles.label}>Location {props.location}</Text>
|
2020-09-01 02:12:32 +00:00
|
|
|
<Barcode width={1.1} height={40} text={data} value={data} format={'CODE128'}/>
|
2020-08-29 03:40:55 +00:00
|
|
|
</View>;
|
|
|
|
}
|