Skip to content

Commit

Permalink
feat: Open scanner on send button
Browse files Browse the repository at this point in the history
  • Loading branch information
holzeis committed Dec 7, 2023
1 parent ca03a70 commit ae451e8
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 228 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Feat: Open scanner on send button

## [1.7.0] - 2023-12-07

- Fix: Reduce WebSocket reconnect timeout to 200ms.
Expand Down
6 changes: 2 additions & 4 deletions mobile/lib/common/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get_10101/common/global_keys.dart';
import 'package:get_10101/common/settings/channel_screen.dart';
import 'package:get_10101/common/status_screen.dart';
import 'package:get_10101/features/wallet/domain/destination.dart';
import 'package:get_10101/features/welcome/loading_screen.dart';
import 'package:get_10101/common/scaffold_with_nav_bar.dart';
import 'package:get_10101/common/settings/app_info_screen.dart';
Expand Down Expand Up @@ -152,10 +153,7 @@ GoRouter createRoutes() {
// Use root navigator so the screen overlays the application shell
parentNavigatorKey: rootNavigatorKey,
builder: (BuildContext context, GoRouterState state) {
if (state.extra != null) {
return SendScreen(encodedDestination: state.extra as String?);
}
return const SendScreen();
return SendScreen(destination: state.extra as Destination);
},
),
GoRoute(
Expand Down
210 changes: 182 additions & 28 deletions mobile/lib/features/wallet/scanner_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get_10101/common/color.dart';
import 'package:get_10101/features/wallet/domain/destination.dart';
import 'package:get_10101/features/wallet/send/send_screen.dart';
import 'package:get_10101/features/wallet/wallet_change_notifier.dart';
import 'package:get_10101/features/wallet/wallet_screen.dart';
import 'package:get_10101/logger/logger.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';

class ScannerScreen extends StatefulWidget {
Expand All @@ -22,6 +28,14 @@ class _ScannerScreenState extends State<ScannerScreen> {
QRViewController? controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');

final _formKey = GlobalKey<FormState>();
String? _encodedDestination;
Destination? _destination;

final textEditingController = TextEditingController();

bool cameraPermission = kDebugMode;

@override
void reassemble() {
super.reassemble();
Expand All @@ -37,38 +51,178 @@ class _ScannerScreenState extends State<ScannerScreen> {

@override
Widget build(BuildContext context) {
final walletService = context.read<WalletChangeNotifier>().service;

return Scaffold(
appBar: AppBar(title: const Text("Scan")),
body: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: 300.0),
formatsAllowed: const [BarcodeFormat.qrcode],
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
));
}
body: SafeArea(
child: Container(
margin: const EdgeInsets.only(top: 10),
child: Column(children: [
Container(
margin: const EdgeInsets.only(left: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
child: Container(
alignment: AlignmentDirectional.topStart,
decoration: BoxDecoration(
color: Colors.transparent, borderRadius: BorderRadius.circular(10)),
width: 70,
child: const Icon(
Icons.arrow_back_ios_new_rounded,
size: 22,
)),
onTap: () {
GoRouter.of(context).pop();
},
),
],
),
),
const SizedBox(height: 20),
Expanded(
child: !cameraPermission
? const Padding(
padding: EdgeInsets.only(left: 25, right: 25),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(FontAwesomeIcons.ban, size: 55),
SizedBox(height: 20),
Text(
"To scan a QR code you must give 10101 permission to access the camera.",
textAlign: TextAlign.center)
]),
)
: QRView(
key: qrKey,
onQRViewCreated: (controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) {
if (scanData.code != null) {
setState(() {
_encodedDestination = scanData.code;
textEditingController.text = _encodedDestination ?? "";
});
walletService
.decodeDestination(scanData.code ?? "")
.then((destination) {
_destination = destination;
if (_formKey.currentState!.validate()) {
GoRouter.of(context).go(SendScreen.route, extra: destination);
}
});
}
});
},
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: 300.0),
formatsAllowed: const [BarcodeFormat.qrcode],
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
)),
Container(
margin: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Destination"),
const SizedBox(height: 5),
Form(
key: _formKey,
child: TextFormField(
validator: (value) {
if (_destination == null) {
return "Invalid destination";
}

return null;
},
onChanged: (value) => _encodedDestination = value,
controller: textEditingController,
decoration: InputDecoration(
filled: true,
fillColor: Colors.grey.shade200,
suffixIcon: GestureDetector(
onTap: () async {
final data = await Clipboard.getData("text/plain");

void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) {
GoRouter.of(context).go(SendScreen.route, extra: scanData.code);
});
if (data?.text != null) {
setState(() {
_encodedDestination = data!.text!;
textEditingController.text = _encodedDestination!;
});
}
},
child: const Icon(Icons.paste_rounded, color: tenTenOnePurple, size: 18),
),
enabledBorder:
OutlineInputBorder(borderSide: BorderSide(color: Colors.grey.shade200)),
border:
OutlineInputBorder(borderSide: BorderSide(color: Colors.grey.shade200)),
),
),
),
const SizedBox(height: 20),
SizedBox(
width: MediaQuery.of(context).size.width * 0.9,
child: ElevatedButton(
onPressed: () {
walletService
.decodeDestination(_encodedDestination ?? "")
.then((destination) {
_destination = destination;

if (_formKey.currentState!.validate()) {
GoRouter.of(context).go(SendScreen.route, extra: destination);
}
});
},
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.all(15)),
backgroundColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.disabled)) {
return tenTenOnePurple.shade100;
} else {
return tenTenOnePurple;
}
}),
shape: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.disabled)) {
return RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
side: BorderSide(color: tenTenOnePurple.shade100),
);
} else {
return RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
side: const BorderSide(color: tenTenOnePurple),
);
}
})),
child: const Text(
"Next",
style: TextStyle(fontSize: 18, color: Colors.white),
)),
),
],
),
),
]),
),
));
}

void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
logger.d('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('no Permission')),
);
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool permission) {
logger.d('${DateTime.now().toIso8601String()}_onPermissionSet $permission');
setState(() => cameraPermission = permission);
}

@override
Expand Down
85 changes: 0 additions & 85 deletions mobile/lib/features/wallet/send/enter_destination_modal.dart

This file was deleted.

Loading

0 comments on commit ae451e8

Please sign in to comment.