Samuel Assani d1728951c5 first Push
2021-11-09 14:04:49 +01:00

220 lines
7.3 KiB
JavaScript

import React, { Component } from 'react';
import { AppState, BackHandler } from 'react-native';
import {
BarcodeTracking,
BarcodeTrackingBasicOverlay,
BarcodeTrackingSettings,
Symbology,
} from 'scandit-react-native-datacapture-barcode';
import {
Camera,
CameraSettings,
DataCaptureContext,
DataCaptureView,
FrameSourceState,
VideoResolution,
Brush,
Color,
Anchor,
PointWithUnit,
NumberWithUnit,
MeasureUnit,
Feedback,
} from 'scandit-react-native-datacapture-core';
import { requestCameraPermissionsIfNeeded } from './camera-permission-handler';
import BarcodeListView from './BarcodeListView';
import { styles, values } from './styles';
export default class ScanPage extends Component {
constructor() {
super();
this.dataCaptureContext = DataCaptureContext.forLicenseKey('AcIwhhkoOMpwFfAGbTcGTugBWCFSANJ7YliERzpN2LmfSSjTSgOZY9Fd3mdfO5bd51NpwplA+Y5QdEuLujKw1wlgzGSsS1uz9zWYoGZTFdm8XJwIy1ApIJN6reMOIjfFnCjM0yo26iwsOkyPnCIhWxrh2TmST/CSNs2WhTLyah688LGBdhRuA3JS6OQ2J1IiCtH2BgqxPCUaqKE2CvqrRxpXCAzbeARH9Q0eoJCA4r+wdgpZ7Q578hL42QdRKJevrBOs68UoMkO9TloguQBMH8uL0CArZs0gXIWrOps0qf0n+Y3pSFrdkowltRvTaF0rRR/iL/doqVCcVnSwkNNTzJbs0auyGrh9i/xHfxsIAAFI7eqeY+CybMHM34vaKAXYcBCXRckVPnAcqmtenpC1oP3EB++jmDoSd5+RGZsQ4gzh1PKfWTJU3WCahPWFoaNoGX5/AAbsFqvJdc3Wc7RBaNrbxy80n9LUf/RMtBEuOqt+7bVNqQ2OCeWwu6O6uuaxfUgFOzabMWqDCrYZC0lbC1lX6rYwhWEu0yA0/rGMbJ/v64iuU/lvW0Cob874f8aGiEdTqIVTJzNWsa2klTaNZOAX1yJUH0DvoWqkWRjY06aP+pTBAgC7cr66ZlojMX9btOZMor/xkulbIM0DJwEGQkTXRyQgrP+Vj2K1vkeMU5DnwnjADdZnX2vArDjMjuUx1f79LK1P2C9pvjKSsn2qW4HkKfQveBu514hQk9vVBCvmZ9uJ8roSrm57NVoRm+mWw6X6SsibNVHY00P7LEFAWwObP+ibVB3XiPHJJGVW/UO5ZtsPpaEtFFIroqXV')
this.viewRef = React.createRef();
this.onCaptureResults = this.onCaptureResults.bind(this);
this.onCardPress = this.onCardPress.bind(this);
this.onClearPress = this.onClearPress.bind(this);
// Store results that the barcode scanner is capturing.
this.results = {};
this.state = {
show: false,
capturedResults: {} // The scan results that will be passed to the barcode list view.
};
}
componentDidMount() {
AppState.addEventListener('change', this.handleAppStateChange);
this.setupScanning();
// Keep Scandit logo visible on screen when scanning.
this.viewRef.current.logoAnchor = Anchor.BottomRight;
this.viewRef.current.logoOffset = this.logoOffset();
this.props.navigation.addListener('focus', () => {
this.results = {};
});
}
componentWillUnmount() {
AppState.removeEventListener('change', this.handleAppStateChange);
this.dataCaptureContext.dispose();
}
handleAppStateChange = async (nextAppState) => {
if (nextAppState.match(/inactive|background/)) {
this.stopCapture();
} else {
this.startCapture();
}
}
startCapture() {
this.startCamera();
this.barcodeTracking.isEnabled = true;
}
stopCapture() {
this.barcodeTracking.isEnabled = false;
this.stopCamera();
}
stopCamera() {
if (this.camera) {
this.camera.switchToDesiredState(FrameSourceState.Off);
}
}
startCamera() {
if (!this.camera) {
// Use the world-facing (back) camera and set it as the frame source of the context. The camera is off by
// default and must be turned on to start streaming frames to the data capture context for recognition.
this.camera = Camera.default;
this.dataCaptureContext.setFrameSource(this.camera);
const cameraSettings = new CameraSettings();
cameraSettings.preferredResolution = VideoResolution.FullHD;
this.camera.applySettings(cameraSettings);
}
// Switch camera on to start streaming frames and enable the barcode tracking mode.
// The camera is started asynchronously and will take some time to completely turn on.
requestCameraPermissionsIfNeeded()
.then(() => this.camera.switchToDesiredState(FrameSourceState.On))
.catch(() => BackHandler.exitApp());
}
setupScanning() {
// The barcode tracking process is configured through barcode tracking settings
// which are then applied to the barcode tracking instance that manages barcode tracking.
const settings = new BarcodeTrackingSettings();
// The settings instance initially has all types of barcodes (symbologies) disabled. For the purpose of this
// sample we enable a very generous set of symbologies. In your own app ensure that you only enable the
// symbologies that your app requires as every additional enabled symbology has an impact on processing times.
settings.enableSymbologies([
Symbology.EAN13UPCA,
Symbology.EAN8,
Symbology.UPCE,
Symbology.Code39,
Symbology.Code128,
Symbology.DataMatrix,
Symbology.QR,
Symbology.MicroQR,
]);
// Create new barcode tracking mode with the settings from above.
this.barcodeTracking = BarcodeTracking.forContext(this.dataCaptureContext, settings);
// Register a listener to get informed whenever a new barcode is tracked.
this.barcodeTrackingListener = {
didUpdateSession: (_, session) => {
this.results = {};
Object.values(session.trackedBarcodes).forEach(trackedBarcode => {
const { data, symbology } = trackedBarcode.barcode;
this.results[data] = { data, symbology };
});
}
};
this.barcodeTracking.addListener(this.barcodeTrackingListener);
// Add a barcode tracking overlay to the data capture view to render the location of captured barcodes on top of
// the video preview. This is optional, but recommended for better visual feedback.
const overlay = BarcodeTrackingBasicOverlay.withBarcodeTrackingForView(this.barcodeTracking, this.viewRef.current);
// Implement the BarcodeTrackingBasicOverlayListener interface.
// The method BarcodeTrackingBasicOverlayListener.brushForTrackedBarcode() is invoked every time a new tracked
// barcode appears and it can be used to set a brush that will highlight that specific barcode in the overlay.
overlay.listener = {
brushForTrackedBarcode: (overlay, trackedBarcode) => new Brush(
Color.fromRGBA(255, 255, 255, 0.4),
Color.fromRGBA(255, 255, 255, 1),
2
)
};
}
logoOffset() {
return new PointWithUnit(
new NumberWithUnit(0, MeasureUnit.Pixel),
new NumberWithUnit(-values.cardMinHeight, MeasureUnit.DIP)
);
}
onCaptureResults() {
// Do nothing when the card is expanded.
if (this.state.show) {
return;
}
if (Object.keys(this.results).length !== 0) {
Feedback.defaultFeedback.emit();
}
this.setState({
capturedResults: Object.assign({}, this.results)
})
this.results = {};
}
onCardPress() {
if (this.state.show) {
this.startCapture();
} else {
this.stopCapture();
}
this.setState({
show: !this.state.show
})
}
onClearPress() {
this.startCapture();
this.setState({
show: false
})
}
render() {
const { show, capturedResults } = this.state;
return (
<>
<DataCaptureView style={styles.scanContainer} context={this.dataCaptureContext} ref={this.viewRef} />
<BarcodeListView
show={show}
results={capturedResults}
onCaptureResults={this.onCaptureResults}
onClearPress={this.onClearPress}
onCardPress={this.onCardPress}
/>
</>
);
};
}