Copy QrCode as image + download
This commit is contained in:
parent
9de38c2cfc
commit
3585a67ee2
@ -1,4 +1,11 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:manager_app/Components/check_input_container.dart';
|
import 'package:manager_app/Components/check_input_container.dart';
|
||||||
import 'package:manager_app/Components/confirmation_dialog.dart';
|
import 'package:manager_app/Components/confirmation_dialog.dart';
|
||||||
import 'package:manager_app/Components/fetch_section_icon.dart';
|
import 'package:manager_app/Components/fetch_section_icon.dart';
|
||||||
@ -25,6 +32,9 @@ import 'SubSection/Menu/menu_config.dart';
|
|||||||
import 'SubSection/Quizz/quizz_config.dart';
|
import 'SubSection/Quizz/quizz_config.dart';
|
||||||
import 'SubSection/Slider/slider_config.dart';
|
import 'SubSection/Slider/slider_config.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
|
import 'package:pasteboard/pasteboard.dart';
|
||||||
|
|
||||||
|
import 'dart:html' as html;
|
||||||
|
|
||||||
class SectionDetailScreen extends StatefulWidget {
|
class SectionDetailScreen extends StatefulWidget {
|
||||||
final String id;
|
final String id;
|
||||||
@ -41,13 +51,15 @@ class _SectionDetailScreenState extends State<SectionDetailScreen> {
|
|||||||
final appContext = Provider.of<AppContext>(context);
|
final appContext = Provider.of<AppContext>(context);
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
|
GlobalKey globalKey = new GlobalKey();
|
||||||
|
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: getSection(widget.id, (appContext.getContext() as ManagerAppContext).clientAPI!),
|
future: getSection(widget.id, (appContext.getContext() as ManagerAppContext).clientAPI!),
|
||||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
bodySection(snapshot.data, size, appContext, context),
|
bodySection(snapshot.data, size, appContext, context, globalKey),
|
||||||
Align(
|
Align(
|
||||||
alignment: AlignmentDirectional.bottomCenter,
|
alignment: AlignmentDirectional.bottomCenter,
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -71,7 +83,7 @@ class _SectionDetailScreenState extends State<SectionDetailScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget bodySection(SectionDTO? sectionDTO, Size size, AppContext appContext, BuildContext context) {
|
Widget bodySection(SectionDTO? sectionDTO, Size size, AppContext appContext, BuildContext context, GlobalKey globalKey) {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
//mainAxisAlignment: MainAxisAlignment.spaceAround,
|
//mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
@ -157,14 +169,24 @@ class _SectionDetailScreenState extends State<SectionDetailScreen> {
|
|||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
InkWell(
|
||||||
width: size.width *0.1,
|
onTap: () async {
|
||||||
height: 125,
|
var image = await _captureAndSharePng(globalKey, sectionDTO!.id!);
|
||||||
child: QrImage(
|
await readAndWriteFiles(image);
|
||||||
padding: EdgeInsets.only(left: 0.0, top: 5.0, bottom: 5.0),
|
showNotification(kSuccess, kWhite, 'Ce QR code a été copié dans le presse papier', context, null);
|
||||||
data: sectionDTO!.id!,
|
},
|
||||||
version: QrVersions.auto,
|
child: Container(
|
||||||
size: 50.0,
|
width: size.width *0.1,
|
||||||
|
height: 125,
|
||||||
|
child: RepaintBoundary(
|
||||||
|
key: globalKey,
|
||||||
|
child: QrImage(
|
||||||
|
padding: EdgeInsets.only(left: 5.0, top: 5.0, bottom: 5.0, right: 5.0),
|
||||||
|
data: sectionDTO!.id!,
|
||||||
|
version: QrVersions.auto,
|
||||||
|
size: 50.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SelectableText(sectionDTO.id!, style: new TextStyle(fontSize: 15))
|
SelectableText(sectionDTO.id!, style: new TextStyle(fontSize: 15))
|
||||||
@ -435,3 +457,29 @@ Future<SectionDTO?> getSection(String sectionId, Client client) async {
|
|||||||
//print(section);
|
//print(section);
|
||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Uint8List?> _captureAndSharePng(GlobalKey globalKey, String sectionId) async {
|
||||||
|
try {
|
||||||
|
RenderRepaintBoundary ? boundary = globalKey.currentContext!.findRenderObject()! as RenderRepaintBoundary;
|
||||||
|
var image = await boundary.toImage();
|
||||||
|
ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
|
||||||
|
Uint8List pngBytes = byteData!.buffer.asUint8List();
|
||||||
|
final base64data = base64.encode(pngBytes);
|
||||||
|
final a = html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
|
||||||
|
a.download = '$sectionId.jpg';
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
return pngBytes;
|
||||||
|
|
||||||
|
} catch(e) {
|
||||||
|
print(e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> readAndWriteFiles(Uint8List? image) async {
|
||||||
|
await Pasteboard.writeImage(image);
|
||||||
|
|
||||||
|
final files = await Pasteboard.files();
|
||||||
|
print(files);
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <pasteboard/pasteboard_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) pasteboard_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
|
||||||
|
pasteboard_plugin_register_with_registrar(pasteboard_registrar);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
pasteboard
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
@ -7,10 +7,12 @@ import Foundation
|
|||||||
|
|
||||||
import audio_session
|
import audio_session
|
||||||
import just_audio
|
import just_audio
|
||||||
|
import pasteboard
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||||
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
||||||
|
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -551,6 +551,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.2"
|
version: "0.3.2"
|
||||||
|
pasteboard:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: pasteboard
|
||||||
|
sha256: "1c8b6a8b3f1d12e55d4e9404433cda1b4abe66db6b17bc2d2fb5965772c04674"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -52,6 +52,7 @@ dependencies:
|
|||||||
# ref: 927f8cbc09b35d85245c095f2db8df9b186f6618
|
# ref: 927f8cbc09b35d85245c095f2db8df9b186f6618
|
||||||
password_credential: ^0.3.1
|
password_credential: ^0.3.1
|
||||||
diacritic: ^0.1.3
|
diacritic: ^0.1.3
|
||||||
|
pasteboard: ^0.2.0
|
||||||
manager_api_new:
|
manager_api_new:
|
||||||
path: manager_api_new
|
path: manager_api_new
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <pasteboard/pasteboard_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
PasteboardPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("PasteboardPlugin"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
pasteboard
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user