Skip to content

Commit d936a93

Browse files
Merge pull request #306 from TheOneWithTheBraid/master
Added web support
2 parents 514fce7 + d14278a commit d936a93

12 files changed

Lines changed: 490 additions & 24 deletions

File tree

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,20 @@ In order to use this plugin, add the following to your Info.plist file:
132132
<string>This app needs camera access to scan QR codes</string>
133133
```
134134

135+
## Web Integration
136+
137+
Add this to `web/index.html`:
138+
139+
```html
140+
<script src="https://cdn.jsdelivr.net/npm/jsqr@1.3.1/dist/jsQR.min.js"></script>
141+
```
142+
143+
Please note: on web, only QR codes are supported. Other barcodes and 2D codes cannot be scanned.
144+
145+
Web support is in very earlt stage. Features such as flash, pause or resume are not implemented. Moreover, the camera
146+
preview does not respect the surrounding constraints. This is not at last due to Flutter's early state of platform views
147+
on web.
148+
135149
## Flip Camera (Back/Front)
136150
The default camera is the back camera.
137151
```dart

example/web/favicon.png

917 Bytes
Loading

example/web/icons/Icon-192.png

5.17 KB
Loading

example/web/icons/Icon-512.png

8.06 KB
Loading

example/web/index.html

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<!--
5+
If you are serving your web app in a path other than the root, change the
6+
href value below to reflect the base path you are serving from.
7+
8+
The path provided below has to start and end with a slash "/" in order for
9+
it to work correctly.
10+
11+
Fore more details:
12+
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
13+
-->
14+
<base href="/">
15+
16+
<meta charset="UTF-8">
17+
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
18+
<meta name="description" content="A new Flutter project.">
19+
20+
<!-- iOS meta tags & icons -->
21+
<meta name="apple-mobile-web-app-capable" content="yes">
22+
<meta name="apple-mobile-web-app-status-bar-style" content="black">
23+
<meta name="apple-mobile-web-app-title" content="example">
24+
<link rel="apple-touch-icon" href="icons/Icon-192.png">
25+
26+
<!-- Favicon -->
27+
<link rel="icon" type="image/png" href="favicon.png"/>
28+
29+
<title>example</title>
30+
<link rel="manifest" href="manifest.json">
31+
<script src="https://cdn.jsdelivr.net/npm/jsqr@1.3.1/dist/jsQR.min.js"></script>
32+
</head>
33+
<body>
34+
<!-- This script installs service_worker.js to provide PWA functionality to
35+
application. For more information, see:
36+
https://developers.google.com/web/fundamentals/primers/service-workers -->
37+
<script>
38+
if ('serviceWorker' in navigator) {
39+
window.addEventListener('flutter-first-frame', function () {
40+
navigator.serviceWorker.register('flutter_service_worker.js');
41+
});
42+
}
43+
</script>
44+
<script src="main.dart.js" type="application/javascript"></script>
45+
</body>
46+
</html>

example/web/manifest.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "example",
3+
"short_name": "example",
4+
"start_url": ".",
5+
"display": "standalone",
6+
"background_color": "#0175C2",
7+
"theme_color": "#0175C2",
8+
"description": "A new Flutter project.",
9+
"orientation": "portrait-primary",
10+
"prefer_related_applications": false,
11+
"icons": [
12+
{
13+
"src": "icons/Icon-192.png",
14+
"sizes": "192x192",
15+
"type": "image/png"
16+
},
17+
{
18+
"src": "icons/Icon-512.png",
19+
"sizes": "512x512",
20+
"type": "image/png"
21+
}
22+
]
23+
}

lib/src/qr_code_scanner.dart

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'dart:async';
2-
import 'dart:io';
32

43
import 'package:flutter/foundation.dart';
54
import 'package:flutter/material.dart';
@@ -12,6 +11,9 @@ import 'types/barcode_format.dart';
1211
import 'types/camera.dart';
1312
import 'types/camera_exception.dart';
1413
import 'types/features.dart';
14+
import 'web/flutter_qr_stub.dart'
15+
// ignore: uri_does_not_exist
16+
if (dart.library.html) 'web/flutter_qr_web.dart';
1517

1618
typedef QRViewCreatedCallback = void Function(QRViewController);
1719
typedef PermissionSetCallback = void Function(QRViewController, bool);
@@ -111,28 +113,35 @@ class _QRViewState extends State<QRView> {
111113

112114
Widget _getPlatformQrView() {
113115
Widget _platformQrView;
114-
switch (defaultTargetPlatform) {
115-
case TargetPlatform.android:
116-
_platformQrView = AndroidView(
117-
viewType: 'net.touchcapture.qr.flutterqr/qrview',
118-
onPlatformViewCreated: _onPlatformViewCreated,
119-
creationParams:
120-
_QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(),
121-
creationParamsCodec: StandardMessageCodec(),
122-
);
123-
break;
124-
case TargetPlatform.iOS:
125-
_platformQrView = UiKitView(
126-
viewType: 'net.touchcapture.qr.flutterqr/qrview',
127-
onPlatformViewCreated: _onPlatformViewCreated,
128-
creationParams:
129-
_QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(),
130-
creationParamsCodec: StandardMessageCodec(),
131-
);
132-
break;
133-
default:
134-
throw UnsupportedError(
135-
"Trying to use the default qrview implementation for $defaultTargetPlatform but there isn't a default one");
116+
if (kIsWeb) {
117+
_platformQrView = createWebQrView(
118+
onPlatformViewCreated: widget.onQRViewCreated,
119+
cameraFacing: widget.cameraFacing,
120+
);
121+
} else {
122+
switch (defaultTargetPlatform) {
123+
case TargetPlatform.android:
124+
_platformQrView = AndroidView(
125+
viewType: 'net.touchcapture.qr.flutterqr/qrview',
126+
onPlatformViewCreated: _onPlatformViewCreated,
127+
creationParams:
128+
_QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(),
129+
creationParamsCodec: StandardMessageCodec(),
130+
);
131+
break;
132+
case TargetPlatform.iOS:
133+
_platformQrView = UiKitView(
134+
viewType: 'net.touchcapture.qr.flutterqr/qrview',
135+
onPlatformViewCreated: _onPlatformViewCreated,
136+
creationParams:
137+
_QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(),
138+
creationParamsCodec: StandardMessageCodec(),
139+
);
140+
break;
141+
default:
142+
throw UnsupportedError(
143+
"Trying to use the default qrview implementation for $defaultTargetPlatform but there isn't a default one");
144+
}
136145
}
137146
return _platformQrView;
138147
}
@@ -309,7 +318,7 @@ class QRViewController {
309318

310319
/// Stops the camera and disposes the barcode stream.
311320
void dispose() {
312-
if (Platform.isIOS) stopCamera();
321+
if (defaultTargetPlatform == TargetPlatform.iOS) stopCamera();
313322
_scanUpdateController.close();
314323
}
315324

lib/src/web/flutter_qr_stub.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import 'package:flutter/widgets.dart';
2+
import 'package:qr_code_scanner/src/types/camera.dart';
3+
4+
Widget createWebQrView({onPlatformViewCreated, CameraFacing? cameraFacing}) =>
5+
throw UnimplementedError();

0 commit comments

Comments
 (0)