diff --git a/lib/Screens/Configurations/Section/section_detail_screen.dart b/lib/Screens/Configurations/Section/section_detail_screen.dart index e703d1b..9c20828 100644 --- a/lib/Screens/Configurations/Section/section_detail_screen.dart +++ b/lib/Screens/Configurations/Section/section_detail_screen.dart @@ -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/rendering.dart'; +import 'package:flutter/services.dart'; import 'package:manager_app/Components/check_input_container.dart'; import 'package:manager_app/Components/confirmation_dialog.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/Slider/slider_config.dart'; import 'package:qr_flutter/qr_flutter.dart'; +import 'package:pasteboard/pasteboard.dart'; + +import 'dart:html' as html; class SectionDetailScreen extends StatefulWidget { final String id; @@ -41,13 +51,15 @@ class _SectionDetailScreenState extends State { final appContext = Provider.of(context); Size size = MediaQuery.of(context).size; + GlobalKey globalKey = new GlobalKey(); + return FutureBuilder( future: getSection(widget.id, (appContext.getContext() as ManagerAppContext).clientAPI!), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { return Stack( children: [ - bodySection(snapshot.data, size, appContext, context), + bodySection(snapshot.data, size, appContext, context, globalKey), Align( alignment: AlignmentDirectional.bottomCenter, child: Container( @@ -71,7 +83,7 @@ class _SectionDetailScreenState extends State { ); } - Widget bodySection(SectionDTO? sectionDTO, Size size, AppContext appContext, BuildContext context) { + Widget bodySection(SectionDTO? sectionDTO, Size size, AppContext appContext, BuildContext context, GlobalKey globalKey) { return SingleChildScrollView( child: Column( //mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -157,14 +169,24 @@ class _SectionDetailScreenState extends State { Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( - width: size.width *0.1, - height: 125, - child: QrImage( - padding: EdgeInsets.only(left: 0.0, top: 5.0, bottom: 5.0), - data: sectionDTO!.id!, - version: QrVersions.auto, - size: 50.0, + InkWell( + onTap: () async { + var image = await _captureAndSharePng(globalKey, sectionDTO!.id!); + await readAndWriteFiles(image); + showNotification(kSuccess, kWhite, 'Ce QR code a été copié dans le presse papier', context, null); + }, + child: Container( + 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)) @@ -435,3 +457,29 @@ Future getSection(String sectionId, Client client) async { //print(section); return section; } + +Future _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 readAndWriteFiles(Uint8List? image) async { + await Pasteboard.writeImage(image); + + final files = await Pasteboard.files(); + print(files); +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index e71a16d..d21238c 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include 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); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 2e1de87..c242e0a 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + pasteboard ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index df18b27..c9dab27 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,10 +7,12 @@ import Foundation import audio_session import just_audio +import pasteboard import path_provider_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) + PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 50da93d..b4454e1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -551,6 +551,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.2" + pasteboard: + dependency: "direct main" + description: + name: pasteboard + sha256: "1c8b6a8b3f1d12e55d4e9404433cda1b4abe66db6b17bc2d2fb5965772c04674" + url: "https://pub.dev" + source: hosted + version: "0.2.0" path: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a7ce7e9..c85696c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,6 +52,7 @@ dependencies: # ref: 927f8cbc09b35d85245c095f2db8df9b186f6618 password_credential: ^0.3.1 diacritic: ^0.1.3 + pasteboard: ^0.2.0 manager_api_new: path: manager_api_new diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 8b6d468..7c2f20e 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + PasteboardPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PasteboardPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b93c4c3..6414160 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + pasteboard ) list(APPEND FLUTTER_FFI_PLUGIN_LIST