Show option on mobile only

This commit is contained in:
Neeraj Gupta
2025-08-21 15:16:21 +05:30
parent 5b3e996aaa
commit 38ea2248b8
9 changed files with 253 additions and 22 deletions

View File

@@ -875,21 +875,22 @@ 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,
),
SpeedDialChild(
child: const Icon(Icons.photo_library),
backgroundColor: Theme.of(context).colorScheme.fabBackgroundColor,
foregroundColor: Theme.of(context).colorScheme.fabForegroundColor,
labelWidget:
const SpeedDialLabelWidget("Import from Gallery (Native)"),
onTap: _importFromGalleryNative,
),
if (PlatformUtil.isMobile())
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,
),
if (PlatformUtil.isMobile())
SpeedDialChild(
child: const Icon(Icons.photo_library),
backgroundColor: Theme.of(context).colorScheme.fabBackgroundColor,
foregroundColor: Theme.of(context).colorScheme.fabForegroundColor,
labelWidget: const SpeedDialLabelWidget("Scan image (Native)"),
onTap: _importFromGalleryNative,
),
],
);
}

View File

@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:ente_qr/ente_qr.dart';
class QrTestPage extends StatefulWidget {
@override
_QrTestPageState createState() => _QrTestPageState();
}
class _QrTestPageState extends State<QrTestPage> {
String _platformVersion = 'Unknown';
final _enteQr = EnteQr();
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
String platformVersion;
try {
platformVersion =
await _enteQr.getPlatformVersion() ?? 'Unknown platform version';
} catch (e) {
platformVersion = 'Failed to get platform version: $e';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('QR Plugin Test'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
);
}
}

View File

@@ -1 +1 @@
include: ../../../../analysis_options.yaml
include: ../../analysis_options.yaml

View File

@@ -0,0 +1,15 @@
import Flutter
import UIKit
import ente_qr
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@@ -0,0 +1,124 @@
import 'dart:async';
import 'package:ente_qr/ente_qr.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
String _qrResult = 'No QR code scanned yet';
final _enteQrPlugin = EnteQr();
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion = await _enteQrPlugin.getPlatformVersion() ??
'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
Future<void> _pickImageAndScanQr() async {
try {
final FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.image,
allowMultiple: false,
);
if (result != null && result.files.single.path != null) {
final String imagePath = result.files.single.path!;
setState(() {
_qrResult = 'Scanning QR code...';
});
final QrScanResult qrResult =
await _enteQrPlugin.scanQrFromImage(imagePath);
setState(() {
if (qrResult.success) {
_qrResult = 'QR Code found: ${qrResult.content}';
} else {
_qrResult = 'Error: ${qrResult.error}';
}
});
} else {
setState(() {
_qrResult = 'No image selected';
});
}
} catch (e) {
setState(() {
_qrResult = 'Error picking file: $e';
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Ente QR Plugin Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('Running on: $_platformVersion\n'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _pickImageAndScanQr,
child: const Text('Pick Image and Scan QR Code'),
),
const SizedBox(height: 20),
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: Text(
_qrResult,
style: const TextStyle(fontSize: 16),
),
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,45 @@
name: ente_qr_example
description: "Demonstrates how to use the ente_qr plugin."
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: '>=3.4.3 <4.0.0'
dependencies:
flutter:
sdk: flutter
ente_qr:
# When depending on this package from a real application you should use:
# ente_qr: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
file_picker: ^5.5.0
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^3.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true

View File

@@ -8,12 +8,12 @@ class EnteQr {
}
/// Scans a QR code from an image file at the given path.
///
///
/// [imagePath] - The file path to the image containing the QR code
///
///
/// Returns a [QrScanResult] containing either the QR code content on success
/// or an error message on failure.
///
///
/// Example:
/// ```dart
/// final qr = EnteQr();

View File

@@ -28,7 +28,8 @@ class MethodChannelEnteQr extends EnteQrPlatform {
}
// Convert to Map<String, dynamic> safely
final Map<String, dynamic> resultMap = Map<String, dynamic>.from(result as Map);
final Map<String, dynamic> resultMap =
Map<String, dynamic>.from(result as Map);
final bool success = resultMap['success'] as bool? ?? false;
if (success) {

View File

@@ -7,12 +7,11 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart';
class MockEnteQrPlatform
with MockPlatformInterfaceMixin
implements EnteQrPlatform {
@override
Future<String?> getPlatformVersion() => Future.value('42');
@override
Future<QrScanResult> scanQrFromImage(String imagePath) =>
Future<QrScanResult> scanQrFromImage(String imagePath) =>
Future.value(QrScanResult.error('Mock implementation'));
}