From e9ac655835d266c9c13af04ddde2fe12c93b6fa2 Mon Sep 17 00:00:00 2001 From: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com> Date: Tue, 22 Jul 2025 16:33:21 +0300 Subject: [PATCH] Polish the webview stuff. --- hmm.json | 5 ++ project.hxp | 25 ++++-- source/funkin/InitState.hx | 5 ++ .../funkin/api/newgrounds/NewgroundsClient.hx | 17 ++--- source/funkin/mobile/util/InAppReviewUtil.hx | 2 +- source/funkin/mobile/util/WebViewUtil.hx | 76 +++++++++++++++++++ source/funkin/modding/PolymodHandler.hx | 31 ++++++-- 7 files changed, 137 insertions(+), 24 deletions(-) create mode 100644 source/funkin/mobile/util/WebViewUtil.hx diff --git a/hmm.json b/hmm.json index e1818dc9f..840f14846 100644 --- a/hmm.json +++ b/hmm.json @@ -41,6 +41,11 @@ "type": "haxelib", "version": "1.0.3" }, + { + "name": "extension-webviewcore", + "type": "haxelib", + "version": "1.0.0" + }, { "name": "flixel", "type": "git", diff --git a/project.hxp b/project.hxp index 356307daa..30260b92b 100644 --- a/project.hxp +++ b/project.hxp @@ -385,6 +385,12 @@ class Project extends HXProject */ static final FEATURE_MOBILE_IAR:FeatureFlag = "FEATURE_MOBILE_IAR"; + /** + * `-DFEATURE_MOBILE_WEBVIEW` + * If this feature flag is enabled, the user may sometimes be prompted to review the app on their respective store. + */ + static final FEATURE_MOBILE_WEBVIEW:FeatureFlag = "FEATURE_MOBILE_WEBVIEW"; + /** * `-DFEATURE_NAUGHTYNESS` * If this feature flag is enabled, naughtyness will be a toggleable option in the Options Menu. @@ -921,6 +927,7 @@ class Project extends HXProject FEATURE_MOBILE_ADVERTISEMENTS.apply(this, (isMobile() && isRelease() && !isIOSSimulator()) && envConfig != null); FEATURE_MOBILE_IAP.apply(this, (isMobile() && isRelease() && !isIOSSimulator()) && envConfig != null); FEATURE_MOBILE_IAR.apply(this, isMobile() && isRelease() && !isIOSSimulator()); + FEATURE_MOBILE_WEBVIEW.apply(this, isMobile() && FEATURE_NEWGROUNDS.isEnabled(this)); // The coveted ghost tapping feature. // Essential on mobile but delayed on desktop. @@ -1365,9 +1372,6 @@ class Project extends HXProject if (FEATURE_NEWGROUNDS.isEnabled(this)) { addHaxelib('newgrounds'); // Newgrounds API - - if (isMobile()) - addHaxelib('extension-webviewcore'); // WebView Extension } if (FEATURE_FUNKVIS.isEnabled(this)) @@ -1381,16 +1385,16 @@ class Project extends HXProject addHaxelib('FlxPartialSound'); // Partial sound } - if (FEATURE_MOBILE_ADVERTISEMENTS.isEnabled(this)) - { - addHaxelib('extension-admob'); // Ads Extension - } - if (FEATURE_HAPTICS.isEnabled(this)) { addHaxelib('extension-haptics'); // Haptic feedback } + if (FEATURE_MOBILE_ADVERTISEMENTS.isEnabled(this)) + { + addHaxelib('extension-admob'); // Ads Extension + } + if (FEATURE_MOBILE_IAP.isEnabled(this)) { addHaxelib('extension-iapcore'); // In-app purchases Extension @@ -1400,6 +1404,11 @@ class Project extends HXProject { addHaxelib('extension-iarcore'); // In-app reviews Extension } + + if (FEATURE_MOBILE_WEBVIEW.isEnabled(this)) + { + addHaxelib('extension-webviewcore'); // WebView Extension + } } function configureAssets() diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index c9f6b3255..d74ad4e6b 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -140,6 +140,11 @@ class InitState extends FlxState funkin.mobile.util.InAppReviewUtil.init(); #end + #if FEATURE_MOBILE_WEBVIEW + // Setup WebView + funkin.mobile.util.WebViewUtil.init(); + #end + #if android // Setup Callback util. funkin.external.android.CallbackUtil.init(); diff --git a/source/funkin/api/newgrounds/NewgroundsClient.hx b/source/funkin/api/newgrounds/NewgroundsClient.hx index 98fc22c0e..439e0f046 100644 --- a/source/funkin/api/newgrounds/NewgroundsClient.hx +++ b/source/funkin/api/newgrounds/NewgroundsClient.hx @@ -13,8 +13,8 @@ import io.newgrounds.utils.MedalList; import io.newgrounds.utils.SaveSlotList; import io.newgrounds.utils.ScoreBoardList; import io.newgrounds.objects.User; -#if mobile -import extension.webviewcore.WebView; +#if FEATURE_MOBILE_WEBVIEW +import funkin.mobile.util.WebViewUtil; #end @:build(funkin.util.macro.EnvironmentMacro.build()) @@ -115,12 +115,14 @@ class NewgroundsClient var passportHandler:String->Void = function(passportUrl:String) { // This exists so we can create a popup on mobile but with a WebView instead. - #if mobile + #if FEATURE_MOBILE_WEBVIEW if (passportUrl != null) { NG.core.logVerbose('Loading passport from WebView: ${passportUrl}'); - WebView.openWithURL(passportUrl); + WebViewUtil.openURL(passportUrl, function():Void { + NG.core.cancelLoginRequest(); + }); NG.core.onPassportUrlOpen(); } @@ -215,11 +217,8 @@ class NewgroundsClient function onLoginResolved(outcome:LoginOutcome):Void { - #if mobile - if (WebView.isOpened()) - { - WebView.close(); - } + #if FEATURE_MOBILE_WEBVIEW + WebViewUtil.close(); #end switch (outcome) diff --git a/source/funkin/mobile/util/InAppReviewUtil.hx b/source/funkin/mobile/util/InAppReviewUtil.hx index 7cc1966f1..ac807c0d2 100644 --- a/source/funkin/mobile/util/InAppReviewUtil.hx +++ b/source/funkin/mobile/util/InAppReviewUtil.hx @@ -18,7 +18,7 @@ class InAppReviewUtil /** * Chance for exiting the Results screen to display a prompt to review the game, as a percent. */ - public static var ODDS:UInt = 5; + public static final ODDS:UInt = 5; /** * Initializes callbacks tied to the In-App Review functionality. diff --git a/source/funkin/mobile/util/WebViewUtil.hx b/source/funkin/mobile/util/WebViewUtil.hx new file mode 100644 index 000000000..ce53fc77b --- /dev/null +++ b/source/funkin/mobile/util/WebViewUtil.hx @@ -0,0 +1,76 @@ +package funkin.mobile.util; + +#if FEATURE_MOBILE_WEBVIEW +import extension.webviewcore.WebView; + +/** + * Provides utility functions for working with WebView. + */ +class WebViewUtil +{ + /** + * Initializes the WebView. + */ + public static function init():Void + { + WebView.init(); + } + + /** + * Opens a URL in a WebView if one is not already open. + * + * @param url The URL to open. If the protocol is missing, 'https://' is prepended. + * Only 'http' and 'https' protocols are allowed; otherwise, an error is thrown. + * @param onCloseButtonPressed Optional callback function to be called when the WebView's close button is pressed. + * + * If the WebView is already open, this function does nothing. + */ + public static function openURL(url:String, ?onCloseButtonPressed:Void->Void):Void + { + if (!WebView.isOpened()) + { + var protocol:Array = url.split("://"); + + if (protocol.length == 1) + { + url = 'https://${url}'; + } + else if (protocol[0] != 'http' && protocol[0] != 'https') + { + throw "openURL can only open http and https links."; + } + + function onButtonClicked():Void + { + WebViewUtil.close(); + + if (onCloseButtonPressed != null) + { + onCloseButtonPressed(); + } + } + + WebView.onCloseButtonClicked.add(onButtonClicked); + + WebView.openWithURL(url, false, true); + } + } + + /** + * Closes the currently opened WebView if it is open. + * + * This function checks if the WebView is currently opened. + * + * If so, it removes all listeners from the `onCloseButtonClicked` event to prevent any further callbacks, and then closes the WebView. + */ + public static function close():Void + { + if (WebView.isOpened()) + { + WebView.onCloseButtonClicked.removeAll(); + + WebView.close(); + } + } +} +#end diff --git a/source/funkin/modding/PolymodHandler.hx b/source/funkin/modding/PolymodHandler.hx index 53e652221..f445c4d16 100644 --- a/source/funkin/modding/PolymodHandler.hx +++ b/source/funkin/modding/PolymodHandler.hx @@ -330,16 +330,27 @@ class PolymodHandler // Disable access to In-App Purchases Util Polymod.blacklistImport('funkin.mobile.util.InAppPurchasesUtil'); - // Disable access to Admob Extension - for (cls in ClassMacro.listClassesInPackage('extension.admob')) + // Disable access to In-App Reviews Util + Polymod.blacklistImport('funkin.mobile.util.InAppReviewUtil'); + + // Disable access to AndroidTools Extension + for (cls in ClassMacro.listClassesInPackage('extension.androidtools')) { if (cls == null) continue; var className:String = Type.getClassName(cls); Polymod.blacklistImport(className); } - // Disable access to AndroidTools Extension - for (cls in ClassMacro.listClassesInPackage('extension.androidtools')) + // Disable access to Haptics Extension + for (cls in ClassMacro.listClassesInPackage('extension.haptics')) + { + if (cls == null) continue; + var className:String = Type.getClassName(cls); + Polymod.blacklistImport(className); + } + + // Disable access to Admob Extension + for (cls in ClassMacro.listClassesInPackage('extension.admob')) { if (cls == null) continue; var className:String = Type.getClassName(cls); @@ -354,8 +365,16 @@ class PolymodHandler Polymod.blacklistImport(className); } - // Disable access to Haptics Extension - for (cls in ClassMacro.listClassesInPackage('extension.haptics')) + // Disable access to IARCore Extension + for (cls in ClassMacro.listClassesInPackage('extension.iarcore')) + { + if (cls == null) continue; + var className:String = Type.getClassName(cls); + Polymod.blacklistImport(className); + } + + // Disable access to WebViewCore Extension + for (cls in ClassMacro.listClassesInPackage('extension.webviewcore')) { if (cls == null) continue; var className:String = Type.getClassName(cls);