mirror of
https://github.com/serratus/quaggaJS.git
synced 2026-08-13 05:31:37 +08:00
added es-lint config to sandbox
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "./node_modules/eslint-config-netconomy/react.js",
|
||||
"parser": "babel-eslint",
|
||||
"rules": {
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="static/style.css" />
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0" />
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,500' rel='stylesheet' type='text/css'>
|
||||
|
||||
</head>
|
||||
|
||||
<body style="margin: 0">
|
||||
|
||||
@@ -10,11 +10,15 @@
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.9.0",
|
||||
"babel-eslint": "^6.1.2",
|
||||
"babel-loader": "^6.2.4",
|
||||
"babel-plugin-transform-class-properties": "^6.9.0",
|
||||
"babel-preset-es2015-webpack": "^6.4.1",
|
||||
"babel-preset-react": "^6.5.0",
|
||||
"babel-preset-stage-0": "^6.5.0",
|
||||
"eslint": "^3.0.1",
|
||||
"eslint-config-netconomy": "^300.0.0",
|
||||
"eslint-plugin-react": "^5.2.2",
|
||||
"webpack": "^2.1.0-beta.7"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,33 +1,38 @@
|
||||
import React from 'react';
|
||||
import AppBar from 'material-ui/AppBar';
|
||||
import Drawer from 'material-ui/Drawer';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import FloatingActionButton from 'material-ui/FloatingActionButton';
|
||||
import ContentAdd from 'material-ui/svg-icons/content/add';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {Card, CardTitle, CardText} from 'material-ui/Card';
|
||||
import IconButton from 'material-ui/IconButton';
|
||||
import TuneIcon from 'material-ui/svg-icons/image/tune';
|
||||
|
||||
import Scanner from './Scanner';
|
||||
import ScanIcon from './ScanIcon';
|
||||
import ConfigView from './ConfigView';
|
||||
|
||||
export default class App extends React.Component {
|
||||
state = {
|
||||
drawerOpen: false,
|
||||
scanning: false,
|
||||
currentView: 'root',
|
||||
scannedCodes: [{
|
||||
codeResult: {
|
||||
code: "FANAVF1461710",
|
||||
format: "code_128"
|
||||
format: "code_128",
|
||||
},
|
||||
timestamp: new Date()
|
||||
}]
|
||||
timestamp: new Date(),
|
||||
}],
|
||||
};
|
||||
|
||||
_handleToggle = () => this.setState({drawerOpen: !this.state.drawerOpen});
|
||||
_handleToggle = () => {
|
||||
this.setState({drawerOpen: !this.state.drawerOpen});
|
||||
}
|
||||
_handleClose = () => this.setState({drawerOpen: false});
|
||||
_onRequestChange = drawerOpen => this.setState({drawerOpen});
|
||||
_onRequestChange = drawerOpen => {
|
||||
this.setState({drawerOpen});
|
||||
};
|
||||
|
||||
_startScanning = (e) => {
|
||||
e.preventDefault();
|
||||
@@ -47,22 +52,27 @@ export default class App extends React.Component {
|
||||
.concat(this.state.scannedCodes)});
|
||||
}
|
||||
|
||||
_navigateTo = (route) => {
|
||||
this.setState({
|
||||
drawerOpen: false,
|
||||
currentView: route,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Drawer
|
||||
docked={false}
|
||||
width={200}
|
||||
open={this.state.drawerOpen}
|
||||
onRequestChange={this._onRequestChange}
|
||||
>
|
||||
<MenuItem onTouchTap={this._handleClose}>Menu Item</MenuItem>
|
||||
<MenuItem onTouchTap={this._handleClose}>Menu Item 2</MenuItem>
|
||||
<ConfigView />
|
||||
</Drawer>
|
||||
<AppBar
|
||||
style={{position: 'fixed', top: '0px'}}
|
||||
title="QuaggaJS"
|
||||
iconClassNameRight="muidocs-icon-navigation-expand-more"
|
||||
iconElementLeft={<IconButton onTouchTap={this._handleToggle}><TuneIcon /></IconButton>}
|
||||
onLeftIconButtonTouchTap={this._handleToggle}
|
||||
/>
|
||||
<FloatingActionButton
|
||||
@@ -80,7 +90,7 @@ export default class App extends React.Component {
|
||||
<FlatButton
|
||||
label="Cancel"
|
||||
primary={true}
|
||||
onTouchTap={this._stopScanning}/>
|
||||
onTouchTap={this._stopScanning}/>,
|
||||
]}
|
||||
modal={true}
|
||||
contentStyle={{width: '95%', maxWidth: '95%', height: '95%', maxHeight: '95%'}}
|
||||
@@ -89,7 +99,7 @@ export default class App extends React.Component {
|
||||
<Scanner onDetected={this._handleResult} onCancel={this._stopScanning} />
|
||||
</Dialog>
|
||||
<div style={{paddingTop: '64px'}}>
|
||||
{this.state.scannedCodes.map((scannedCode, i) => (
|
||||
{this.state.currentView === 'root' && this.state.scannedCodes.map((scannedCode, i) => (
|
||||
<Card key={i} style={{margin: '0.5em 0.25em 0em'}}>
|
||||
<CardTitle
|
||||
titleStyle={{textOverflow: 'ellipsis', overflow: 'hidden'}}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
import React from 'react';
|
||||
import {List, ListItem} from 'material-ui/List';
|
||||
import Subheader from 'material-ui/Subheader';
|
||||
import Toggle from 'material-ui/Toggle';
|
||||
import SelectField from 'material-ui/SelectField';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
|
||||
function generateItems(keyValuePairs) {
|
||||
return keyValuePairs.map(([value, label]) => (
|
||||
<MenuItem key={value} value={value} primaryText={label} />
|
||||
));
|
||||
}
|
||||
|
||||
const availableReaders = [
|
||||
['ean_reader', "EAN-13", true],
|
||||
['ean_8_reader', "EAN-8"],
|
||||
["upc_e_reader", "UPC-E"],
|
||||
["code_39_reader", "CODE 39", true],
|
||||
["codabar_reader", "Codabar"],
|
||||
["code_128_reader", "CODE 128", true],
|
||||
["i2of5_reader", "ITF", true],
|
||||
];
|
||||
|
||||
let configOptions = {
|
||||
width: [[640, "640px"], [800, "800px"], [1280, "1280px"], [1920, "1920px"]],
|
||||
height: [[480, "480px"], [600, "600px"], [720, "720px"], [1080, "1080px"]],
|
||||
facingMode: [["user", "user"], ["environment", "environment"]],
|
||||
aspectRatio: [[1, '1/1'], [4 / 3, '4/3'], [16 / 9, '16/9'], [21 / 9, '21/9']],
|
||||
deviceId: [],
|
||||
};
|
||||
|
||||
let items = Object.keys(configOptions).reduce((result, option) => ({
|
||||
...result,
|
||||
[option]: generateItems(configOptions[option]),
|
||||
}), {});
|
||||
|
||||
const selectStyle = {
|
||||
};
|
||||
const selectedItemStyle = {
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
};
|
||||
|
||||
export default class ConfigView extends React.Component {
|
||||
state = {
|
||||
devicesFetched: false,
|
||||
numOfWorkers: 2,
|
||||
...Object
|
||||
.keys(configOptions)
|
||||
.reduce((result, option) => ({...result, [option]: (configOptions[option][0] || [null])[0]}), {}),
|
||||
};
|
||||
|
||||
handleChange = (category, event, index, value) => {
|
||||
this.setState({[category]: value});
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
navigator.mediaDevices
|
||||
.enumerateDevices()
|
||||
.then((devices) => {
|
||||
const videoDevices = devices
|
||||
.filter(info => info.kind === 'videoinput')
|
||||
.map(videoDevice => ([
|
||||
videoDevice.deviceId,
|
||||
videoDevice.label,
|
||||
]));
|
||||
configOptions = {
|
||||
...configOptions,
|
||||
deviceId: videoDevices,
|
||||
};
|
||||
items = {
|
||||
...items,
|
||||
deviceId: generateItems(configOptions.deviceId),
|
||||
};
|
||||
this.setState({devicesFetched: true});
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Subheader>Constraints</Subheader>
|
||||
<div style={{paddingLeft: 16, paddingRight: 16}}>
|
||||
{Object.keys(items).map(option => (
|
||||
<SelectField fullWidth={true} key={option} style={selectStyle}
|
||||
labelStyle={selectedItemStyle}
|
||||
value={this.state[option]}
|
||||
onChange={this.handleChange.bind(this, option)}
|
||||
floatingLabelText={option}
|
||||
>
|
||||
{items[option]}
|
||||
</SelectField>
|
||||
))}
|
||||
</div>
|
||||
<List>
|
||||
<Subheader>General</Subheader>
|
||||
<ListItem primaryText="locate" secondaryText="Automatically detect position" rightToggle={<Toggle />} />
|
||||
<div style={{paddingLeft: 16, paddingRight: 16}}>
|
||||
<SelectField fullWidth={true} key={'numOfWorkers'}
|
||||
style={selectStyle}
|
||||
labelStyle={selectedItemStyle}
|
||||
value={this.state.numOfWorkers}
|
||||
onChange={this.handleChange.bind(this, 'numOfWorkers')}
|
||||
floatingLabelText='numOfWorkers'
|
||||
>
|
||||
{[0, 1, 2, 4, 8]
|
||||
.map(numOfWorkers => <MenuItem key={numOfWorkers} value={numOfWorkers} primaryText={numOfWorkers} />)
|
||||
}
|
||||
</SelectField>
|
||||
</div>
|
||||
</List>
|
||||
<List>
|
||||
<Subheader>Readers</Subheader>
|
||||
{availableReaders.map(([reader, label, enabled]) => (
|
||||
<ListItem
|
||||
key={reader}
|
||||
primaryText={label}
|
||||
rightToggle={<Toggle defaultToggled={enabled ? enabled : false} />}
|
||||
/>
|
||||
))}
|
||||
</List>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -2,6 +2,11 @@ import React from 'react';
|
||||
import Quagga from '../../../../dist/quagga';
|
||||
|
||||
export default class Scanner extends React.Component {
|
||||
propTypes = {
|
||||
onDetected: React.PropTypes.func,
|
||||
onCancel: React.PropTypes.func,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._scanner = Quagga
|
||||
@@ -13,23 +18,19 @@ export default class Scanner extends React.Component {
|
||||
constraints: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
facingMode: "environment"
|
||||
}
|
||||
facingMode: "environment",
|
||||
},
|
||||
});
|
||||
this._onCancel = this._onCancel.bind(this);
|
||||
}
|
||||
_onCancel(e) {
|
||||
|
||||
_onCancel = (e) => {
|
||||
e.preventDefault();
|
||||
if (this._scanUntilResult) {
|
||||
this._scanUntilResult.cancel();
|
||||
this._scanUntilResult = null;
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className="overlay__content" />
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._scanUntilResult = this._scanner.toPromise();
|
||||
this._scanUntilResult.promise
|
||||
@@ -37,6 +38,12 @@ export default class Scanner extends React.Component {
|
||||
.catch(this.props.onCancel);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="overlay__content" />
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._scanner
|
||||
.removeEventListener('detected', this.props.onDetected)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
html {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
.overlay__content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user