scandit implementation

This commit is contained in:
Lorenz Hilpert
2022-04-19 14:58:15 +02:00
parent 9052fe25db
commit b7feea46f7
15 changed files with 227 additions and 13 deletions

5
.gitignore vendored
View File

@@ -46,4 +46,7 @@ testem.log
.DS_Store
Thumbs.db
libs/swagger/src/lib/*
libs/swagger/src/lib/*
apps/isa-app/src/scandit/*
!apps/isa-app/src/scandit/.gitkeep

View File

@@ -3321,7 +3321,8 @@
"apps/isa-app/src/assets",
"apps/isa-app/src/config",
"apps/isa-app/src/silent-refresh.html",
"apps/isa-app/src/manifest.webmanifest"
"apps/isa-app/src/manifest.webmanifest",
"apps/isa-app/src/scandit"
],
"styles": [
"apps/isa-app/src/styles.scss"
@@ -3845,6 +3846,6 @@
}
}
}
},
},
"defaultProject": "isa-app"
}

View File

@@ -1,14 +1,21 @@
import { NgModule } from '@angular/core';
import { DevScanAdapter } from './dev.scan-adapter';
import { NativeScanAdapter } from './native.scan-adapter';
import { ScanditModalModule } from './scandit-modal';
import { ScanditScanAdapter } from './scandit.scan-adapter';
import { SCAN_ADAPTER } from './tokens';
@NgModule({})
@NgModule({
imports: [ScanditModalModule],
})
export class ScanAdapterModule {
static forRoot(dev?: boolean) {
return {
ngModule: ScanAdapterModule,
providers: [{ provide: SCAN_ADAPTER, useClass: NativeScanAdapter, multi: true }],
providers: [
{ provide: SCAN_ADAPTER, useClass: NativeScanAdapter, multi: true },
{ provide: SCAN_ADAPTER, useClass: ScanditScanAdapter, multi: true },
],
// Use for testing:
// providers: [{ provide: SCAN_ADAPTER, useClass: dev ? DevScanAdapter : NativeScanAdapter, multi: true }],
};

View File

@@ -0,0 +1,2 @@
export * from './scandit-modal.component';
export * from './scandit-modal.module';

View File

@@ -0,0 +1 @@
<div #scanContainer></div>

View File

@@ -0,0 +1,3 @@
div {
@apply mt-8;
}

View File

@@ -0,0 +1,54 @@
import { Component, ChangeDetectionStrategy, ViewChild, ElementRef, AfterViewInit, NgZone, Inject } from '@angular/core';
import { UiModalRef } from '@ui/modal';
import { Barcode, BarcodePicker, ScanSettings } from 'scandit-sdk';
@Component({
selector: 'scandit-modal',
templateUrl: 'scandit-modal.component.html',
styleUrls: ['scandit-modal.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ScanditModalComponent implements AfterViewInit {
private _barcodePicker: BarcodePicker;
@ViewChild('scanContainer', { read: ElementRef, static: true }) scanContainer: ElementRef;
constructor(private _modalRef: UiModalRef, private readonly _zone: NgZone) {}
ngAfterViewInit(): void {
this._zone.runOutsideAngular(() => {
BarcodePicker.create(this.scanContainer.nativeElement, {
playSoundOnScan: true,
vibrateOnScan: true,
}).then((picker) => {
this._barcodePicker = picker;
var scanSettings = new ScanSettings({
enabledSymbologies: [
Barcode.Symbology.EAN8,
Barcode.Symbology.EAN13,
Barcode.Symbology.UPCA,
Barcode.Symbology.UPCE,
Barcode.Symbology.CODE128,
Barcode.Symbology.CODE39,
Barcode.Symbology.CODE93,
Barcode.Symbology.INTERLEAVED_2_OF_5,
Barcode.Symbology.QR,
],
codeDuplicateFilter: 1000,
});
picker.applyScanSettings(scanSettings);
picker.on('scan', (barcode) => {
this._modalRef.close(barcode.texts[0].value);
});
});
});
}
cancel() {
this._barcodePicker?.pauseCameraAccess();
this._barcodePicker?.destroy();
this._modalRef.close();
}
}

View File

@@ -0,0 +1,11 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ScanditModalComponent } from './scandit-modal.component';
@NgModule({
imports: [CommonModule],
exports: [ScanditModalComponent],
declarations: [ScanditModalComponent],
})
export class ScanditModalModule {}

View File

@@ -0,0 +1,49 @@
import { Injectable } from '@angular/core';
import { UiModalService } from '@ui/modal';
import { Observable } from 'rxjs';
import { ScanAdapter } from './scan-adapter';
import { configure } from 'scandit-sdk';
import { ScanditModalComponent } from './scandit-modal';
import { filter, map } from 'rxjs/operators';
import { Config } from '@core/config';
@Injectable()
export class ScanditScanAdapter implements ScanAdapter {
private _isReady = false;
constructor(private readonly _modal: UiModalService, private readonly _config: Config) {
this.configure();
}
private async configure() {
await configure(this._config.get('licence.scandit'), {
engineLocation: '/scandit/',
});
this._isReady = true;
}
getName(): string {
return 'Scandit';
}
isPrimary(): boolean {
return false;
}
isReady(): boolean {
return this._isReady;
}
scan(): Observable<string> {
return this._modal
.open({
content: ScanditModalComponent,
})
.afterClosed$.pipe(
map((result) => result.data),
filter((result) => !!result)
);
}
}

View File

@@ -1,5 +1,8 @@
{
"title": "ISA - Local",
"licence": {
"skandit": "AXvBoAZ/JLaLOMv7IyiBFShF6KLnGGdx7GC5pQ4v9wuaXnCY+2/4SPYNEGKmUtWkWGMtmbFmKJpRIxUE6kq1kppQrRlQE5LwMnf9IhFIX2YJckWxXl5RG0BCqdckUrS3d0CFyjpNuuHWQQ0SDDSlpCAcsK04LTiVtC800dhaj4YAVWnXnEbqsSwklW9mJv16nQS9r21VUvlsl9KReZkGymagAgRJps0gf7B6b/S7f6VQ3VT12Amu9/L207GDYh0GGMl6RaE+LjClqIak5jLiSD2l7a9F9lGMVScCTMYl2zw6Ugud4ttzaBY/uMUZfS15gW2H/2zfYO2mVwIOMBIXDFEoq/JOqjOLBB8IEgm6Eu6vKKFqwQ8F6HSKbo9Ba3/be59qMmztiFLaZXe8vNgAr4yJ+YCcrxK0iD/A30tTgL25E/H4QMRFWSAgFBoOwdbyYeM0WbqwasTMbtWUC7xyKr7EIYLN1LdxpnyuS6BObD/0AtuEdd3nrBl8Yc+4R/MOnJ5QF6vopNFhFGiVoYwaGR0G/NfTVMeIYHinwOjB1qQcA6Qr40IZqKK9VFuwsUw32MM5RrQQCr0olnGRrVO8JHmFaRIiwwQ4+NSRV7Z0iyDM9sh1A1Xl4IW5azQaqA4zGXOdiDBRvKGY5zOE2TWgDdzCe1oQ1d3Qk6VXDx+eCzFIAb1UA0ealeHAQ6SzWlXAkHuY+zrw3pGVoe2b4aSTkBRdegFAaU9/H2Xl9WAx4DW4pfUQRZBbR4htgaWs1a9vVUb76P8GpK2ihF4YIYLC9B1EW7hzaOfGfhWVFRmK7j544aiqbz+bL/HgG6QZhdyTRhHAj1oWl0/hSV1eeq7BgqsDQQEidHbX/Gg="
},
"@cdn/product-image": {
"url": "https://produktbilder.paragon-data.net"
},

View File

@@ -1,5 +1,8 @@
{
"title": "ISA - Local",
"licence": {
"scandit": "AXvBoAZ/JLaLOMv7IyiBFShF6KLnGGdx7GC5pQ4v9wuaXnCY+2/4SPYNEGKmUtWkWGMtmbFmKJpRIxUE6kq1kppQrRlQE5LwMnf9IhFIX2YJckWxXl5RG0BCqdckUrS3d0CFyjpNuuHWQQ0SDDSlpCAcsK04LTiVtC800dhaj4YAVWnXnEbqsSwklW9mJv16nQS9r21VUvlsl9KReZkGymagAgRJps0gf7B6b/S7f6VQ3VT12Amu9/L207GDYh0GGMl6RaE+LjClqIak5jLiSD2l7a9F9lGMVScCTMYl2zw6Ugud4ttzaBY/uMUZfS15gW2H/2zfYO2mVwIOMBIXDFEoq/JOqjOLBB8IEgm6Eu6vKKFqwQ8F6HSKbo9Ba3/be59qMmztiFLaZXe8vNgAr4yJ+YCcrxK0iD/A30tTgL25E/H4QMRFWSAgFBoOwdbyYeM0WbqwasTMbtWUC7xyKr7EIYLN1LdxpnyuS6BObD/0AtuEdd3nrBl8Yc+4R/MOnJ5QF6vopNFhFGiVoYwaGR0G/NfTVMeIYHinwOjB1qQcA6Qr40IZqKK9VFuwsUw32MM5RrQQCr0olnGRrVO8JHmFaRIiwwQ4+NSRV7Z0iyDM9sh1A1Xl4IW5azQaqA4zGXOdiDBRvKGY5zOE2TWgDdzCe1oQ1d3Qk6VXDx+eCzFIAb1UA0ealeHAQ6SzWlXAkHuY+zrw3pGVoe2b4aSTkBRdegFAaU9/H2Xl9WAx4DW4pfUQRZBbR4htgaWs1a9vVUb76P8GpK2ihF4YIYLC9B1EW7hzaOfGfhWVFRmK7j544aiqbz+bL/HgG6QZhdyTRhHAj1oWl0/hSV1eeq7BgqsDQQEidHbX/Gg="
},
"@cdn/product-image": {
"url": "https://produktbilder.paragon-data.net"
},

View File

69
package-lock.json generated
View File

@@ -3826,6 +3826,15 @@
"regenerator-runtime": "^0.13.4"
}
},
"@babel/runtime-corejs2": {
"version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.17.9.tgz",
"integrity": "sha512-+QThIsnjVY12uURTvmnW33risFZ7ulq6OWw0VJL08UwiYiWVp9PM63s+W1L2ppajYyKAYKb7afcGYSHzA0k04Q==",
"requires": {
"core-js": "^2.6.5",
"regenerator-runtime": "^0.13.4"
}
},
"@babel/runtime-corejs3": {
"version": "7.17.8",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz",
@@ -4009,6 +4018,11 @@
"schema-utils": "^2.7.0"
}
},
"@juggle/resize-observer": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz",
"integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw=="
},
"@microsoft/signalr": {
"version": "5.0.10",
"resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.10.tgz",
@@ -7222,6 +7236,11 @@
"css-tree": "^1.1.2"
}
},
"csstype": {
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz",
"integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw=="
},
"cuint": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
@@ -8116,8 +8135,7 @@
"eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"dev": true
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
},
"events": {
"version": "3.3.0",
@@ -8708,9 +8726,9 @@
"dev": true
},
"fs-extra": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz",
"integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
@@ -9172,6 +9190,11 @@
}
}
},
"howler": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/howler/-/howler-2.2.3.tgz",
"integrity": "sha512-QM0FFkw0LRX1PR8pNzJVAY25JhIWvbKMBFM4gqk+QdV+kPXOhleWGCB6AiAF/goGjIHK2e/nIElplvjQwhr0jg=="
},
"hpack.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
@@ -10488,6 +10511,11 @@
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==",
"dev": true
},
"js-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
"integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -12944,6 +12972,11 @@
"isobject": "^3.0.1"
}
},
"objectFitPolyfill": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/objectFitPolyfill/-/objectFitPolyfill-2.3.5.tgz",
"integrity": "sha512-8Quz071ZmGi0QWEG4xB3Bv5Lpw6K0Uca87FLoLMKMWjB6qIq9IyBegP3b/VLNxv2WYvIMGoeUQ+c6ibUkNa8TA=="
},
"obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
@@ -16253,8 +16286,7 @@
"regenerator-runtime": {
"version": "0.13.7",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
"dev": true
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
},
"regenerator-transform": {
"version": "0.14.5",
@@ -16794,6 +16826,29 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
},
"scandit-sdk": {
"version": "5.11.0",
"resolved": "https://registry.npmjs.org/scandit-sdk/-/scandit-sdk-5.11.0.tgz",
"integrity": "sha512-xaWBcosU87eqeUw5wziG6ML2NbCQCLCr4AA7oCcPCMsPBnUZxlLsYHD6PXbc4juq1Glg4xfvwduUjtRFWkH5PA==",
"requires": {
"@babel/runtime-corejs2": "^7.17.8",
"@juggle/resize-observer": "^3.3.1",
"csstype": "^3.0.11",
"eventemitter3": "^4.0.7",
"howler": "^2.2.3",
"js-cookie": "^3.0.1",
"objectFitPolyfill": "^2.3.5",
"tslib": "^2.3.1",
"ua-parser-js": "^1.0.2"
},
"dependencies": {
"ua-parser-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz",
"integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg=="
}
}
},
"schema-utils": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",

View File

@@ -32,7 +32,8 @@
"gen:swagger:print": "ng-swagger-gen --config ng-swagger-gen/print.json",
"gen:swagger:eis": "ng-swagger-gen --config ng-swagger-gen/eis.json",
"gen:swagger:remi": "ng-swagger-gen --config ng-swagger-gen/remi.json",
"prettier": "prettier --write ."
"prettier": "prettier --write .",
"copy:scandit-engine": "node ./tools/copy node_modules/scandit-sdk/build apps/isa-app/src/scandit"
},
"husky": {
"hooks": {
@@ -76,6 +77,7 @@
"ngx-toggle-switch": "^2.0.5",
"object-hash": "^2.1.1",
"rxjs": "^6.6.7",
"scandit-sdk": "^5.11.0",
"smoothscroll-polyfill": "^0.4.4",
"socket.io": "^2.2.0",
"tslib": "^2.0.0",
@@ -100,6 +102,7 @@
"@types/object-hash": "^2.1.0",
"@types/uuid": "^8.3.0",
"codelyzer": "^6.0.0",
"fs-extra": "^10.1.0",
"husky": "^4.2.3",
"jasmine-core": "~3.6.0",
"jasmine-marbles": "^0.6.0",
@@ -111,6 +114,7 @@
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"karma-junit-reporter": "^2.0.1",
"minimist": "^1.2.6",
"ng-mocks": "^12.5.0",
"ng-packagr": "^12.2.5",
"ng-swagger-gen": "^2.3.1",

18
tools/copy.js Normal file
View File

@@ -0,0 +1,18 @@
const fs = require('fs-extra');
const path = require('path');
const minimist = require('minimist');
const args = minimist(process.argv.slice(2));
const cwd = args.cwd ?? process.cwd();
const overwrite = args.overwrite ?? true;
const source = path.join(cwd, args._[0]);
const dest = path.join(cwd, args._[1]);
// copy all files and directories from source to dest recursive
fs.copySync(source, dest, {
overwrite,
});