diff --git a/android/README.md b/android/README.md index 959c53f..b03860c 100644 --- a/android/README.md +++ b/android/README.md @@ -5,6 +5,17 @@ A hybrid mobile app built with **Next.js (TypeScript)** frontend, **Firebase bac Right now it's just a webview wrapper around the web application, but in the future it may contain native code as well. +/!\ This is still a work in progress, as google sign in does not work yet. Most of the issue is that Google doesn't allow to sign in inside the webview for security reasons. + +We could sign in in a browser with signInWithRedirect and then redirect to the webview, but I haven't found a way to make it come back to the app and store the token. + +We could also use a native sign in with SocialLogin, but it only runs on local assets, not on the webview that loads the remote sign-in page. So one way would be to force the webview to load the local assets, but it's not a clean solution and I haven't found a way to do it yet. + +Third solution is to implement a native app, not using webview, in React Native. + +If you can make it work, please contribute! + + This document describes how to: 1. Build and run the web frontend and backend locally 2. Sync and build the Android WebView wrapper @@ -101,7 +112,7 @@ npx cap sync android ### Load from site -During local development, open Android Studio project and run the app on an emulator or your physical device. +During local development, open Android Studio project and run the app on an emulator or your physical device. Note that right now you can't use a physical device for the local web version (`10.0.2.2:3000 time out` ) ``` npx cap open android diff --git a/android/app/src/main/java/com/compass/app/MainActivity.java b/android/app/src/main/java/com/compass/app/MainActivity.java index 3033883..3ef1b40 100644 --- a/android/app/src/main/java/com/compass/app/MainActivity.java +++ b/android/app/src/main/java/com/compass/app/MainActivity.java @@ -1,13 +1,13 @@ package com.compass.app; import android.content.Intent; -import android.net.Uri; import android.os.Bundle; import android.util.Log; +import android.webkit.JavascriptInterface; import android.webkit.WebView; -import android.webkit.WebViewClient; import com.getcapacitor.BridgeActivity; +import com.getcapacitor.BridgeWebViewClient; import com.getcapacitor.Plugin; import com.getcapacitor.PluginHandle; @@ -16,43 +16,58 @@ import ee.forgr.capacitor.social.login.ModifiedMainActivityForSocialLoginPlugin; import ee.forgr.capacitor.social.login.SocialLoginPlugin; public class MainActivity extends BridgeActivity implements ModifiedMainActivityForSocialLoginPlugin { + public class NativeBridge { + @JavascriptInterface + public boolean isNativeApp() { + return true; + } + } + + private static final String LOCAL_URL = "file:///android_asset/public/server/pages"; + private static final String REMOTE_URL = "https://www.compassmeet.com"; + + // Optional helper for future use + public void loadLocalContent() { + Log.i("CompassApp", "Loading local assets..."); + this.bridge.getWebView().loadUrl(LOCAL_URL); + } + + public void loadRemoteContent() { + Log.i("CompassApp", "Loading remote content..."); + this.bridge.getWebView().loadUrl(REMOTE_URL); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - WebView.setWebContentsDebuggingEnabled(true); WebView webView = this.bridge.getWebView(); + webView.setWebViewClient(new BridgeWebViewClient(this.bridge)); + + WebView.setWebContentsDebuggingEnabled(true); // Set a recognizable User-Agent (always reliable) webView.getSettings().setUserAgentString( webView.getSettings().getUserAgentString() + " CompassAppWebView" ); - // To know in JS if we are running from an APK - webView.evaluateJavascript("window.IS_APK = true;", null); + webView.getSettings().setJavaScriptEnabled(true); + webView.addJavascriptInterface(new NativeBridge(), "AndroidBridge"); - webView.setWebViewClient(new WebViewClient() { - @Override - public void onPageFinished(WebView view, String url) { - super.onPageFinished(view, url); - // This runs once the document exists - view.evaluateJavascript("window.IS_APK = true;", null); - } - - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - // Load only compassmeet.com URLs in WebView - if (url.startsWith("https://www.compassmeet.com")) { - view.loadUrl(url); - return true; - } - - // All other URLs open externally - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - startActivity(intent); - return true; // handled externally - } - }); + // Allow remote URLs to still have access to Capacitor bridge +// webView.setWebViewClient(new BridgeWebViewClient(this.bridge) { +// @Override +// public boolean shouldOverrideUrlLoading(android.webkit.WebView view, String url) { +// if (url.startsWith("https://www.compassmeet.com")) { +// view.loadUrl(url); +// return true; +// } +// return super.shouldOverrideUrlLoading(view, url); +// } +// }); +// +// // Load your remote site instead of local assets +// this.bridge.getWebView().loadUrl("https://www.compassmeet.com"); } @Override diff --git a/capacitor.config.ts b/capacitor.config.ts index 8de1201..0667140 100644 --- a/capacitor.config.ts +++ b/capacitor.config.ts @@ -9,7 +9,8 @@ const config: CapacitorConfig = { webDir: 'web/.next', server: { url: LOCAL_ANDROID ? "http://10.0.2.2:3000" : 'https://compassmeet.com', - cleartext: true + cleartext: true, + "allowNavigation": ["www.compassmeet.com"], }, };