diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index 65d7660..5d8c11f 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,13 @@ + + + + + android:icon="@mipmap/ic_launcher" + android:requestLegacyExternalStorage="true"> (create: (_) => get() - ..add( - InitEvent(), - )), BlocProvider( create: (_) => get() ..add( OnboardingAuthEvent(), ), - lazy: false, ), BlocProvider(create: (context) => QuizRegistrationCubit()), ], child: MaterialApp.router( theme: ThemeData( - textTheme: GoogleFonts.poppinsTextTheme(), + textTheme: GoogleFonts.interTextTheme(), ), routerConfig: router, debugShowCheckedModeBanner: false, diff --git a/app/lib/core/constants/BebrasGroupCategory.dart b/app/lib/core/constants/BebrasGroupCategory.dart new file mode 100644 index 0000000..82e1959 --- /dev/null +++ b/app/lib/core/constants/BebrasGroupCategory.dart @@ -0,0 +1,13 @@ +class BebrasGroupCategory { + final int index; + final String bebrasChallengeKey; + + const BebrasGroupCategory(this.index, this.bebrasChallengeKey); +} + +List bebrasGroupList = [ + BebrasGroupCategory(0, 'sikecil'), + BebrasGroupCategory(1, 'siaga'), + BebrasGroupCategory(2, 'penggalang'), + BebrasGroupCategory(3, 'penegak'), +]; \ No newline at end of file diff --git a/app/lib/core/constants/bebrasBookId.dart b/app/lib/core/constants/bebrasBookId.dart new file mode 100644 index 0000000..2393e47 --- /dev/null +++ b/app/lib/core/constants/bebrasBookId.dart @@ -0,0 +1,11 @@ +List bebrasMaterialIds = [ + "penegak_2016-buku_bebras", + "penegak_2017-buku_bebras", + "penegak_2018-buku_bebras", + "penggalang_2016-buku_bebras", + "penggalang_2017-buku_bebras", + "penggalang_2018-buku_bebras", + "siaga_2016-buku_bebras", + "siaga_2017-buku_bebras", + "siaga_2018-buku_bebras", +]; \ No newline at end of file diff --git a/app/lib/features/main/presentation/pages/main_page.dart b/app/lib/features/main/presentation/pages/main_page.dart index 27de950..08d87f3 100644 --- a/app/lib/features/main/presentation/pages/main_page.dart +++ b/app/lib/features/main/presentation/pages/main_page.dart @@ -63,7 +63,7 @@ class _MainPageState extends State { Button( buttonType: ButtonType.primary, onTap: () async { - await context.push('/construction'); + await context.push('/material'); }, text: 'Lihat Materi', ), diff --git a/app/lib/features/material/menu/presentation/pages/_pages.dart b/app/lib/features/material/menu/presentation/pages/_pages.dart new file mode 100644 index 0000000..99caa0c --- /dev/null +++ b/app/lib/features/material/menu/presentation/pages/_pages.dart @@ -0,0 +1,11 @@ + +import 'package:bebras_pandai/core/constants/BebrasGroupCategory.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_storage/firebase_storage.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import '../../../../../core/bases/widgets/layout/bebras_scaffold.dart'; +import '../../../../../core/constants/assets.dart'; + +part 'material_menu.dart'; \ No newline at end of file diff --git a/app/lib/features/material/menu/presentation/pages/material_menu.dart b/app/lib/features/material/menu/presentation/pages/material_menu.dart new file mode 100644 index 0000000..34e610b --- /dev/null +++ b/app/lib/features/material/menu/presentation/pages/material_menu.dart @@ -0,0 +1,210 @@ +part of '_pages.dart'; + +class MaterialMenu extends StatefulWidget { + const MaterialMenu({super.key}); + + @override + State createState() => _MaterialMenuState(); +} + +class _MaterialMenuState extends State { + final Stream materialsStream = + FirebaseFirestore.instance.collection('learning_material').snapshots(); + + String? selectedValue = null; + + int filterIndex = 0; + + Widget CustomRadioButton(String text, int index) { + return InkWell( + onTap: () { + setState(() { + filterIndex = index; + }); + }, + child: Container( + alignment: Alignment.center, + height: 40, + width: 130, + decoration: BoxDecoration( + border: Border.all(), + color: (filterIndex == index) ? Colors.black54 : Colors.white, + boxShadow: [ + BoxShadow( + color: (filterIndex == index) ? Colors.white : Colors.black, + blurRadius: 2.0, + spreadRadius: 0.0, + offset: (filterIndex == index) + ? Offset(0, 0) + : Offset(2.0, 2.0), // shadow direction: bottom right + ) + ], + ), + child: Text( + text, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: (filterIndex == index) ? Colors.white : Colors.black), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + return BebrasScaffold( + avoidBottomInset: false, + body: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Stack( + children: [ + Container( + padding: const EdgeInsets.all(32), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + Assets.bebrasPandaiText, + ), + const SizedBox( + height: 30, + ), + Container( + height: 40, + width: 296, // double.infinity, + decoration: BoxDecoration(border: Border.all()), + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + CustomRadioButton( + "siKecil", bebrasGroupList[0].index), + CustomRadioButton("Siaga", bebrasGroupList[1].index), + CustomRadioButton( + "Penggalang", bebrasGroupList[2].index), + CustomRadioButton( + "Penegak", bebrasGroupList[3].index), + ]), + ), + // Container( + // height: 70, + // width: 296, // double.infinity, + // decoration: BoxDecoration(border: Border.all()), + // child: Column( + // children: [ + // Row( + // children: [ + // CustomRadioButton( + // "siKecil", bebrasGroupList[0].index), + // CustomRadioButton( + // "Siaga", bebrasGroupList[1].index), + // ], + // ), + // Row( + // children: [ + // CustomRadioButton( + // "Penggalang", bebrasGroupList[2].index), + // CustomRadioButton( + // "Penegak", bebrasGroupList[3].index), + // ], + // ), + // ], + // ), + // ), + const SizedBox( + height: 10, + ), + Container( + width: double.infinity, + child: const Text('Daftar Materi')), + const SizedBox( + height: 10, + ), + StreamBuilder( + stream: materialsStream, + builder: (BuildContext context, + AsyncSnapshot snapshot) { + if (snapshot.hasError) { + return Text('Something went wrong'); + } + + if (snapshot.connectionState == + ConnectionState.waiting) { + return Text("Loading"); + } + + return Container( + height: 360, + decoration: BoxDecoration(border: Border.all()), + child: ListView( + children: snapshot.data!.docs + .map((DocumentSnapshot document) { + Map materialDoc = + document.data()! as Map; + if (materialDoc['challenge_group'] == + bebrasGroupList[filterIndex] + .bebrasChallengeKey) { + return InkWell( + onTap: () { + context.push(Uri( + path: '/material/${document.id}', + queryParameters: { + 'id': document.id, + 'title': materialDoc['title'], + 'description': + materialDoc['description'], + 'pdfUrl': materialDoc['gsReference'], + }).toString()); + }, + child: Container( + height: 80, + width: double.infinity, + padding: const EdgeInsets.symmetric( + horizontal: 16), + decoration: + BoxDecoration(border: Border.all()), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 7, vertical: 10), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + width: 140, + child: Text( + materialDoc['title'].toString(), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600), + ), + ), + Container( + width: 60, + child: Text( + 'Terakhir dilihat: 15/09', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + ], + ), + ), + ), + ); + } + return Container(); + }).toList(), + ), + ); + }), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/app/lib/features/material/viewer/presentation/pages/_pages.dart b/app/lib/features/material/viewer/presentation/pages/_pages.dart new file mode 100644 index 0000000..b0f23c8 --- /dev/null +++ b/app/lib/features/material/viewer/presentation/pages/_pages.dart @@ -0,0 +1,13 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:firebase_storage/firebase_storage.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_pdfview/flutter_pdfview.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:permission_handler/permission_handler.dart'; + + +part 'pdf_viewer_page.dart'; \ No newline at end of file diff --git a/app/lib/features/material/viewer/presentation/pages/pdf_viewer_page.dart b/app/lib/features/material/viewer/presentation/pages/pdf_viewer_page.dart new file mode 100644 index 0000000..bf3de81 --- /dev/null +++ b/app/lib/features/material/viewer/presentation/pages/pdf_viewer_page.dart @@ -0,0 +1,147 @@ +part of '_pages.dart'; + +class PdfViewerPage extends StatefulWidget { + final String? pdfUrl; + final String? id; + final String? title; + final String? description; + + const PdfViewerPage({ + Key? key, + required this.pdfUrl, + this.id, + this.title, + this.description, + }) : super(key: key); + + @override + State createState() => _PdfViewerPageState(); +} + +class _PdfViewerPageState extends State { + String basePath = "/storage/emulated/0/Android/data/com.toki.bebras_pandai/files/PDF_Download/"; + String localPathPdf = ""; + String remotePathPdf = ""; + + @override + void initState() { + super.initState(); + if (File(basePath + widget.id.toString() + ".pdf").existsSync()) { + setState(() { + localPathPdf = basePath + widget.id.toString() + ".pdf"; + }); + } + WidgetsBinding.instance.addPostFrameCallback((_) { + fetchUrlPdfFile(widget.pdfUrl.toString()); + }); + // WidgetsBinding.instance.addPostFrameCallback((_){ + // saveFile(widget.pdfUrl.toString(), "${widget.id}.pdf"); + // }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.black54, + title: Text( + widget.title.toString(), // name + style: TextStyle(color: Colors.white), + ), + actions: [ + IconButton( + onPressed: () async { + try { + await saveFile(remotePathPdf, "${widget.id}.pdf"); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'successfully saved to internal storage', + style: TextStyle(color: Colors.white), + ), + ), + ); + } catch (e) { + print(e); + } + }, + icon: const Icon(Icons.download_rounded), + ), + ], + ), + body: Stack( + children: [ + localPathPdf == '' ? + LinearProgressIndicator() : + PDFView( + filePath: localPathPdf, + onError: (error) { + print(error.toString()); + }, + onPageError: (page, error) { + print('$page: ${error.toString()}'); + }, + ), + ], + ), + ); + } + + Future saveFile(String url, String fileName) async { + try { + if (await _requestPermission(Permission.storage)) { + Directory? directory; + directory = await getExternalStorageDirectory(); + String newPath = ""; + newPath = directory!.path + "/PDF_Download"; + directory = Directory(newPath); + + File saveFile = File(directory.path + "/$fileName"); + if (kDebugMode) { + print(saveFile.path); + } + if (!await directory.exists()) { + await directory.create(recursive: true); + } + if (await directory.exists()) { + await Dio().download( + url, + saveFile.path, + ); + setState(() { + localPathPdf = saveFile.path; + }); + print(localPathPdf); + } + } + return true; + } catch (e) { + return false; + } + } + + Future _requestPermission(Permission permission) async { + if (await permission.isGranted) { + return true; + } else { + var result = await permission.request(); + if (result == PermissionStatus.granted) { + return true; + } + } + return false; + } + + Future fetchUrlPdfFile(String pathReference) async { + try { + final storageRef = FirebaseStorage.instance.ref(); + String url = await storageRef.child(pathReference).getDownloadURL(); + setState(() { + remotePathPdf = url; + }); + saveFile(url, "${widget.id}.pdf"); + } catch (e) { + debugPrint(e.toString()); + } + } +} diff --git a/app/lib/services/router_service.dart b/app/lib/services/router_service.dart index 868c9dd..4e04468 100644 --- a/app/lib/services/router_service.dart +++ b/app/lib/services/router_service.dart @@ -4,6 +4,8 @@ import '../features/authentication/register/presentation/pages/_pages.dart'; import '../features/authentication/signin/presentation/pages/_pages.dart'; import '../features/error/presentation/pages/_pages.dart'; import '../features/main/presentation/pages/_pages.dart'; +import '../features/material/menu/presentation/pages/_pages.dart'; +import '../features/material/viewer/presentation/pages/_pages.dart'; import '../features/onboarding/presentation/pages/_pages.dart'; import '../features/quiz_registration/presentation/pages/_pages.dart'; @@ -33,5 +35,17 @@ GoRouter router = GoRouter( path: '/quiz_registration', builder: (context, state) => const QuizRegistrationPage(), ), + GoRoute( + path: '/material', + builder: (context, state) => const MaterialMenu(), + ), + GoRoute( + path: '/material/:id', + builder: (context, state) => PdfViewerPage( + pdfUrl: state.queryParameters['pdfUrl'], + title: state.queryParameters['title'], + id: state.queryParameters['id'], + ), + ), ], ); diff --git a/app/macos/Flutter/GeneratedPluginRegistrant.swift b/app/macos/Flutter/GeneratedPluginRegistrant.swift index 2c93bec..9142ca0 100644 --- a/app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,6 +8,7 @@ import Foundation import cloud_firestore import firebase_auth import firebase_core +import firebase_storage import flutter_local_notifications import geolocator_apple import path_provider_foundation @@ -18,6 +19,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/app/pubspec.lock b/app/pubspec.lock index 18b216b..6758e74 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: d84d98f1992976775f83083523a34c5d22fea191eec3abb2bd09537fb623c2e0 + sha256: "76c15c4167f820b74abcd8c6fc5e393e1ed5e1207a34e9b22953603e03b3ba6a" url: "https://pub.dev" source: hosted - version: "1.3.7" + version: "1.3.9" analyzer: dependency: transitive description: @@ -173,26 +173,26 @@ packages: dependency: "direct main" description: name: cloud_firestore - sha256: "1179ae4c69e2ea18179d844d70fc6ed2f082a2bbeb7fa62d35a2a24e2992bd4d" + sha256: "019da47850fe2c86266a4b86e82e0d00dcb5bf0718f26fc70bf9df275ee16537" url: "https://pub.dev" source: hosted - version: "4.9.3" + version: "4.11.0" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface - sha256: acdcf0743bbdd0e6b342f3d2033e15d260a2c6f9434dd34b008b8f1c35e62b23 + sha256: "7e08cd322ff98ddfdb6ab8a89b24f895c473992d674bfd3b36865037879baa3f" url: "https://pub.dev" source: hosted - version: "5.16.2" + version: "6.0.1" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web - sha256: "321bb0732c8d782a49aede96805e59609e05cf98b6c34370faa04103f46a4a3a" + sha256: bd2183128b67d66a6e672c50e47bc70393418f3bd669aad8ac321e88f027b2b5 url: "https://pub.dev" source: hosted - version: "3.7.2" + version: "3.8.1" code_builder: dependency: transitive description: @@ -309,50 +309,74 @@ packages: dependency: "direct main" description: name: firebase_auth - sha256: "6d9be853426ab686d68076b8007ac29b2c31e7d549444a45b5c3fe1abc249fb0" + sha256: "46129e2733336ac77377174c3ca33a68cca2cd5848504aad63028aeb92afb7b2" url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.11.1" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface - sha256: "2946cfdc17f925fa9771dd0ba3ce9dd2d019100a8685d0557c161f7786ea9b14" + sha256: b89936896b2cc02496b97e486793fd4bcf8c51beb99d6a7223c0eea2352d404e url: "https://pub.dev" source: hosted - version: "6.18.0" + version: "7.0.1" firebase_auth_web: dependency: transitive description: name: firebase_auth_web - sha256: d8972d754702a3f4881184706b8056e2837d0dae91613a43b988c960b8e0d988 + sha256: "88b7655c9394d723e121fd53f115d876c32260b8c8b499bdc3108341044a8306" url: "https://pub.dev" source: hosted - version: "5.8.0" + version: "5.8.4" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "95580fa07c8ca3072a2bb1fecd792616a33f8683477d25b7d29d3a6a399e6ece" + sha256: "57bba167105d2315d243a4524939406df688f38a5b6d7a4159382bbbe43cdd00" url: "https://pub.dev" source: hosted - version: "2.17.0" + version: "2.19.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 + sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "5.0.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: e8c408923cd3a25bd342c576a114f2126769cd1a57106a4edeaa67ea4a84e962 + sha256: "0631a2ec971dbc540275e2fa00c3a8a2676f0a7adbc3c197d6fba569db689d97" url: "https://pub.dev" source: hosted - version: "2.8.0" + version: "2.8.1" + firebase_storage: + dependency: "direct main" + description: + name: firebase_storage + sha256: c23dfab4fbdafd014b579e2bcc5b23ca69457d9b8625a64dffb669d098cff6fe + url: "https://pub.dev" + source: hosted + version: "11.3.1" + firebase_storage_platform_interface: + dependency: transitive + description: + name: firebase_storage_platform_interface + sha256: "8650ba68840122f0c7e8a1a529d16580a5d00a614653d7167d7cd044c67fa245" + url: "https://pub.dev" + source: hosted + version: "4.4.9" + firebase_storage_web: + dependency: transitive + description: + name: firebase_storage_web + sha256: "93ac56b2a9722a94e0d752a4aa2dd5ec8c4ceeb8ff07121bb6580198dbede199" + url: "https://pub.dev" + source: hosted + version: "3.6.10" fixnum: dependency: transitive description: @@ -422,6 +446,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0+1" + flutter_pdfview: + dependency: "direct main" + description: + name: flutter_pdfview + sha256: a9055bf920c7095bf08c2781db431ba23577aa5da5a056a7152dc89a18fbec6f + url: "https://pub.dev" + source: hosted + version: "1.3.2" flutter_polyline_points: dependency: "direct main" description: @@ -864,6 +896,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8" + url: "https://pub.dev" + source: hosted + version: "11.0.1" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e + url: "https://pub.dev" + source: hosted + version: "11.1.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" + url: "https://pub.dev" + source: hosted + version: "9.1.4" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" + url: "https://pub.dev" + source: hosted + version: "3.12.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 + url: "https://pub.dev" + source: hosted + version: "0.1.3" petitparser: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 118146d..9bdd420 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -55,8 +55,11 @@ dependencies: firebase_auth: ^4.9.0 url_launcher: ^6.1.14 flutter_dotenv: ^5.1.0 + flutter_pdfview: ^1.3.2 + permission_handler: ^11.0.1 cloud_firestore: ^4.9.3 dropdown_search: ^5.0.6 + firebase_storage: ^11.3.1 dev_dependencies: build_runner: null @@ -71,10 +74,14 @@ dev_dependencies: # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec +permission: + git: + url: https://github.com/kamlesh9070/permission # 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. diff --git a/app/windows/flutter/generated_plugin_registrant.cc b/app/windows/flutter/generated_plugin_registrant.cc index 16039c1..8c7ce19 100644 --- a/app/windows/flutter/generated_plugin_registrant.cc +++ b/app/windows/flutter/generated_plugin_registrant.cc @@ -6,15 +6,24 @@ #include "generated_plugin_registrant.h" +#include +#include #include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + CloudFirestorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); + FirebaseAuthPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); FirebaseCorePluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); GeolocatorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("GeolocatorWindows")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/app/windows/flutter/generated_plugins.cmake b/app/windows/flutter/generated_plugins.cmake index e30096f..28b7120 100644 --- a/app/windows/flutter/generated_plugins.cmake +++ b/app/windows/flutter/generated_plugins.cmake @@ -3,8 +3,11 @@ # list(APPEND FLUTTER_PLUGIN_LIST + cloud_firestore + firebase_auth firebase_core geolocator_windows + permission_handler_windows url_launcher_windows )