diff --git a/lib/main.dart b/lib/main.dart index bc09db8..d28263f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ // ignore_for_file: depend_on_referenced_packages import 'dart:io'; +import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -22,7 +23,10 @@ import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as path; late Isar isar; -void main() async { +void main(List args) async { + if (runWebViewTitleBarWidget(args)) { + return; + } WidgetsFlutterBinding.ensureInitialized(); await _initDB(); runApp(const ProviderScope(child: MyApp())); diff --git a/lib/modules/manga/detail/manga_details_view.dart b/lib/modules/manga/detail/manga_details_view.dart index 0dddd90..b83c053 100644 --- a/lib/modules/manga/detail/manga_details_view.dart +++ b/lib/modules/manga/detail/manga_details_view.dart @@ -152,7 +152,7 @@ class _MangaDetailsViewState extends ConsumerState { ), ) : SizedBox( - width: mediaWidth(context, 0.4), + width: isTablet(context) ? null : mediaWidth(context, 0.4), child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: diff --git a/lib/modules/manga/home/manga_home_screen.dart b/lib/modules/manga/home/manga_home_screen.dart index c1bf95f..977c8b6 100644 --- a/lib/modules/manga/home/manga_home_screen.dart +++ b/lib/modules/manga/home/manga_home_screen.dart @@ -106,6 +106,7 @@ class _MangaHomeScreenState extends ConsumerState { Map data = { 'url': getMangaBaseUrl(widget.mangaType.source!), 'source': widget.mangaType.source!, + 'title': '' }; context.push("/mangawebview", extra: data); }, diff --git a/lib/modules/webview/webview.dart b/lib/modules/webview/webview.dart index 39474b6..1dc0e2f 100644 --- a/lib/modules/webview/webview.dart +++ b/lib/modules/webview/webview.dart @@ -1,11 +1,20 @@ +// ignore_for_file: depend_on_referenced_packages + +import 'dart:convert'; +import 'dart:io'; + +import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/settings.dart'; import 'package:mangayomi/services/http_service/cloudflare/cookie.dart'; +import 'package:mangayomi/utils/constant.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:share_plus/share_plus.dart'; +import 'package:path/path.dart' as p; +import 'package:path_provider/path_provider.dart'; class MangaWebView extends ConsumerStatefulWidget { final String url; @@ -26,166 +35,233 @@ class _MangaWebViewState extends ConsumerState { final GlobalKey webViewKey = GlobalKey(); double progress = 0; + @override + void initState() { + if (Platform.isWindows || Platform.isLinux) { + _runWebViewDesktop(); + } else { + setState(() { + isNotDesktop = true; + }); + } + super.initState(); + } + Webview? webview; + _runWebViewDesktop() async { + webview = await WebviewWindow.create( + configuration: CreateConfiguration( + userDataFolderWindows: await getWebViewPath(), + ), + ); + webview! + ..setBrightness(Brightness.dark) + ..setApplicationNameForUserAgent(defaultUserAgent) + ..launch(widget.url) + ..onClose.whenComplete(() { + Navigator.pop(context); + }); + } + + bool isNotDesktop = false; InAppWebViewController? _webViewController; late String _url = widget.url; late String _title = widget.title; bool _canGoback = false; bool _canGoForward = false; + @override Widget build(BuildContext context) { - return SafeArea( - child: WillPopScope( - onWillPop: () async { - _webViewController?.goBack(); - return false; - }, - child: Column( - children: [ - SizedBox( - height: AppBar().preferredSize.height, - child: Row( + return !isNotDesktop + ? Scaffold( + appBar: AppBar( + title: Text( + _title, + style: const TextStyle( + overflow: TextOverflow.ellipsis, + fontWeight: FontWeight.bold), + ), + leading: IconButton( + onPressed: () { + webview!.close(); + Navigator.pop(context); + }, + icon: const Icon(Icons.close)), + ), + ) + : SafeArea( + child: WillPopScope( + onWillPop: () async { + _webViewController?.goBack(); + return false; + }, + child: Column( children: [ - Expanded( - child: ListTile( - dense: true, - subtitle: Text( - _url, - style: const TextStyle( - fontSize: 10, overflow: TextOverflow.ellipsis), - ), - title: Text( - _title, - style: const TextStyle( - overflow: TextOverflow.ellipsis, - fontWeight: FontWeight.bold), - ), - leading: IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: const Icon(Icons.close)), + SizedBox( + height: AppBar().preferredSize.height, + child: Row( + children: [ + Expanded( + child: ListTile( + dense: true, + subtitle: Text( + _url, + style: const TextStyle( + fontSize: 10, + overflow: TextOverflow.ellipsis), + ), + title: Text( + _title, + style: const TextStyle( + overflow: TextOverflow.ellipsis, + fontWeight: FontWeight.bold), + ), + leading: IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: const Icon(Icons.close)), + ), + ), + IconButton( + icon: Icon(Icons.arrow_back, + color: _canGoback ? null : Colors.grey), + onPressed: _canGoback + ? () { + _webViewController?.goBack(); + } + : null, + ), + IconButton( + icon: Icon(Icons.arrow_forward, + color: _canGoForward ? null : Colors.grey), + onPressed: _canGoForward + ? () { + _webViewController?.goForward(); + } + : null, + ), + PopupMenuButton(itemBuilder: (context) { + return [ + const PopupMenuItem( + value: 0, child: Text("Refresh")), + const PopupMenuItem( + value: 1, child: Text("Share")), + const PopupMenuItem( + value: 2, child: Text("Open in browser")), + const PopupMenuItem( + value: 3, child: Text("Clear cookie")), + ]; + }, onSelected: (value) async { + if (value == 0) { + _webViewController?.reload(); + } else if (value == 1) { + Share.share(_url); + } else if (value == 2) { + await InAppBrowser.openWithSystemBrowser( + url: WebUri.uri(Uri.parse(_url))); + } else if (value == 3) { + CookieManager.instance().getAllCookies(); + } + }), + ], ), ), - IconButton( - icon: Icon(Icons.arrow_back, - color: _canGoback ? null : Colors.grey), - onPressed: _canGoback - ? () { - _webViewController?.goBack(); + progress < 1.0 + ? LinearProgressIndicator(value: progress) + : Container(), + Expanded( + child: InAppWebView( + key: webViewKey, + onWebViewCreated: (controller) async { + _webViewController = controller; + }, + onLoadStart: (controller, url) async { + setState(() { + _url = url.toString(); + }); + }, + onPermissionRequest: (controller, request) async { + return PermissionResponse( + resources: request.resources, + action: PermissionResponseAction.GRANT); + }, + shouldOverrideUrlLoading: + (controller, navigationAction) async { + var uri = navigationAction.request.url!; + + if (![ + "http", + "https", + "file", + "chrome", + "data", + "javascript", + "about" + ].contains(uri.scheme)) { + if (await canLaunchUrl(uri)) { + // Launch the App + await launchUrl( + uri, + ); + // and cancel the request + return NavigationActionPolicy.CANCEL; } - : null, + } + + return NavigationActionPolicy.ALLOW; + }, + onLoadStop: (controller, url) async { + setState(() { + _url = url.toString(); + }); + }, + onReceivedError: (controller, request, error) {}, + onProgressChanged: (controller, progress) async { + setState(() { + this.progress = progress / 100; + }); + }, + onUpdateVisitedHistory: + (controller, url, isReload) async { + await ref.watch( + setCookieProvider(widget.source, url.toString()) + .future); + final canGoback = await controller.canGoBack(); + final canGoForward = await controller.canGoForward(); + final title = await controller.getTitle(); + setState(() { + _url = url.toString(); + _title = title!; + _canGoback = canGoback; + _canGoForward = canGoForward; + }); + }, + initialSettings: InAppWebViewSettings( + userAgent: isar.settings.getSync(227)!.userAgent!), + initialUrlRequest: + URLRequest(url: WebUri.uri(Uri.parse(widget.url))), + ), ), - IconButton( - icon: Icon(Icons.arrow_forward, - color: _canGoForward ? null : Colors.grey), - onPressed: _canGoForward - ? () { - _webViewController?.goForward(); - } - : null, - ), - PopupMenuButton(itemBuilder: (context) { - return [ - const PopupMenuItem( - value: 0, child: Text("Refresh")), - const PopupMenuItem(value: 1, child: Text("Share")), - const PopupMenuItem( - value: 2, child: Text("Open in browser")), - const PopupMenuItem( - value: 3, child: Text("Clear cookie")), - ]; - }, onSelected: (value) async { - if (value == 0) { - _webViewController?.reload(); - } else if (value == 1) { - Share.share(_url); - } else if (value == 2) { - await InAppBrowser.openWithSystemBrowser( - url: WebUri.uri(Uri.parse(_url))); - } else if (value == 3) { - CookieManager.instance().getAllCookies(); - } - }), ], ), ), - progress < 1.0 - ? LinearProgressIndicator(value: progress) - : Container(), - Expanded( - child: InAppWebView( - key: webViewKey, - onWebViewCreated: (controller) async { - _webViewController = controller; - }, - onLoadStart: (controller, url) async { - setState(() { - _url = url.toString(); - }); - }, - onPermissionRequest: (controller, request) async { - return PermissionResponse( - resources: request.resources, - action: PermissionResponseAction.GRANT); - }, - shouldOverrideUrlLoading: (controller, navigationAction) async { - var uri = navigationAction.request.url!; - - if (![ - "http", - "https", - "file", - "chrome", - "data", - "javascript", - "about" - ].contains(uri.scheme)) { - if (await canLaunchUrl(uri)) { - // Launch the App - await launchUrl( - uri, - ); - // and cancel the request - return NavigationActionPolicy.CANCEL; - } - } - - return NavigationActionPolicy.ALLOW; - }, - onLoadStop: (controller, url) async { - setState(() { - _url = url.toString(); - }); - }, - onReceivedError: (controller, request, error) {}, - onProgressChanged: (controller, progress) async { - setState(() { - this.progress = progress / 100; - }); - }, - onUpdateVisitedHistory: (controller, url, isReload) async { - await ref.watch( - setCookieProvider(widget.source, url.toString()).future); - final canGoback = await controller.canGoBack(); - final canGoForward = await controller.canGoForward(); - final title = await controller.getTitle(); - setState(() { - _url = url.toString(); - _title = title!; - _canGoback = canGoback; - _canGoForward = canGoForward; - }); - }, - initialSettings: InAppWebViewSettings( - userAgent: isar.settings.getSync(227)!.userAgent!), - initialUrlRequest: - URLRequest(url: WebUri.uri(Uri.parse(widget.url))), - ), - ), - ], - ), - ), - ); + ); } } + +Future getWebViewPath() async { + final document = await getApplicationDocumentsDirectory(); + return p.join( + document.path, + 'desktop_webview_window', + ); +} + +decodeHtml(Webview webview) async { + final html = await webview + .evaluateJavaScript("window.document.documentElement.outerHTML;"); + // final cookie = await webview.evaluateJavaScript("window.document.cookie;"); + // log(cookie!); + return jsonDecode(html!) as String; +} diff --git a/lib/services/http_service/cloudflare/cloudflare_bypass.dart b/lib/services/http_service/cloudflare/cloudflare_bypass.dart index 1fdf146..3ca3578 100644 --- a/lib/services/http_service/cloudflare/cloudflare_bypass.dart +++ b/lib/services/http_service/cloudflare/cloudflare_bypass.dart @@ -1,8 +1,14 @@ +import 'dart:developer'; +import 'dart:io'; + +import 'package:desktop_webview_window/desktop_webview_window.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:html/dom.dart' as dom; import 'package:html/dom.dart'; import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/settings.dart'; +import 'package:mangayomi/modules/webview/webview.dart'; import 'package:mangayomi/services/http_service/cloudflare/cookie.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'cloudflare_bypass.g.dart'; @@ -12,49 +18,88 @@ Future cloudflareBypassDom(CloudflareBypassDomRef ref, {required String url, required String source, required bool useUserAgent}) async { - // log(source); + final ua = isar.settings.getSync(227)!.userAgent!; bool isOk = false; dom.Document? htmll; - final ua = isar.settings.getSync(227)!.userAgent!; - HeadlessInAppWebView? headlessWebViewJapScan; - headlessWebViewJapScan = HeadlessInAppWebView( - onLoadStop: (controller, u) async { - String? html; - html = await controller.evaluateJavascript( - source: "window.document.getElementsByTagName('html')[0].outerHTML;"); - await Future.doWhile(() async { - if (html == null || - html!.contains("Just a moment") || - html!.contains("https://challenges.cloudflare.com")) { - html = await controller.evaluateJavascript( - source: - "window.document.getElementsByTagName('html')[0].outerHTML;"); - return true; - } + if (Platform.isWindows || Platform.isLinux) { + String? html; + final webview = await WebviewWindow.create( + configuration: CreateConfiguration( + windowHeight: 500, + windowWidth: 500, + userDataFolderWindows: await getWebViewPath(), + ), + ); + webview + ..setBrightness(Brightness.dark) + ..setApplicationNameForUserAgent(useUserAgent ? ua : '') + ..launch(url); + + await Future.delayed(const Duration(seconds: 10)); + html = await decodeHtml(webview); + isOk = true; + await Future.doWhile(() async { + await Future.delayed(const Duration(seconds: 1)); + if (isOk == true) { return false; - }); - html = await controller.evaluateJavascript( - source: "window.document.getElementsByTagName('html')[0].outerHTML;"); - htmll = dom.Document.html(html!); - isOk = true; - headlessWebViewJapScan!.dispose(); - }, - initialSettings: useUserAgent ? InAppWebViewSettings(userAgent: ua) : null, - initialUrlRequest: URLRequest( - url: WebUri.uri(Uri.parse(url)), - ), - ); + } + return true; + }); + html = await decodeHtml(webview); + htmll = dom.Document.html(html!); + isOk = true; + webview.close(); + await Future.doWhile(() async { + await Future.delayed(const Duration(seconds: 1)); + if (isOk == true) { + return false; + } + return true; + }); + } else { + HeadlessInAppWebView? headlessWebViewJapScan; + headlessWebViewJapScan = HeadlessInAppWebView( + onLoadStop: (controller, u) async { + String? html; + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + await Future.doWhile(() async { + if (html == null || + html!.contains("Just a moment") || + html!.contains("https://challenges.cloudflare.com")) { + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + return true; + } + return false; + }); + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + htmll = dom.Document.html(html!); + isOk = true; + headlessWebViewJapScan!.dispose(); + }, + initialSettings: + useUserAgent ? InAppWebViewSettings(userAgent: ua) : null, + initialUrlRequest: URLRequest( + url: WebUri.uri(Uri.parse(url)), + ), + ); - headlessWebViewJapScan.run(); + headlessWebViewJapScan.run(); - await Future.doWhile(() async { - await Future.delayed(const Duration(seconds: 1)); - if (isOk == true) { - return false; - } - return true; - }); - await ref.watch(setCookieProvider(source, url).future); + await Future.doWhile(() async { + await Future.delayed(const Duration(seconds: 1)); + if (isOk == true) { + return false; + } + return true; + }); + await ref.watch(setCookieProvider(source, url).future); + } return htmll; } @@ -66,42 +111,71 @@ Future cloudflareBypassHtml(CloudflareBypassHtmlRef ref, final ua = isar.settings.getSync(227)!.userAgent!; bool isOk = false; String? html; - HeadlessInAppWebView? headlessWebViewJapScan; - headlessWebViewJapScan = HeadlessInAppWebView( - onLoadStop: (controller, u) async { - html = await controller.evaluateJavascript( - source: "window.document.getElementsByTagName('html')[0].outerHTML;"); - await Future.doWhile(() async { - if (html == null || - html!.contains("Just a moment") || - html!.contains("Un instant…")) { - html = await controller.evaluateJavascript( - source: - "window.document.getElementsByTagName('html')[0].outerHTML;"); - return true; - } - return false; - }); - await Future.delayed(Duration(seconds: 10)); - html = await controller.evaluateJavascript( - source: "window.document.getElementsByTagName('html')[0].outerHTML;"); - isOk = true; - headlessWebViewJapScan!.dispose(); - }, - initialSettings: useUserAgent ? InAppWebViewSettings(userAgent: ua) : null, - initialUrlRequest: URLRequest( - url: WebUri.uri(Uri.parse(url)), - ), - ); + if (Platform.isWindows || Platform.isLinux) { + final webview = await WebviewWindow.create( + configuration: CreateConfiguration( + windowHeight: 500, + windowWidth: 500, + userDataFolderWindows: await getWebViewPath(), + ), + ); + webview + ..setBrightness(Brightness.dark) + ..setApplicationNameForUserAgent(useUserAgent ? ua : '') + ..launch(url); - headlessWebViewJapScan.run(); - await Future.doWhile(() async { - await Future.delayed(const Duration(seconds: 1)); - if (isOk == true) { + await Future.doWhile(() async { + await Future.delayed(const Duration(seconds: 5)); + if (html == null) { + html = await decodeHtml(webview); + return true; + } return false; - } - return true; - }); - await ref.watch(setCookieProvider(source, url).future); + }); + + isOk = true; + webview.close(); + } else { + HeadlessInAppWebView? headlessWebViewJapScan; + headlessWebViewJapScan = HeadlessInAppWebView( + onLoadStop: (controller, u) async { + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + await Future.doWhile(() async { + if (html == null || + html!.contains("Just a moment") || + html!.contains("Un instant…")) { + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + return true; + } + return false; + }); + await Future.delayed(Duration(seconds: 10)); + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + isOk = true; + headlessWebViewJapScan!.dispose(); + }, + initialSettings: + useUserAgent ? InAppWebViewSettings(userAgent: ua) : null, + initialUrlRequest: URLRequest( + url: WebUri.uri(Uri.parse(url)), + ), + ); + + headlessWebViewJapScan.run(); + await Future.doWhile(() async { + await Future.delayed(const Duration(seconds: 1)); + if (isOk == true) { + return false; + } + return true; + }); + await ref.watch(setCookieProvider(source, url).future); + } return html!; } diff --git a/lib/sources/multisrc/madara/src/madara.dart b/lib/sources/multisrc/madara/src/madara.dart index 556a1ae..517ed69 100644 --- a/lib/sources/multisrc/madara/src/madara.dart +++ b/lib/sources/multisrc/madara/src/madara.dart @@ -1,13 +1,16 @@ -import 'dart:convert'; import 'dart:developer'; - +import 'dart:io'; +import 'package:desktop_webview_window/desktop_webview_window.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:html/dom.dart'; import 'package:mangayomi/models/chapter.dart'; +import 'package:mangayomi/modules/webview/webview.dart'; import 'package:mangayomi/services/http_service/http_service.dart'; import 'package:mangayomi/sources/service.dart'; import 'package:mangayomi/sources/utils/utils.dart'; +import 'package:mangayomi/utils/constant.dart'; import 'package:mangayomi/utils/reg_exp_matcher.dart'; import 'package:mangayomi/utils/xpath_selector.dart'; @@ -91,47 +94,76 @@ class Madara extends MangaYomiServices { .toList(); bool isOk = false; String? html; - HeadlessInAppWebView? headlessWebViewJapScan; - headlessWebViewJapScan = HeadlessInAppWebView( - onLoadStop: (controller, u) async { - html = await controller.evaluateJavascript( - source: - "window.document.getElementsByTagName('html')[0].outerHTML;"); - await Future.doWhile(() async { + if (Platform.isWindows || Platform.isLinux) { + final webview = await WebviewWindow.create( + configuration: CreateConfiguration( + windowHeight: 500, + windowWidth: 500, + userDataFolderWindows: await getWebViewPath(), + ), + ); + webview + ..setBrightness(Brightness.dark) + ..setApplicationNameForUserAgent(defaultUserAgent) + ..launch(manga.url!); + + await Future.doWhile(() async { + await Future.delayed(const Duration(seconds: 10)); + html = await decodeHtml(webview); + if (xpathSelector(html!) + .query("//*[@id='manga-chapters-holder']/div[2]/div/ul/li/a/@href") + .attrs + .isEmpty) { + html = await decodeHtml(webview); + return true; + } + return false; + }); + html = await decodeHtml(webview); + isOk = true; + await Future.doWhile(() async { + await Future.delayed(const Duration(seconds: 1)); + if (isOk == true) { + return false; + } + return true; + }); + html = await decodeHtml(webview); + webview.close(); + } else { + HeadlessInAppWebView? headlessWebViewJapScan; + headlessWebViewJapScan = HeadlessInAppWebView( + onLoadStop: (controller, u) async { html = await controller.evaluateJavascript( source: "window.document.getElementsByTagName('html')[0].outerHTML;"); - if (xpathSelector(html!) - .query( - "//*[@id='manga-chapters-holder']/div[2]/div/ul/li/a/@href") - .attrs - .isEmpty) { + await Future.doWhile(() async { html = await controller.evaluateJavascript( source: "window.document.getElementsByTagName('html')[0].outerHTML;"); - return true; - } - return false; - }); - html = await controller.evaluateJavascript( - source: - "window.document.getElementsByTagName('html')[0].outerHTML;"); - isOk = true; - headlessWebViewJapScan!.dispose(); - }, - initialUrlRequest: URLRequest( - url: WebUri.uri(Uri.parse(manga.url!)), - ), - ); - - headlessWebViewJapScan.run(); - await Future.doWhile(() async { - await Future.delayed(const Duration(seconds: 1)); - if (isOk == true) { - return false; - } - return true; - }); + if (xpathSelector(html!) + .query( + "//*[@id='manga-chapters-holder']/div[2]/div/ul/li/a/@href") + .attrs + .isEmpty) { + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + return true; + } + return false; + }); + html = await controller.evaluateJavascript( + source: + "window.document.getElementsByTagName('html')[0].outerHTML;"); + isOk = true; + headlessWebViewJapScan!.dispose(); + }, + initialUrlRequest: URLRequest( + url: WebUri.uri(Uri.parse(manga.url!)), + ), + ); + } final xpath = xpathSelector(html!); for (var url in xpath .query("//*[@id='manga-chapters-holder']/div[2]/div/ul/li/a/@href") diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index dd1adf1..aaf9800 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,11 +6,15 @@ #include "generated_plugin_registrant.h" +#include #include #include #include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) desktop_webview_window_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewWindowPlugin"); + desktop_webview_window_plugin_register_with_registrar(desktop_webview_window_registrar); g_autoptr(FlPluginRegistrar) flutter_js_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterJsPlugin"); flutter_js_plugin_register_with_registrar(flutter_js_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index d04efc7..ed0d56e 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + desktop_webview_window flutter_js isar_flutter_libs url_launcher_linux diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 27494ef..9fd621c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,7 @@ import FlutterMacOS import Foundation +import desktop_webview_window import flutter_inappwebview import flutter_js import isar_flutter_libs @@ -15,6 +16,7 @@ import sqflite import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin")) InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) FlutterJsPlugin.register(with: registry.registrar(forPlugin: "FlutterJsPlugin")) IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 9f99cf7..616f67a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -282,6 +282,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + desktop_webview_window: + dependency: "direct main" + description: + name: desktop_webview_window + sha256: da2fc164b46257c7a8b88649d3f2b34b4d98e7b7c403fb9e4183ebe8ff008004 + url: "https://pub.dev" + source: hosted + version: "0.2.0" draggable_menu: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index ce54f68..156b627 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,6 +61,7 @@ dependencies: isar_flutter_libs: 3.1.0+1 share_plus: ^7.0.0 xpath_selector_html_parser: ^3.0.1 + desktop_webview_window: ^0.2.0 # The following adds the Cupertino Icons font to your application. diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 8c59c52..cd8836f 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,7 @@ #include "generated_plugin_registrant.h" +#include #include #include #include @@ -13,6 +14,8 @@ #include void RegisterPlugins(flutter::PluginRegistry* registry) { + DesktopWebviewWindowPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin")); FlutterJsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterJsPlugin")); IsarFlutterLibsPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 594b4ca..790c70b 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + desktop_webview_window flutter_js isar_flutter_libs permission_handler_windows