add qr code scanning from gallery using zxing2
This commit is contained in:
Submodule mobile/apps/auth/flutter updated: edada7c56e...2663184aa7
@@ -519,5 +519,12 @@
|
||||
"algorithm": "Algorithm",
|
||||
"type": "Type",
|
||||
"period": "Period",
|
||||
"digits": "Digits"
|
||||
"digits": "Digits",
|
||||
"importFromGallery": "Import from gallery",
|
||||
"errorCouldNotReadImage": "Could not read the selected image file.",
|
||||
"errorInvalidQRCode": "Invalid QR Code",
|
||||
"errorInvalidQRCodeBody": "The scanned QR code is not a valid 2FA account.",
|
||||
"errorNoQRCode": "No QR code found",
|
||||
"errorGenericTitle": "An Error Occurred",
|
||||
"errorGenericBody": "An unexpected error occurred while importing."
|
||||
}
|
||||
@@ -35,18 +35,22 @@ import 'package:ente_auth/ui/settings_page.dart';
|
||||
import 'package:ente_auth/ui/sort_option_menu.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:ente_auth/utils/platform_util.dart';
|
||||
import 'package:ente_auth/utils/toast_util.dart';
|
||||
import 'package:ente_auth/utils/totp_util.dart';
|
||||
import 'package:ente_events/event_bus.dart';
|
||||
import 'package:ente_lock_screen/lock_screen_settings.dart';
|
||||
import 'package:ente_lock_screen/ui/app_lock.dart';
|
||||
import 'package:ente_ui/pages/base_home_page.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:image/image.dart' as img;
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:move_to_background/move_to_background.dart';
|
||||
import 'package:zxing2/qrcode.dart';
|
||||
|
||||
class HomePage extends BaseHomePage {
|
||||
const HomePage({super.key});
|
||||
@@ -62,6 +66,7 @@ class _HomePageState extends State<HomePage> {
|
||||
);
|
||||
bool _hasLoaded = false;
|
||||
bool _isSettingsOpen = false;
|
||||
bool _isImportingFromGallery = false;
|
||||
final Logger _logger = Logger("HomePage");
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
@@ -288,6 +293,70 @@ class _HomePageState extends State<HomePage> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _importFromGallery() async {
|
||||
|
||||
final l10n = AppLocalizations.of(context);
|
||||
|
||||
if (_isImportingFromGallery) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isImportingFromGallery = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.image,
|
||||
);
|
||||
|
||||
if (result == null || result.files.single.path == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String imagePath = result.files.single.path!;
|
||||
final rawImage = await File(imagePath).readAsBytes();
|
||||
final image = img.decodeImage(rawImage);
|
||||
|
||||
if (image == null) {
|
||||
await showErrorDialog(context, l10n.error, l10n.errorCouldNotReadImage);
|
||||
return;
|
||||
}
|
||||
|
||||
final source = RGBLuminanceSource(
|
||||
image.width, image.height,
|
||||
image.getBytes(order: img.ChannelOrder.rgba).buffer.asInt32List(),
|
||||
);
|
||||
final bitmap = BinaryBitmap(HybridBinarizer(source));
|
||||
final reader = QRCodeReader();
|
||||
final Result decodeResult = reader.decode(bitmap);
|
||||
final String code = decodeResult.text;
|
||||
try{
|
||||
final newCode = Code.fromOTPAuthUrl(code);
|
||||
await CodeStore.instance.addCode(newCode, shouldSync: false);
|
||||
}
|
||||
catch (e){
|
||||
await showErrorDialog(
|
||||
context, l10n.errorInvalidQRCode, l10n.errorInvalidQRCodeBody,
|
||||
);
|
||||
}
|
||||
}
|
||||
on ReaderException {
|
||||
showToast(context, l10n.errorNoQRCode);
|
||||
}
|
||||
|
||||
catch (e) {
|
||||
await showErrorDialog(
|
||||
context, l10n.errorGenericTitle, l10n.errorGenericBody,
|
||||
);
|
||||
}
|
||||
finally {
|
||||
setState(() {
|
||||
_isImportingFromGallery = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _redirectToScannerPage() async {
|
||||
final Code? code = await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
@@ -745,6 +814,13 @@ class _HomePageState extends State<HomePage> {
|
||||
labelWidget: SpeedDialLabelWidget(context.l10n.enterDetailsManually),
|
||||
onTap: _redirectToManualEntryPage,
|
||||
),
|
||||
SpeedDialChild(
|
||||
child: const Icon(Icons.image),
|
||||
backgroundColor: Theme.of(context).colorScheme.fabBackgroundColor,
|
||||
foregroundColor: Theme.of(context).colorScheme.fabForegroundColor,
|
||||
labelWidget: SpeedDialLabelWidget(context.l10n.importFromGallery),
|
||||
onTap: _importFromGallery,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -201,6 +201,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -951,7 +959,7 @@ packages:
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
image:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image
|
||||
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
|
||||
@@ -2021,6 +2029,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
zxing2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: zxing2
|
||||
sha256: "2677c49a3b9ca9457cb1d294fd4bd5041cac6aab8cdb07b216ba4e98945c684f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.4"
|
||||
sdks:
|
||||
dart: ">=3.7.2 <4.0.0"
|
||||
flutter: ">=3.29.0"
|
||||
|
||||
@@ -84,6 +84,7 @@ dependencies:
|
||||
google_nav_bar: ^5.0.5 #supported
|
||||
gradient_borders: ^1.0.0
|
||||
http: ^1.1.0
|
||||
image: ^4.5.4
|
||||
intl: ^0.20.2
|
||||
io: ^1.0.4
|
||||
json_annotation: ^4.5.0
|
||||
@@ -130,6 +131,7 @@ dependencies:
|
||||
win32: ^5.1.1
|
||||
window_manager: ^0.5.0
|
||||
xdg_directories: ^1.0.4
|
||||
zxing2: ^0.2.4
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.1.11
|
||||
|
||||
Reference in New Issue
Block a user