diff --git a/feature/about/src/androidMain/AndroidManifest.xml b/feature/about/src/androidMain/AndroidManifest.xml new file mode 100644 index 000000000..0d7c6f981 --- /dev/null +++ b/feature/about/src/androidMain/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/MyWebView.desktop.kt b/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/AndroidApp.kt similarity index 59% rename from feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/MyWebView.desktop.kt rename to feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/AndroidApp.kt index 8c5ee699e..89fa3dfb7 100644 --- a/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/MyWebView.desktop.kt +++ b/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/AndroidApp.kt @@ -9,14 +9,15 @@ */ package org.mifos.mobile.feature.about -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier +import android.app.Application -@Composable -actual fun MyWebView( - htmlContent: String, - isLoading: (isLoading: Boolean) -> Unit, - onUrlClicked: (url: String) -> Unit, - modifier: Modifier, -) { +class AndroidApp : Application() { + override fun onCreate() { + super.onCreate() + instance = this + } + + companion object { + lateinit var instance: AndroidApp + } } diff --git a/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/MyWebView.android.kt b/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.android.kt similarity index 98% rename from feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/MyWebView.android.kt rename to feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.android.kt index ca7ff37a2..e6411ca73 100644 --- a/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/MyWebView.android.kt +++ b/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.android.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView @Composable -actual fun MyWebView( +actual fun MifosWebView( htmlContent: String, isLoading: (isLoading: Boolean) -> Unit, onUrlClicked: (url: String) -> Unit, diff --git a/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.android.kt b/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.android.kt index 9ef7282ee..6da6c0c55 100644 --- a/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.android.kt +++ b/feature/about/src/androidMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.android.kt @@ -12,6 +12,15 @@ package org.mifos.mobile.feature.about import android.content.Intent import android.net.Uri -actual fun openUrl(url: String?) { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) +internal actual fun openUrl(url: String?) { + val uri = url?.let { Uri.parse(url) } ?: return + val intent = Intent().apply { + action = Intent.ACTION_VIEW + data = uri + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + AndroidApp.instance.startActivity(intent) +} + +internal actual fun openOssLicenses() { } diff --git a/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/MyWebView.kt b/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.kt similarity index 95% rename from feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/MyWebView.kt rename to feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.kt index 17c002b92..3de1b5fef 100644 --- a/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/MyWebView.kt +++ b/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.kt @@ -13,7 +13,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @Composable -expect fun MyWebView( +expect fun MifosWebView( htmlContent: String, isLoading: (isLoading: Boolean) -> Unit, onUrlClicked: (url: String) -> Unit, diff --git a/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.kt b/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.kt index 65d18a8d3..e207847f1 100644 --- a/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.kt +++ b/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.kt @@ -9,4 +9,6 @@ */ package org.mifos.mobile.feature.about -expect fun openUrl(url: String?) +internal expect fun openUrl(url: String?) + +internal expect fun openOssLicenses() diff --git a/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/ui/PrivacyPolicyScreen.kt b/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/ui/PrivacyPolicyScreen.kt index c4093e0c3..9eab2cb46 100644 --- a/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/ui/PrivacyPolicyScreen.kt +++ b/feature/about/src/commonMain/kotlin/org/mifos/mobile/feature/about/ui/PrivacyPolicyScreen.kt @@ -26,7 +26,7 @@ import mifos_mobile.feature.about.generated.resources.feature_about_privacy_poli import org.jetbrains.compose.resources.stringResource import org.mifos.mobile.core.designsystem.component.MifosScaffold import org.mifos.mobile.core.ui.component.MifosProgressIndicator -import org.mifos.mobile.feature.about.MyWebView +import org.mifos.mobile.feature.about.MifosWebView import org.mifos.mobile.feature.about.openUrl @Composable @@ -56,7 +56,7 @@ private fun WebView( Column(modifier) { Spacer(modifier = Modifier.height(20.dp)) - MyWebView( + MifosWebView( htmlContent = url, isLoading = { isLoading = it }, modifier = Modifier.fillMaxWidth(), diff --git a/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.desktop.kt b/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.desktop.kt new file mode 100644 index 000000000..6004ea655 --- /dev/null +++ b/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.desktop.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.feature.about + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign + +@Composable +actual fun MifosWebView( + htmlContent: String, + isLoading: (isLoading: Boolean) -> Unit, + onUrlClicked: (url: String) -> Unit, + modifier: Modifier, +) { + Box(modifier = modifier.fillMaxSize()) { + Text( + text = "Implement platform specific WebView for Desktop", + textAlign = TextAlign.Center, + modifier = Modifier.align(Alignment.Center), + ) + } +} diff --git a/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.desktop.kt b/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.desktop.kt index eb50e0107..4f0f0dd4d 100644 --- a/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.desktop.kt +++ b/feature/about/src/desktopMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.desktop.kt @@ -13,7 +13,9 @@ import java.awt.Desktop import java.net.URI actual fun openUrl(url: String?) { - if (Desktop.isDesktopSupported()) { - Desktop.getDesktop().browse(URI(url)) - } + val uri = url?.let { URI.create(it) } ?: return + Desktop.getDesktop().browse(uri) +} + +internal actual fun openOssLicenses() { } diff --git a/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/MyWebView.wasmJs.kt b/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.js.kt similarity index 95% rename from feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/MyWebView.wasmJs.kt rename to feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.js.kt index 8c5ee699e..6d344a9ce 100644 --- a/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/MyWebView.wasmJs.kt +++ b/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.js.kt @@ -13,7 +13,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @Composable -actual fun MyWebView( +actual fun MifosWebView( htmlContent: String, isLoading: (isLoading: Boolean) -> Unit, onUrlClicked: (url: String) -> Unit, diff --git a/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.js.kt b/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.js.kt index efb9dbb1e..2f05809eb 100644 --- a/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.js.kt +++ b/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.js.kt @@ -9,6 +9,13 @@ */ package org.mifos.mobile.feature.about +import kotlinx.browser.window + actual fun openUrl(url: String?) { -// window.open(url, "_blank") // Opens in a new tab" + if (url != null) { + window.open(url, "_blank") // Opens in a new tab + } +} + +internal actual fun openOssLicenses() { } diff --git a/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/MyWebView.js.kt b/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.native.kt similarity index 54% rename from feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/MyWebView.js.kt rename to feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.native.kt index 8c5ee699e..2d11e63a8 100644 --- a/feature/about/src/jsMain/kotlin/org/mifos/mobile/feature/about/MyWebView.js.kt +++ b/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.native.kt @@ -9,14 +9,26 @@ */ package org.mifos.mobile.feature.about +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign @Composable -actual fun MyWebView( +actual fun MifosWebView( htmlContent: String, isLoading: (isLoading: Boolean) -> Unit, onUrlClicked: (url: String) -> Unit, modifier: Modifier, ) { + Box(modifier = modifier.fillMaxSize()) { + Text( + text = "Implement platform specific WebView for IOS", + textAlign = TextAlign.Center, + modifier = Modifier.align(Alignment.Center), + ) + } } diff --git a/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/MyWebView.native.kt b/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/MyWebView.native.kt deleted file mode 100644 index 4c5e8a9ec..000000000 --- a/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/MyWebView.native.kt +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2025 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.feature.about - -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.UIKitView -import platform.UIKit.NSLayoutConstraint -import platform.UIKit.UIView -import platform.WebKit.WKNavigationAction -import platform.WebKit.WKNavigationActionPolicy -import platform.WebKit.WKNavigationDelegateProtocol -import platform.WebKit.WKNavigationTypeLinkActivated -import platform.WebKit.WKWebView -import platform.WebKit.WKWebViewConfiguration -import platform.darwin.NSObject - -@Composable -actual fun MyWebView( - htmlContent: String, - isLoading: (isLoading: Boolean) -> Unit, - onUrlClicked: (url: String) -> Unit, - modifier: Modifier, -) { - val content = remember { htmlContent } - val webView = remember { WKWebView() } - - // Define the WKNavigationDelegate - val navigationDelegate = rememberWebViewDelegate(onUrlClicked) - - // Set WKNavigationDelegate to the webView - webView.navigationDelegate = navigationDelegate - UIKitView( - modifier = modifier.padding(top = 12.dp), - factory = { - val container = UIView() - container.addSubview(webView) - - // Enable Auto Layout - webView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activateConstraints( - listOf( - webView.topAnchor.constraintEqualToAnchor(container.topAnchor), - webView.bottomAnchor.constraintEqualToAnchor(container.bottomAnchor), - webView.leadingAnchor.constraintEqualToAnchor(container.leadingAnchor), - webView.trailingAnchor.constraintEqualToAnchor(container.trailingAnchor), - ), - ) - webView.apply { - WKWebViewConfiguration().apply { - allowsInlineMediaPlayback = true - allowsAirPlayForMediaPlayback = true - allowsPictureInPictureMediaPlayback = true - } - loadHTMLString(content, baseURL = null) - } - container - }, - ) -} - -@Composable -private fun rememberWebViewDelegate(onUrlClicked: (String) -> Unit): WKNavigationDelegateProtocol { - return object : NSObject(), WKNavigationDelegateProtocol { - override fun webView( - webView: WKWebView, - decidePolicyForNavigationAction: WKNavigationAction, - decisionHandler: (WKNavigationActionPolicy) -> Unit, - ) { - val navigationType = decidePolicyForNavigationAction.navigationType - val request = decidePolicyForNavigationAction.request - - when (navigationType) { - WKNavigationTypeLinkActivated -> { - // Handle link clicks - if (decidePolicyForNavigationAction.targetFrame == null) { - // Load the link in the same WKWebView - webView.loadRequest(request) - } - onUrlClicked(request.URL?.absoluteString ?: "") - println(request.URL?.absoluteString ?: "") - decisionHandler(WKNavigationActionPolicy.WKNavigationActionPolicyAllow) - } - - else -> decisionHandler(WKNavigationActionPolicy.WKNavigationActionPolicyAllow) - } - } - } -} diff --git a/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.native.kt b/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.native.kt index bbbc5f882..8df6cae39 100644 --- a/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.native.kt +++ b/feature/about/src/nativeMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.native.kt @@ -9,9 +9,17 @@ */ package org.mifos.mobile.feature.about -actual fun openUrl(url: String?) { -// val nsUrl = NSURL.URLWithString(url) -// if (nsUrl != null) { -// UIApplication.sharedApplication.openURL(nsUrl) -// } +import platform.Foundation.NSURL +import platform.UIKit.UIApplication + +internal actual fun openUrl(url: String?) { + val nsUrl = url?.let { NSURL.URLWithString(it) } ?: return + UIApplication.sharedApplication.openURL(nsUrl, options = emptyMap()) { success -> + if (!success) { + println("Failed to open URL: $url") + } + } +} + +internal actual fun openOssLicenses() { } diff --git a/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.wasmJs.kt b/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.wasmJs.kt new file mode 100644 index 000000000..d83350986 --- /dev/null +++ b/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/MifosWebView.wasmJs.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.feature.about + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign + +@Composable +actual fun MifosWebView( + htmlContent: String, + isLoading: (isLoading: Boolean) -> Unit, + onUrlClicked: (url: String) -> Unit, + modifier: Modifier, +) { + Box(modifier = modifier.fillMaxSize()) { + Text( + text = "Implement platform specific WebView for WasmJs", + textAlign = TextAlign.Center, + modifier = Modifier.align(Alignment.Center), + ) + } +} diff --git a/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.wasmJs.kt b/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.wasmJs.kt index dd20118d5..2f05809eb 100644 --- a/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.wasmJs.kt +++ b/feature/about/src/wasmJsMain/kotlin/org/mifos/mobile/feature/about/OpenUrl.wasmJs.kt @@ -9,6 +9,13 @@ */ package org.mifos.mobile.feature.about +import kotlinx.browser.window + actual fun openUrl(url: String?) { -// window.open(url, "_blank") // Opens in a new tab + if (url != null) { + window.open(url, "_blank") // Opens in a new tab + } +} + +internal actual fun openOssLicenses() { }