add qr share
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pretty_qr_code/pretty_qr_code.dart';
|
||||||
|
|
||||||
|
Future<void> showQrCode(BuildContext context, String data) {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return Dialog(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Share QR Code',
|
||||||
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
child: PrettyQrView.data(
|
||||||
|
data: data,
|
||||||
|
decoration: const PrettyQrDecoration(
|
||||||
|
image: PrettyQrDecorationImage(
|
||||||
|
image: AssetImage('assets/icon/icon.png'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: const Text('Close'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
+6
-3
@@ -12,9 +12,11 @@ import 'package:weblibre/features/bangs/domain/providers/bangs.dart';
|
|||||||
import 'package:weblibre/features/bangs/presentation/widgets/site_search.dart';
|
import 'package:weblibre/features/bangs/presentation/widgets/site_search.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart';
|
import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/qr_code.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/address_with_suggestions_field.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/address_with_suggestions_field.dart';
|
||||||
import 'package:weblibre/features/user/domain/providers.dart';
|
import 'package:weblibre/features/user/domain/providers.dart';
|
||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
|
import 'package:weblibre/presentation/widgets/share_tile.dart';
|
||||||
import 'package:weblibre/presentation/widgets/website_feed_tile.dart';
|
import 'package:weblibre/presentation/widgets/website_feed_tile.dart';
|
||||||
import 'package:weblibre/presentation/widgets/website_title_tile.dart';
|
import 'package:weblibre/presentation/widgets/website_title_tile.dart';
|
||||||
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
|
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
|
||||||
@@ -180,9 +182,7 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ShareTile(
|
||||||
leading: const Icon(Icons.share),
|
|
||||||
title: const Text('Share link'),
|
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await SharePlus.instance.share(
|
await SharePlus.instance.share(
|
||||||
ShareParams(uri: url),
|
ShareParams(uri: url),
|
||||||
@@ -192,6 +192,9 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onTapQr: () async {
|
||||||
|
await showQrCode(context, url.toString());
|
||||||
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.mobile_screen_share),
|
leading: const Icon(Icons.mobile_screen_share),
|
||||||
|
|||||||
+11
-4
@@ -4,7 +4,9 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:nullability/nullability.dart';
|
import 'package:nullability/nullability.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/qr_code.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
import 'package:weblibre/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
import 'package:weblibre/presentation/widgets/share_tile.dart';
|
||||||
|
|
||||||
class ShareLink extends HookConsumerWidget {
|
class ShareLink extends HookConsumerWidget {
|
||||||
final HitResult hitResult;
|
final HitResult hitResult;
|
||||||
@@ -17,11 +19,11 @@ class ShareLink extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return ListTile(
|
final link = hitResult.tryGetLink();
|
||||||
leading: const Icon(Icons.share),
|
|
||||||
title: const Text('Share link'),
|
return ShareTile(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await hitResult.tryGetLink().mapNotNull(
|
await link.mapNotNull(
|
||||||
(url) => SharePlus.instance.share(ShareParams(uri: url)),
|
(url) => SharePlus.instance.share(ShareParams(uri: url)),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -29,6 +31,11 @@ class ShareLink extends HookConsumerWidget {
|
|||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onTapQr: link.mapNotNull(
|
||||||
|
(url) => () async {
|
||||||
|
await showQrCode(context, url.toString());
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ShareTile extends StatelessWidget {
|
||||||
|
final void Function()? onTap;
|
||||||
|
final void Function()? onTapQr;
|
||||||
|
|
||||||
|
const ShareTile({super.key, this.onTap, this.onTapQr});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(Icons.share),
|
||||||
|
title: const Text('Share link'),
|
||||||
|
onTap: onTap,
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const VerticalDivider(indent: 4, endIndent: 4),
|
||||||
|
IconButton(icon: const Icon(Icons.qr_code), onPressed: onTapQr),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,6 +47,7 @@ dependencies:
|
|||||||
package_info_plus: ^8.3.0
|
package_info_plus: ^8.3.0
|
||||||
path: ^1.9.1
|
path: ^1.9.1
|
||||||
path_provider: ^2.1.5
|
path_provider: ^2.1.5
|
||||||
|
pretty_qr_code: ^3.4.0
|
||||||
riverpod: ^2.6.1
|
riverpod: ^2.6.1
|
||||||
riverpod_annotation: ^2.6.1
|
riverpod_annotation: ^2.6.1
|
||||||
rss_dart: ^1.0.12
|
rss_dart: ^1.0.12
|
||||||
|
|||||||
Reference in New Issue
Block a user