6 次代码提交 66d3746491 ... cbf6f2aeaf

作者 SHA1 备注 提交日期
  juan cbf6f2aeaf Reinitialized repository and recommitted all files 1 月之前
  Juan Marulanda De Los Rios 66d3746491 changed to light theme 1 月之前
  Juan Marulanda De Los Rios 04fa186b2c doing the same as last commit 1 月之前
  Juan Marulanda De Los Rios b96209c872 update to current state 1 月之前
  juan b92f02c088 dumping 1 月之前
  juan 961607f978 Initial dump, and side bar 1 月之前

+ 43 - 0
.gitignore

@@ -0,0 +1,43 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.pub-cache/
+.pub/
+/build/
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release

+ 13 - 0
android/.gitignore

@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
+**/*.keystore
+**/*.jks

+ 3 - 0
android/.gitignore:Zone.Identifier

@@ -0,0 +1,3 @@
+[ZoneTransfer]
+ZoneId=3
+ReferrerUrl=C:\Users\juana\Flutter\flutter_windows_3.22.2-stable.zip

+ 228 - 193
lib/email.dart

@@ -1,193 +1,228 @@
-import 'package:flutter/material.dart';
-import 'package:http/http.dart' as http;
-import 'dart:convert';
-// import 'package:flutter_html/flutter_html.dart';
-
-class SerializableMessage {
-  final String name;
-  final String from;
-  final String path;
-  final String subject;
-  final String date;
-
-  SerializableMessage(
-      {required this.name,
-      required this.from,
-      required this.path,
-      required this.subject,
-      required this.date});
-
-  factory SerializableMessage.fromJson(Map<String, dynamic> json) {
-    return SerializableMessage(
-        name: json['name'],
-        from: json['from'],
-        path: json['path'],
-        subject: json['subject'],
-        date: json['date']);
-  }
-}
-
-class EmailPage extends StatefulWidget {
-  const EmailPage({super.key});
-  final String title = 'cars';
-
-  @override
-  State<EmailPage> createState() => _EmailPageState();
-}
-
-class _EmailPageState extends State<EmailPage> {
-  List emails = [];
-
-  void _displayEmailsFromFolder(String folder) async {
-    Map<String, List<SerializableMessage>> messagesMap = {};
-
-    try {
-      var url = Uri.http(
-          '127.0.0.1:3001', 'sorted_threads_by_date', {'folder': folder});
-      var response = await http.get(url);
-
-      Map<String, dynamic> json = jsonDecode(response.body);
-
-      json.forEach((key, value) {
-        List<SerializableMessage> messages = (value as List)
-            .map((item) => SerializableMessage.fromJson(item))
-            .toList();
-        messagesMap[key] = messages;
-      });
-    } catch (e) {
-      print('_displayEmailsFromFolder caught error: $e');
-    }
-    setState(() {
-      emails.clear();
-      emails = messagesMap.values.toList().expand((list) => list).toList();
-      ;
-    });
-  }
-
-  Future<List<Widget>> _getDrawerItems() async {
-    List<String> drawerItems = [];
-
-    try {
-      var url = Uri.http('127.0.0.1:3001', 'folders');
-      var response = await http.get(url);
-      drawerItems = List<String>.from(json.decode(response.body));
-    } catch (e) {
-      print('_getDrawerItems caught error: $e');
-    }
-
-    List<Widget> drawerWidgets = [];
-
-
-    for (String item in drawerItems) {
-      drawerWidgets.add(
-        ListTile(
-          leading: Icon(Icons.mail),
-          title: Text(item),
-          onTap: () {
-            _displayEmailsFromFolder(item);
-            Navigator.pop(context);
-          },
-        ),
-      );
-    }
-
-    return drawerWidgets;
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-      appBar: AppBar(
-        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
-        title: Text(widget.title),
-      ),
-      drawer: Drawer(
-        child: FutureBuilder<List<Widget>>(
-          future:
-              _getDrawerItems(), // call the async function to get the future
-          builder:
-              (BuildContext context, AsyncSnapshot<List<Widget>> snapshot) {
-            if (snapshot.connectionState == ConnectionState.waiting) {
-              // While data is loading, show a progress indicator
-              return Center(child: CircularProgressIndicator());
-            } else if (snapshot.hasError) {
-              // If something went wrong, show an error message
-              return Center(child: Text('Error: ${snapshot.error}'));
-            } else {
-              // When data is fetched successfully, display the items
-              return ListView(
-                padding: EdgeInsets.zero,
-                children:
-                    snapshot.data!, // Unwrap the data once confirmed it's there
-              );
-            }
-          },
-        ),
-      ),
-      body: EmailListScreen(
-        emails: emails,
-      ),
-    );
-  }
-}
-
-class EmailListScreen extends StatelessWidget {
-  List emails;
-  EmailListScreen({required this.emails});
-
-  @override
-  Widget build(BuildContext context) {
-    print(emails);
-    return Scaffold(
-      appBar: AppBar(
-        title: Text('Emails'),
-      ),
-      body: ListView.separated(
-        itemCount: emails.length,
-        itemBuilder: (context, index) {
-          return ListTile(
-              title: Text(emails[index].from,
-                  style: TextStyle(fontWeight: FontWeight.bold)),
-              subtitle: Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Text(emails[index].subject),
-                ],
-              ),
-              trailing: Text(emails[index].date.toString()),
-              onTap: () {
-                Navigator.push(
-                  context,
-                  MaterialPageRoute(
-                      builder: (context) => EmailView(emailContent: "")),
-                );
-              });
-        },
-        separatorBuilder: (context, index) {
-          return Divider();
-        },
-      ),
-    );
-  }
-}
-
-class EmailView extends StatelessWidget {
-  final String emailContent;
-
-  EmailView({required this.emailContent});
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-      appBar: AppBar(
-        title: Text("HTML Content"),
-      ),
-      body: Text(
-        """
-        <h1>Heading</h1>
-        <p>This is a <strong>simple</strong> HTML example.</p>
-        """,
-      ),
-    );
-  }
-}
+// import 'package:flutter/material.dart';
+// import 'package:http/http.dart' as http;
+// import 'dart:convert';
+// import 'dart:ui_web' as ui;
+// import 'dart:html' as html;
+
+// // import 'package:flutter_html/flutter_html.dart';
+
+// class SerializableMessage {
+//   final String name;
+//   final String from;
+//   final String path;
+//   final String subject;
+//   final String date;
+
+//   SerializableMessage(
+//       {required this.name,
+//       required this.from,
+//       required this.path,
+//       required this.subject,
+//       required this.date});
+
+//   factory SerializableMessage.fromJson(Map<String, dynamic> json) {
+//     return SerializableMessage(
+//         name: json['name'],
+//         from: json['from'],
+//         path: json['path'],
+//         subject: json['subject'],
+//         date: json['date']);
+//   }
+// }
+
+// class EmailPage extends StatefulWidget {
+//   const EmailPage({super.key});
+//   final String title = 'cars';
+
+//   @override
+//   State<EmailPage> createState() => _EmailPageState();
+// }
+
+// class _EmailPageState extends State<EmailPage> {
+//   List emails = [];
+//   //  @override
+//   // void initState() {
+//   //   super.initState();
+//   // }
+//   //register the html element
+//   ui.platformViewRegistry.registerViewFactory(
+//     'html-view',
+//     (int viewId) => html.IFrameElement()
+//       ..width = '100%'
+//       ..height = '100%'
+//       ..srcdoc = r"""
+// """
+//       ..style.border = 'none',
+//   );
+ 
+//   void _displayEmailsFromFolder(String folder) async {
+//     Map<String, List<SerializableMessage>> messagesMap = {};
+
+//     try {
+//       var url = Uri.http(
+//           '127.0.0.1:3001', 'sorted_threads_by_date', {'folder': folder});
+//       var response = await http.get(url);
+
+//       Map<String, dynamic> json = jsonDecode(response.body);
+
+//       json.forEach((key, value) {
+//         List<SerializableMessage> messages = (value as List)
+//             .map((item) => SerializableMessage.fromJson(item))
+//             .toList();
+//         messagesMap[key] = messages;
+//       });
+//     } catch (e) {
+//       print('_displayEmailsFromFolder caught error: $e');
+//     }
+//     setState(() {
+//       emails.clear();
+//       emails = messagesMap.values.toList().expand((list) => list).toList();
+//       ;
+//     });
+//   }
+
+//   Future<List<Widget>> _getDrawerItems() async {
+//     List<String> drawerItems = [];
+
+//     try {
+//       var url = Uri.http('127.0.0.1:3001', 'folders');
+//       var response = await http.get(url);
+//       drawerItems = List<String>.from(json.decode(response.body));
+//     } catch (e) {
+//       print('_getDrawerItems caught error: $e');
+//     }
+
+//     List<Widget> drawerWidgets = [];
+
+//     for (String item in drawerItems) {
+//       drawerWidgets.add(
+//         ListTile(
+//           leading: Icon(Icons.mail),
+//           title: Text(item),
+//           onTap: () {
+//             _displayEmailsFromFolder(item);
+//             Navigator.pop(context);
+//           },
+//         ),
+//       );
+//     }
+
+//     return drawerWidgets;
+//   }
+
+//   @override
+//   Widget build(BuildContext context) {
+//     return Scaffold(
+//       appBar: AppBar(
+//         backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+//         title: Text(widget.title),
+//       ),
+//       drawer: Drawer(
+//         child: FutureBuilder<List<Widget>>(
+//           future:
+//               _getDrawerItems(), // call the async function to get the future
+//           builder:
+//               (BuildContext context, AsyncSnapshot<List<Widget>> snapshot) {
+//             if (snapshot.connectionState == ConnectionState.waiting) {
+//               // While data is loading, show a progress indicator
+//               return Center(child: CircularProgressIndicator());
+//             } else if (snapshot.hasError) {
+//               // If something went wrong, show an error message
+//               return Center(child: Text('Error: ${snapshot.error}'));
+//             } else {
+//               // When data is fetched successfully, display the items
+//               return ListView(
+//                 padding: EdgeInsets.zero,
+//                 children:
+//                     snapshot.data!, // Unwrap the data once confirmed it's there
+//               );
+//             }
+//           },
+//         ),
+//       ),
+//       body: EmailListScreen(
+//         emails: emails,
+//       ),
+//     );
+//   }
+// }
+
+// class EmailListScreen extends StatelessWidget {
+//   List emails;
+//   EmailListScreen({required this.emails});
+
+//   @override
+//   Widget build(BuildContext context) {
+//     print(emails);
+//     return Scaffold(
+//       appBar: AppBar(
+//         title: Text('Emails'),
+//       ),
+//       body: ListView.separated(
+//         itemCount: emails.length,
+//         itemBuilder: (context, index) {
+//           return ListTile(
+//               title: Text(emails[index].from,
+//                   style: TextStyle(fontWeight: FontWeight.bold)),
+//               subtitle: Column(
+//                 crossAxisAlignment: CrossAxisAlignment.start,
+//                 children: [
+//                   Text(emails[index].subject),
+//                 ],
+//               ),
+//               trailing: Text(emails[index].date.toString()),
+//               onTap: () {
+//                 Navigator.push(
+//                   context,
+//                   MaterialPageRoute(
+//                       builder: (context) => EmailView(emailContent: "")),
+//                 );
+//               });
+//         },
+//         separatorBuilder: (context, index) {
+//           return Divider();
+//         },
+//       ),
+//     );
+//   }
+// }
+
+// class HtmlContentWidget extends StatelessWidget {
+//   @override
+//   Widget build(BuildContext context) {
+//     return Container(
+//       width: 800,
+//       height: 10000,
+//       child: HtmlElementView(viewType: 'html-view'),
+//     );
+//   }
+// }
+
+// class EmailView extends StatelessWidget {
+//   final String emailContent;
+
+//   EmailView({required this.emailContent});
+
+//   @override
+//   Widget build(BuildContext context) {
+//     return Scaffold(
+//         appBar: AppBar(
+//           title: Text("HTML Content"),
+//         ),
+//         body: Container(
+//           width: 800,
+//           height: 10000,
+//           child: HtmlElementView(
+//             viewType: 'html-view',
+//           ),
+//         )
+
+//         // Text(
+//         //   """
+//         //   <h1>Heading</h1>
+//         //   <p>This is a <strong>simple</strong> HTML example.</p>
+//         //   """,
+//         // ),
+//         );
+//   }r
+// }

+ 1 - 0
linux/.gitignore

@@ -0,0 +1 @@
+flutter/ephemeral

+ 3 - 0
linux/.gitignore:Zone.Identifier

@@ -0,0 +1,3 @@
+[ZoneTransfer]
+ZoneId=3
+ReferrerUrl=C:\Users\juana\Flutter\flutter_windows_3.22.2-stable.zip

+ 4 - 0
linux/flutter/generated_plugin_registrant.cc

@@ -6,6 +6,10 @@
 
 #include "generated_plugin_registrant.h"
 
+#include <url_launcher_linux/url_launcher_plugin.h>
 
 void fl_register_plugins(FlPluginRegistry* registry) {
+  g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
+      fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
+  url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
 }

+ 1 - 0
linux/flutter/generated_plugins.cmake

@@ -3,6 +3,7 @@
 #
 
 list(APPEND FLUTTER_PLUGIN_LIST
+  url_launcher_linux
 )
 
 list(APPEND FLUTTER_FFI_PLUGIN_LIST

+ 7 - 0
macos/.gitignore

@@ -0,0 +1,7 @@
+# Flutter-related
+**/Flutter/ephemeral/
+**/Pods/
+
+# Xcode-related
+**/dgph
+**/xcuserdata/

+ 3 - 0
macos/.gitignore:Zone.Identifier

@@ -0,0 +1,3 @@
+[ZoneTransfer]
+ZoneId=3
+ReferrerUrl=C:\Users\juana\Flutter\flutter_windows_3.22.2-stable.zip

+ 10 - 0
macos/Flutter/GeneratedPluginRegistrant.swift

@@ -5,10 +5,20 @@
 import FlutterMacOS
 import Foundation
 
+import audio_session
+import just_audio
+import path_provider_foundation
+import sqflite
+import url_launcher_macos
 import video_player_avfoundation
 import wakelock_macos
 
 func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
+  AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
+  JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
+  PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
+  SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
+  UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
   FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
   WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin"))
 }

+ 338 - 2
pubspec.lock

@@ -17,6 +17,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.11.0"
+  audio_session:
+    dependency: transitive
+    description:
+      name: audio_session
+      sha256: "343e83bc7809fbda2591a49e525d6b63213ade10c76f15813be9aed6657b3261"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.1.21"
   boolean_selector:
     dependency: transitive
     description:
@@ -25,6 +33,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.1"
+  cached_network_image:
+    dependency: transitive
+    description:
+      name: cached_network_image
+      sha256: "4a5d8d2c728b0f3d0245f69f921d7be90cae4c2fd5288f773088672c0893f819"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.4.0"
+  cached_network_image_platform_interface:
+    dependency: transitive
+    description:
+      name: cached_network_image_platform_interface
+      sha256: ff0c949e323d2a1b52be73acce5b4a7b04063e61414c8ca542dbba47281630a7
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.1.0"
+  cached_network_image_web:
+    dependency: transitive
+    description:
+      name: cached_network_image_web
+      sha256: "6322dde7a5ad92202e64df659241104a43db20ed594c41ca18de1014598d7996"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.3.0"
   characters:
     dependency: transitive
     description:
@@ -65,6 +97,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.18.0"
+  crypto:
+    dependency: transitive
+    description:
+      name: crypto
+      sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.3"
   csslib:
     dependency: transitive
     description:
@@ -105,11 +145,35 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.2"
+  file:
+    dependency: transitive
+    description:
+      name: file
+      sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "7.0.0"
+  fixnum:
+    dependency: transitive
+    description:
+      name: fixnum
+      sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.0"
   flutter:
     dependency: "direct main"
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_cache_manager:
+    dependency: transitive
+    description:
+      name: flutter_cache_manager
+      sha256: a77f77806a790eb9ba0118a5a3a936e81c4fea2b61533033b2b0c3d50bbde5ea
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.4.0"
   flutter_html:
     dependency: transitive
     description:
@@ -216,6 +280,70 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_widget_from_html:
+    dependency: "direct main"
+    description:
+      name: flutter_widget_from_html
+      sha256: "8d2a9a7979a9c1a5d866d1f4134d2ec2cca78716c112c76803d6a552281405cc"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.10.6"
+  flutter_widget_from_html_core:
+    dependency: transitive
+    description:
+      name: flutter_widget_from_html_core
+      sha256: "22140caa191cb4bba0fe4d5e4ad875c7e8a9ba47d61517f56d733019cf76396d"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.10.6"
+  fwfh_cached_network_image:
+    dependency: transitive
+    description:
+      name: fwfh_cached_network_image
+      sha256: "3de22aa3a6943c968e0d9fbcba4463b3dbbf7103171d62c84b6c672fb83eebdf"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.7.0+7"
+  fwfh_chewie:
+    dependency: transitive
+    description:
+      name: fwfh_chewie
+      sha256: "0b51a1c976bb74da5e8e45d545c74cb54a7168ad3938dd77103a7aee485f55fa"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.7.1+4"
+  fwfh_just_audio:
+    dependency: transitive
+    description:
+      name: fwfh_just_audio
+      sha256: "237b93a4cb9f0495a4b51940f361adda2a5abd57231dd44f07459db00144a6cd"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.0+3"
+  fwfh_svg:
+    dependency: transitive
+    description:
+      name: fwfh_svg
+      sha256: c6bb6b513f7ce2766aba76d7276caf9a96b6fee729ac3a492c366a42f82ef02e
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.8.2"
+  fwfh_url_launcher:
+    dependency: transitive
+    description:
+      name: fwfh_url_launcher
+      sha256: b9f5d55a5ae2c2c07243ba33f7ba49ac9544bdb2f4c16d8139df9ccbebe3449c
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.1"
+  fwfh_webview:
+    dependency: transitive
+    description:
+      name: fwfh_webview
+      sha256: "90a8dda0695403cf57abd7e8b83f6fb1f1a12933930a0bf9cac7cafb06e06a18"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.0+2"
   html:
     dependency: transitive
     description:
@@ -248,6 +376,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.6.7"
+  just_audio:
+    dependency: transitive
+    description:
+      name: just_audio
+      sha256: b7cb6bbf3750caa924d03f432ba401ec300fd90936b3f73a9b33d58b1e96286b
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.37"
+  just_audio_platform_interface:
+    dependency: transitive
+    description:
+      name: just_audio_platform_interface
+      sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790"
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.3.0"
+  just_audio_web:
+    dependency: transitive
+    description:
+      name: just_audio_web
+      sha256: "134356b0fe3d898293102b33b5fd618831ffdc72bb7a1b726140abdf22772b70"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.4.9"
   leak_tracker:
     dependency: transitive
     description:
@@ -320,6 +472,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.0"
+  octo_image:
+    dependency: transitive
+    description:
+      name: octo_image
+      sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.0"
   path:
     dependency: transitive
     description:
@@ -336,6 +496,54 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  path_provider:
+    dependency: transitive
+    description:
+      name: path_provider
+      sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.4"
+  path_provider_android:
+    dependency: transitive
+    description:
+      name: path_provider_android
+      sha256: "490539678396d4c3c0b06efdaab75ae60675c3e0c66f72bc04c2e2c1e0e2abeb"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.9"
+  path_provider_foundation:
+    dependency: transitive
+    description:
+      name: path_provider_foundation
+      sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.0"
+  path_provider_linux:
+    dependency: transitive
+    description:
+      name: path_provider_linux
+      sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.1"
+  path_provider_platform_interface:
+    dependency: transitive
+    description:
+      name: path_provider_platform_interface
+      sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.2"
+  path_provider_windows:
+    dependency: transitive
+    description:
+      name: path_provider_windows
+      sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.0"
   petitparser:
     dependency: transitive
     description:
@@ -344,6 +552,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "6.0.2"
+  platform:
+    dependency: transitive
+    description:
+      name: platform
+      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.5"
   plugin_platform_interface:
     dependency: transitive
     description:
@@ -368,6 +584,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.2.1"
+  rxdart:
+    dependency: transitive
+    description:
+      name: rxdart
+      sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.27.7"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -381,6 +605,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.10.0"
+  sprintf:
+    dependency: transitive
+    description:
+      name: sprintf
+      sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
+      url: "https://pub.dev"
+    source: hosted
+    version: "7.0.0"
+  sqflite:
+    dependency: transitive
+    description:
+      name: sqflite
+      sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.3+1"
+  sqflite_common:
+    dependency: transitive
+    description:
+      name: sqflite_common
+      sha256: "3da423ce7baf868be70e2c0976c28a1bb2f73644268b7ffa7d2e08eab71f16a4"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.5.4"
   stack_trace:
     dependency: transitive
     description:
@@ -405,6 +653,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.2.0"
+  synchronized:
+    dependency: transitive
+    description:
+      name: synchronized
+      sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.0+1"
   term_glyph:
     dependency: transitive
     description:
@@ -437,6 +693,78 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.2"
+  url_launcher:
+    dependency: transitive
+    description:
+      name: url_launcher
+      sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.3.0"
+  url_launcher_android:
+    dependency: transitive
+    description:
+      name: url_launcher_android
+      sha256: "94d8ad05f44c6d4e2ffe5567ab4d741b82d62e3c8e288cc1fcea45965edf47c9"
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.3.8"
+  url_launcher_ios:
+    dependency: transitive
+    description:
+      name: url_launcher_ios
+      sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.3.1"
+  url_launcher_linux:
+    dependency: transitive
+    description:
+      name: url_launcher_linux
+      sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.1"
+  url_launcher_macos:
+    dependency: transitive
+    description:
+      name: url_launcher_macos
+      sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.2.0"
+  url_launcher_platform_interface:
+    dependency: transitive
+    description:
+      name: url_launcher_platform_interface
+      sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.2"
+  url_launcher_web:
+    dependency: transitive
+    description:
+      name: url_launcher_web
+      sha256: a36e2d7981122fa185006b216eb6b5b97ede3f9a54b7a511bc966971ab98d049
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.2"
+  url_launcher_windows:
+    dependency: transitive
+    description:
+      name: url_launcher_windows
+      sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.2"
+  uuid:
+    dependency: transitive
+    description:
+      name: uuid
+      sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90"
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.4.2"
   vector_graphics:
     dependency: transitive
     description:
@@ -577,10 +905,10 @@ packages:
     dependency: transitive
     description:
       name: webview_flutter_android
-      sha256: "060e1a621add859dc822f3e4c59b01468e8515ea78cfc5ac4c6b28bc903b5f74"
+      sha256: c66651fba15f9d7ddd31daec42da8d6bce46c85610a7127e3ebcb39a4395c3c9
       url: "https://pub.dev"
     source: hosted
-    version: "3.16.5"
+    version: "3.16.6"
   webview_flutter_platform_interface:
     dependency: transitive
     description:
@@ -605,6 +933,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.1.4"
+  xdg_directories:
+    dependency: transitive
+    description:
+      name: xdg_directories
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.4"
   xml:
     dependency: transitive
     description:

+ 2 - 0
pubspec.yaml

@@ -13,6 +13,8 @@ dependencies:
     sdk: flutter
   http: 1.2.2
   flutter_html_all: 3.0.0-beta.2
+  flutter_widget_from_html: ^0.10.0
+  
 
   english_words: ^4.0.0
   provider: ^6.0.0

+ 3 - 0
windows/flutter/generated_plugin_registrant.cc

@@ -6,6 +6,9 @@
 
 #include "generated_plugin_registrant.h"
 
+#include <url_launcher_windows/url_launcher_windows.h>
 
 void RegisterPlugins(flutter::PluginRegistry* registry) {
+  UrlLauncherWindowsRegisterWithRegistrar(
+      registry->GetRegistrarForPlugin("UrlLauncherWindows"));
 }

+ 1 - 0
windows/flutter/generated_plugins.cmake

@@ -3,6 +3,7 @@
 #
 
 list(APPEND FLUTTER_PLUGIN_LIST
+  url_launcher_windows
 )
 
 list(APPEND FLUTTER_FFI_PLUGIN_LIST