update invoice section show download option
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -6,8 +6,11 @@
|
|||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="28" />
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
|
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_DOCUMENTS" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
class ApiConfig {
|
class ApiConfig {
|
||||||
static const String baseUrl = "http://10.119.0.74:8000/api";
|
static const String baseUrl = "http://10.119.0.74:8000/api";
|
||||||
|
static const String fileBaseUrl = "http://10.119.0.74:8000/";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,17 +176,17 @@ class InstallmentCard extends StatelessWidget {
|
|||||||
Divider(color: Colors.grey.shade300, thickness: 1),
|
Divider(color: Colors.grey.shade300, thickness: 1),
|
||||||
SizedBox(height: isTablet ? 10 : 6),
|
SizedBox(height: isTablet ? 10 : 6),
|
||||||
|
|
||||||
Align(
|
// Align(
|
||||||
alignment: Alignment.centerRight,
|
// alignment: Alignment.centerRight,
|
||||||
child: Text(
|
// child: Text(
|
||||||
"Installment #${inst['id'] ?? ''}",
|
// "Installment #${inst['id'] ?? ''}",
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
fontSize: isTablet ? 15 : 13,
|
// fontSize: isTablet ? 15 : 13,
|
||||||
color: Colors.grey.shade600,
|
// color: Colors.grey.shade600,
|
||||||
fontWeight: FontWeight.w500,
|
// fontWeight: FontWeight.w500,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
import 'package:pdf/widgets.dart' as pw;
|
|
||||||
import 'package:share_plus/share_plus.dart';
|
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
import '../config/api_config.dart';
|
||||||
import '../services/dio_client.dart';
|
import '../services/dio_client.dart';
|
||||||
import '../services/invoice_service.dart';
|
import '../services/invoice_service.dart';
|
||||||
import '../widgets/invoice_detail_view.dart';
|
import '../widgets/invoice_detail_view.dart';
|
||||||
@@ -26,9 +29,6 @@ class _InvoiceDetailScreenState extends State<InvoiceDetailScreen> {
|
|||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// ⭐ LOAD INVOICE FROM API
|
|
||||||
// -------------------------------------------------------
|
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
final service = InvoiceService(DioClient.getInstance(context));
|
final service = InvoiceService(DioClient.getInstance(context));
|
||||||
try {
|
try {
|
||||||
@@ -40,93 +40,116 @@ class _InvoiceDetailScreenState extends State<InvoiceDetailScreen> {
|
|||||||
invoice = {};
|
invoice = {};
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// handle error gracefully
|
||||||
invoice = {};
|
invoice = {};
|
||||||
} finally {
|
} finally {
|
||||||
if (mounted) setState(() => loading = false);
|
if (mounted) setState(() => loading = false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
String? get pdfUrl {
|
||||||
// ⭐ GENERATE + SAVE PDF TO DOWNLOADS FOLDER
|
final path = invoice['pdf_path'];
|
||||||
// (No Permission Needed)
|
if (path == null || path.toString().isEmpty) return null;
|
||||||
// -------------------------------------------------------
|
|
||||||
Future<File> generatePDF() async {
|
|
||||||
final pdf = pw.Document();
|
|
||||||
|
|
||||||
pdf.addPage(
|
return ApiConfig.fileBaseUrl + path;
|
||||||
pw.Page(
|
}
|
||||||
build: (context) => pw.Column(
|
|
||||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
pw.Text(
|
|
||||||
"INVOICE DETAILS",
|
|
||||||
style: pw.TextStyle(fontSize: 26, fontWeight: pw.FontWeight.bold),
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 20),
|
|
||||||
|
|
||||||
pw.Text("Invoice ID: ${invoice['id'] ?? '-'}"),
|
static const MethodChannel _mediaScanner =
|
||||||
pw.Text("Amount: ₹${invoice['amount'] ?? '-'}"),
|
MethodChannel('media_scanner');
|
||||||
pw.Text("Status: ${invoice['status'] ?? '-'}"),
|
|
||||||
pw.Text("Date: ${invoice['date'] ?? '-'}"),
|
|
||||||
pw.Text("Customer: ${invoice['customer_name'] ?? '-'}"),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// ⭐ SAFEST WAY (Android 10–14)
|
Future<void> _scanFile(String path) async {
|
||||||
final downloadsDir = await getDownloadsDirectory();
|
try {
|
||||||
|
await _mediaScanner.invokeMethod('scanFile', {'path': path});
|
||||||
final filePath = "${downloadsDir!.path}/invoice_${invoice['id']}.pdf";
|
} catch (e) {
|
||||||
final file = File(filePath);
|
debugPrint("❌ MediaScanner error: $e");
|
||||||
|
|
||||||
await file.writeAsBytes(await pdf.save());
|
|
||||||
|
|
||||||
if (mounted) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(content: Text("PDF saved to Downloads:\n$filePath")),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// ⭐ SHARE THE SAVED PDF FILE
|
|
||||||
// -------------------------------------------------------
|
|
||||||
Future<void> sharePDF() async {
|
|
||||||
final file = await generatePDF();
|
|
||||||
|
|
||||||
await Share.shareXFiles(
|
|
||||||
[XFile(file.path)],
|
Future<File?> _downloadPdf(String url) async {
|
||||||
text: "Invoice Details",
|
try {
|
||||||
);
|
debugPrint("📥 PDF URL: $url");
|
||||||
|
|
||||||
|
final fileName = url.split('/').last;
|
||||||
|
|
||||||
|
// ✅ SAME FOLDER AS CHAT FILES
|
||||||
|
final baseDir = Directory('/storage/emulated/0/Download/KentChat');
|
||||||
|
|
||||||
|
if (!await baseDir.exists()) {
|
||||||
|
await baseDir.create(recursive: true);
|
||||||
|
debugPrint("📁 Created directory: ${baseDir.path}");
|
||||||
|
}
|
||||||
|
|
||||||
|
final filePath = "${baseDir.path}/$fileName";
|
||||||
|
debugPrint("📄 Saving PDF to: $filePath");
|
||||||
|
|
||||||
|
await Dio().download(
|
||||||
|
url,
|
||||||
|
filePath,
|
||||||
|
onReceiveProgress: (received, total) {
|
||||||
|
if (total > 0) {
|
||||||
|
debugPrint(
|
||||||
|
"⬇ Downloading: ${(received / total * 100).toStringAsFixed(1)}%",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 🔔 VERY IMPORTANT: Notify Android system (same as chat)
|
||||||
|
await _scanFile(filePath);
|
||||||
|
|
||||||
|
debugPrint("✅ PDF Downloaded & Scanned Successfully");
|
||||||
|
|
||||||
|
return File(filePath);
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("❌ PDF download error: $e");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final width = MediaQuery.of(context).size.width;
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
// ⭐ COMPACT RESPONSIVE SCALE
|
||||||
final scale = (width / 430).clamp(0.88, 1.08);
|
final scale = (width / 430).clamp(0.88, 1.08);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: const Text("Invoice Details"),
|
||||||
"Invoice Details",
|
actions: pdfUrl == null
|
||||||
style: TextStyle(
|
? []
|
||||||
fontSize: 18 * scale,
|
: [
|
||||||
fontWeight: FontWeight.w600,
|
// DOWNLOAD
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.download_rounded),
|
||||||
|
onPressed: () async {
|
||||||
|
final file = await _downloadPdf(pdfUrl!);
|
||||||
|
if (file != null && mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text("Invoice downloaded")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
|
|
||||||
// ⭐ PDF + SHARE BUTTONS
|
// SHARE
|
||||||
actions: [
|
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.picture_as_pdf),
|
icon: const Icon(Icons.share_rounded),
|
||||||
onPressed: generatePDF,
|
onPressed: () async {
|
||||||
),
|
final file = await _downloadPdf(pdfUrl!);
|
||||||
IconButton(
|
if (file != null) {
|
||||||
icon: const Icon(Icons.share),
|
await Share.shareXFiles(
|
||||||
onPressed: sharePDF,
|
[XFile(file.path)],
|
||||||
|
text: "Invoice ${invoice['invoice_number']}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -146,6 +169,8 @@ class _InvoiceDetailScreenState extends State<InvoiceDetailScreen> {
|
|||||||
)
|
)
|
||||||
: Padding(
|
: Padding(
|
||||||
padding: EdgeInsets.all(12 * scale),
|
padding: EdgeInsets.all(12 * scale),
|
||||||
|
// NOTE: InvoiceDetailView should handle its own responsiveness.
|
||||||
|
// If you want it to follow the same `scale`, I can update that widget to accept `scale`.
|
||||||
child: InvoiceDetailView(invoice: invoice),
|
child: InvoiceDetailView(invoice: invoice),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -92,9 +92,9 @@ class _OrderInvoiceScreenState extends State<OrderInvoiceScreen>
|
|||||||
_detailRow(Icons.numbers, "Invoice No", invoice['invoice_number'], scale),
|
_detailRow(Icons.numbers, "Invoice No", invoice['invoice_number'], scale),
|
||||||
_detailRow(Icons.calendar_month, "Invoice Date", invoice['invoice_date'], scale),
|
_detailRow(Icons.calendar_month, "Invoice Date", invoice['invoice_date'], scale),
|
||||||
_detailRow(Icons.date_range, "Due Date", invoice['due_date'], scale),
|
_detailRow(Icons.date_range, "Due Date", invoice['due_date'], scale),
|
||||||
_detailRow(Icons.payment, "Payment Method", invoice['payment_method'], scale),
|
// _detailRow(Icons.payment, "Payment Method", invoice['payment_method'], scale),
|
||||||
_detailRow(Icons.confirmation_number, "Reference No",
|
// _detailRow(Icons.confirmation_number, "Reference No",
|
||||||
invoice['reference_no'], scale),
|
// invoice['reference_no'], scale),
|
||||||
], scale),
|
], scale),
|
||||||
|
|
||||||
// AMOUNT SECTION
|
// AMOUNT SECTION
|
||||||
@@ -103,6 +103,7 @@ class _OrderInvoiceScreenState extends State<OrderInvoiceScreen>
|
|||||||
}, scale),
|
}, scale),
|
||||||
_sectionBody(s2, [
|
_sectionBody(s2, [
|
||||||
_detailRow(Icons.money, "Amount", invoice['final_amount'], scale),
|
_detailRow(Icons.money, "Amount", invoice['final_amount'], scale),
|
||||||
|
_detailRow(Icons.percent, "GST percent", invoice['gst_percent'], scale),
|
||||||
_detailRow(Icons.percent, "GST Amount", invoice['gst_amount'], scale),
|
_detailRow(Icons.percent, "GST Amount", invoice['gst_amount'], scale),
|
||||||
_detailRow(Icons.summarize, "Final With GST",
|
_detailRow(Icons.summarize, "Final With GST",
|
||||||
invoice['final_amount_with_gst'], scale),
|
invoice['final_amount_with_gst'], scale),
|
||||||
|
|||||||
@@ -4,55 +4,30 @@ class InvoiceService {
|
|||||||
final Dio dio;
|
final Dio dio;
|
||||||
InvoiceService(this.dio);
|
InvoiceService(this.dio);
|
||||||
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// ⭐ GET ALL INVOICES
|
|
||||||
// -------------------------------------------------------
|
|
||||||
Future<Map<String, dynamic>> getAllInvoices() async {
|
Future<Map<String, dynamic>> getAllInvoices() async {
|
||||||
try {
|
try {
|
||||||
final res = await dio.get("/user/invoices");
|
final res = await dio.get("/user/invoices");
|
||||||
|
|
||||||
print("🔵 ALL INVOICES RESPONSE:");
|
|
||||||
print(res.data);
|
|
||||||
|
|
||||||
return Map<String, dynamic>.from(res.data);
|
return Map<String, dynamic>.from(res.data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("❌ ERROR (All Invoices): $e");
|
|
||||||
return {"success": false, "message": e.toString()};
|
return {"success": false, "message": e.toString()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// ⭐ GET INSTALLMENTS
|
|
||||||
// -------------------------------------------------------
|
|
||||||
Future<Map<String, dynamic>> getInstallments(int invoiceId) async {
|
Future<Map<String, dynamic>> getInstallments(int invoiceId) async {
|
||||||
try {
|
try {
|
||||||
final res =
|
final res = await dio.get("/user/invoice/$invoiceId/installments");
|
||||||
await dio.get("/user/invoice/$invoiceId/installments");
|
|
||||||
|
|
||||||
print("🔵 INSTALLMENTS RESPONSE:");
|
|
||||||
print(res.data);
|
|
||||||
|
|
||||||
return Map<String, dynamic>.from(res.data);
|
return Map<String, dynamic>.from(res.data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("❌ ERROR (Installments): $e");
|
|
||||||
return {"success": false, "message": e.toString()};
|
return {"success": false, "message": e.toString()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
/// 🔵 NEW FUNCTION — Fetch Full Invoice Details
|
||||||
// ⭐ GET FULL INVOICE DETAILS (PRINT JSON HERE)
|
|
||||||
// -------------------------------------------------------
|
|
||||||
Future<Map<String, dynamic>> getInvoiceDetails(int invoiceId) async {
|
Future<Map<String, dynamic>> getInvoiceDetails(int invoiceId) async {
|
||||||
try {
|
try {
|
||||||
final res = await dio.get("/user/invoice/$invoiceId/details");
|
final res = await dio.get("/user/invoice/$invoiceId/details");
|
||||||
|
|
||||||
print("👇👇👇 INVOICE API RESPONSE START 👇👇👇");
|
|
||||||
print(res.data); // <-- THIS IS WHAT YOU NEED
|
|
||||||
print("👆👆👆 INVOICE API RESPONSE END 👆👆👆");
|
|
||||||
|
|
||||||
return Map<String, dynamic>.from(res.data);
|
return Map<String, dynamic>.from(res.data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("❌ ERROR (Invoice Details): $e");
|
|
||||||
return {"success": false, "message": e.toString()};
|
return {"success": false, "message": e.toString()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,17 +298,18 @@ class _InvoiceDetailViewState extends State<InvoiceDetailView>
|
|||||||
() => setState(() => s3 = !s3), scale),
|
() => setState(() => s3 = !s3), scale),
|
||||||
sectionBody(s3, [
|
sectionBody(s3, [
|
||||||
detailRow(Icons.money, "Amount", invoice['final_amount'], scale),
|
detailRow(Icons.money, "Amount", invoice['final_amount'], scale),
|
||||||
detailRow(Icons.percent, "GST %", invoice['gst_percent'], scale),
|
detailRow(Icons.percent, "GST percent %", invoice['gst_percent'], scale),
|
||||||
|
detailRow(Icons.percent, "GST amount %", invoice['gst_amount'], scale),
|
||||||
detailRow(Icons.summarize, "Total", invoice['final_amount_with_gst'], scale),
|
detailRow(Icons.summarize, "Total", invoice['final_amount_with_gst'], scale),
|
||||||
], scale),
|
], scale),
|
||||||
|
|
||||||
sectionHeader("Payment Details", Icons.payment, s4,
|
// sectionHeader("Payment Details", Icons.payment, s4,
|
||||||
() => setState(() => s4 = !s4), scale),
|
// () => setState(() => s4 = !s4), scale),
|
||||||
sectionBody(s4, [
|
// sectionBody(s4, [
|
||||||
detailRow(Icons.credit_card, "Method", invoice['payment_method'], scale),
|
// detailRow(Icons.credit_card, "Method", invoice['payment_method'], scale),
|
||||||
detailRow(Icons.confirmation_number, "Reference",
|
// detailRow(Icons.confirmation_number, "Reference",
|
||||||
invoice['reference_no'], scale),
|
// invoice['reference_no'], scale),
|
||||||
], scale),
|
// ], scale),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
48
pubspec.lock
48
pubspec.lock
@@ -544,6 +544,54 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.11.3"
|
version: "3.11.3"
|
||||||
|
permission_handler:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: permission_handler
|
||||||
|
sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.4.0"
|
||||||
|
permission_handler_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_android
|
||||||
|
sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "12.1.0"
|
||||||
|
permission_handler_apple:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_apple
|
||||||
|
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.4.7"
|
||||||
|
permission_handler_html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_html
|
||||||
|
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3+5"
|
||||||
|
permission_handler_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_platform_interface
|
||||||
|
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
|
permission_handler_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_windows
|
||||||
|
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ dependencies:
|
|||||||
video_player: ^2.9.1
|
video_player: ^2.9.1
|
||||||
chewie: ^1.8.1
|
chewie: ^1.8.1
|
||||||
flutter_pdfview: ^1.3.2
|
flutter_pdfview: ^1.3.2
|
||||||
|
permission_handler: ^11.3.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,15 @@
|
|||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
|
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||||
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
FileSelectorWindowsRegisterWithRegistrar(
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||||
|
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
|
permission_handler_windows
|
||||||
share_plus
|
share_plus
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user