Skip to content

Commit

Permalink
refactor: drag-and-drop in dedicated component
Browse files Browse the repository at this point in the history
Outsource complexity from main component and prepare new component
to be exposed as standalone public component.
  • Loading branch information
gruhn committed Oct 23, 2018
1 parent a48312e commit 046b3d3
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 61 deletions.
51 changes: 51 additions & 0 deletions src/components/QrcodeDropZone.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template lang="html">
<div
@drop.prevent.stop="onDrop"
@dragover.prevent.stop
@dragenter.prevent.stop
@dragleave.prevent.stop>
<slot></slot>
</div>
</template>

<script>
import { scan } from '../misc/scanner.js'
import { imageDataFromFile, imageDataFromUrl } from '../misc/image-data.js'
import CommonAPI from '../mixins/CommonAPI.vue'
export default {
mixins: [ CommonAPI ],
methods: {
onDrop ({ dataTransfer }) {
const droppedFiles = [...dataTransfer.files]
const droppedUrl = dataTransfer.getData('text')
droppedFiles.forEach(file => {
this.onDetect(this.processFile(file))
})
if (droppedUrl !== '') {
this.onDetect(this.processUrl(droppedUrl))
}
},
async processFile (file) {
const imageData = await imageDataFromFile(file)
const scanResult = await scan(imageData)
return { source: 'file', ...scanResult }
},
async processUrl (url) {
const imageData = await imageDataFromUrl(url)
const scanResult = await scan(imageData)
return { source: 'url', ...scanResult }
},
},
}
</script>
80 changes: 20 additions & 60 deletions src/components/QrcodeReader.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
<template lang="html">
<div class="qrcode-reader">
<div class="qrcode-reader__inner-wrapper">
<div
class="qrcode-reader__overlay"
@drop.prevent.stop="onDrop"
@dragover.prevent.stop
@dragenter.prevent.stop
@dragleave.prevent.stop
>
<QrcodeDropZone
@detect="onDetect"
class="qrcode-reader__overlay">
<slot></slot>
</div>
</QrcodeDropZone>

<canvas
ref="trackingLayer"
Expand All @@ -35,13 +31,18 @@
</template>

<script>
import * as Scanner from '../misc/scanner.js'
import { keepScanning } from '../misc/scanner.js'
import Camera from '../misc/camera.js'
import { imageDataFromFile, imageDataFromUrl } from '../misc/image-data.js'
import isBoolean from 'lodash/isBoolean'
import QrcodeDropZone from './QrcodeDropZone.vue'
import CommonAPI from '../mixins/CommonAPI.vue'
export default {
components: { QrcodeDropZone },
mixins: [ CommonAPI ],
props: {
paused: {
type: Boolean,
Expand Down Expand Up @@ -210,9 +211,16 @@ export default {
},
startScanning () {
Scanner.keepScanning(this.cameraInstance, {
const detectHandler = promise => {
this.onDetect(async () => {
const result = await promise
return { source: 'stream', ...result }
})
}
keepScanning(this.cameraInstance, {
detectHandler,
locateHandler: this.onLocate,
detectHandler: scanResult => this.onDetect('stream', scanResult),
shouldContinue: () => this.shouldScan,
minDelay: this.scanInterval,
})
Expand All @@ -235,54 +243,6 @@ export default {
}
},
async onDetect (source, promise) {
this.$emit('detect', (async () => {
const data = await promise
return { source, ...data }
})())
try {
const { content } = await promise
if (content !== null) {
this.$emit('decode', content)
}
} catch (error) {
// fail silently
}
},
onDrop ({ dataTransfer }) {
const droppedFiles = [...dataTransfer.files]
droppedFiles.forEach(this.onDropFile)
const droppedUrl = dataTransfer.getData('text')
if (droppedUrl !== '') {
this.onDropUrl(droppedUrl)
}
},
async onDropFile (file) {
this.onDetect('file', (async () => {
const imageData = await imageDataFromFile(file)
const scanResult = await Scanner.scan(imageData)
return scanResult
})())
},
async onDropUrl (url) {
this.onDetect('url', (async () => {
const imageData = await imageDataFromUrl(url)
const scanResult = await Scanner.scan(imageData)
return scanResult
})())
},
/**
* The coordinates are based on the original camera resolution but the
* video element is responsive and scales with space available. Therefore
Expand Down
6 changes: 5 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import QrcodeReader from './components/QrcodeReader.vue'
// import QrcodeDropZone from './components/QrcodeDropZone.vue'

// Install the components
export function install (Vue) {
Vue.component('qrcode-reader', QrcodeReader)
}

// Expose the components
export { QrcodeReader }
export {
QrcodeReader,
// QrcodeDropZone,
}

/* -- Plugin definition & Auto-install -- */
/* You shouldn't have to modify the code below */
Expand Down
21 changes: 21 additions & 0 deletions src/mixins/CommonAPI.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script>
export default {
methods: {
async onDetect (resultPromise) {
this.$emit('detect', resultPromise)
try {
const { content } = await resultPromise
if (content !== null) {
this.$emit('decode', content)
}
} catch (error) {
// fail silently
}
},
},
}
</script>

0 comments on commit 046b3d3

Please sign in to comment.