mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-08-05 19:59:51 +00:00
Refactor webview configuration and data clearing functions for iOS and JVM platforms
- Updated `platformWebviewConfig` function to accept an optional `pluginId` parameter for both iOS and JVM implementations. - Enhanced data directory handling in JVM to create a separate directory for each plugin. - Implemented `platformClearWebviewData` function for both platforms to clear webview data based on the provided `pluginId`. - Added necessary imports for iOS and JVM specific functionalities.
This commit is contained in:
parent
14ee4f6a4c
commit
fe0ebb47fe
@ -17,8 +17,20 @@
|
||||
|
||||
package dev.krtirtho.spotube.core.webview
|
||||
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.WebStorage
|
||||
import android.webkit.WebView
|
||||
import io.github.kdroidfilter.webview.web.WebViewState
|
||||
|
||||
actual fun platformWebviewConfig(webView: WebViewState) {
|
||||
webView.webView?.nativeWebView?.settings?.domStorageEnabled = true
|
||||
actual fun platformWebviewConfig(webView: WebViewState, pluginId: String?) {
|
||||
val nativeWebView = webView.webView?.nativeWebView as? WebView ?: return
|
||||
nativeWebView.settings.domStorageEnabled = true
|
||||
}
|
||||
|
||||
actual suspend fun platformClearWebviewData(pluginId: String?) {
|
||||
if (pluginId == null) return
|
||||
|
||||
CookieManager.getInstance().removeAllCookies(null)
|
||||
CookieManager.getInstance().flush()
|
||||
WebStorage.getInstance().deleteAllData()
|
||||
}
|
||||
@ -38,6 +38,8 @@ class WebViewController(val navigationCommands: NavigationCommands): KoinCompone
|
||||
private var cookieManager: CookieManager? = null
|
||||
private val urlFlow = MutableStateFlow("")
|
||||
private val webViewCreated = MutableSharedFlow<Unit>(replay = 1)
|
||||
var currentPluginId: String? = null
|
||||
private set
|
||||
|
||||
suspend fun getCookies(url: String): List<Cookie> {
|
||||
if (cookieManager == null) {
|
||||
@ -104,19 +106,21 @@ class WebViewController(val navigationCommands: NavigationCommands): KoinCompone
|
||||
webViewNavigator = null
|
||||
}
|
||||
|
||||
fun navigateTo(url: String) {
|
||||
fun navigateTo(url: String, pluginId: String) {
|
||||
if (this.content != null) {
|
||||
throw IllegalStateException("WebView is already open. Please close the current WebView before navigating to a new URL.")
|
||||
}
|
||||
this.currentPluginId = pluginId
|
||||
this.content = url
|
||||
this.isHtmlContent = false
|
||||
navigationCommands.navigateTo(Routes.WebView)
|
||||
}
|
||||
|
||||
fun navigateToHTML(html: String) {
|
||||
fun navigateToHTML(html: String, pluginId: String) {
|
||||
if (this.content != null) {
|
||||
throw IllegalStateException("WebView is already open. Please close the current WebView before navigating to a new URL.")
|
||||
}
|
||||
this.currentPluginId = pluginId
|
||||
this.content = html
|
||||
this.isHtmlContent = true
|
||||
navigationCommands.navigateTo(Routes.WebView)
|
||||
@ -138,12 +142,15 @@ class WebViewController(val navigationCommands: NavigationCommands): KoinCompone
|
||||
return completer.await()
|
||||
}
|
||||
|
||||
suspend fun clearData() {
|
||||
suspend fun clearData(pluginId: String? = null) {
|
||||
cookieManager?.removeAllCookies()
|
||||
val targetPluginId = pluginId ?: currentPluginId
|
||||
platformClearWebviewData(targetPluginId)
|
||||
cookieManager = null
|
||||
content = null
|
||||
isHtmlContent = false
|
||||
webViewNavigator = null
|
||||
currentPluginId = null
|
||||
}
|
||||
|
||||
val urlChangedFlow = urlFlow.asStateFlow()
|
||||
|
||||
@ -19,4 +19,6 @@ package dev.krtirtho.spotube.core.webview
|
||||
|
||||
import io.github.kdroidfilter.webview.web.WebViewState
|
||||
|
||||
expect fun platformWebviewConfig(webView: WebViewState)
|
||||
expect fun platformWebviewConfig(webView: WebViewState, pluginId: String?)
|
||||
|
||||
expect suspend fun platformClearWebviewData(pluginId: String?)
|
||||
|
||||
@ -19,7 +19,6 @@ package dev.krtirtho.spotube.core.webview
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@ -40,30 +39,25 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.github.kdroidfilter.webview.jsbridge.IJsMessageHandler
|
||||
import io.github.kdroidfilter.webview.jsbridge.JsMessage
|
||||
import io.github.kdroidfilter.webview.jsbridge.rememberWebViewJsBridge
|
||||
import io.github.kdroidfilter.webview.web.WebView
|
||||
import io.github.kdroidfilter.webview.web.rememberWebViewNavigator
|
||||
import io.github.kdroidfilter.webview.web.WebViewState
|
||||
import io.github.kdroidfilter.webview.web.WebViewNavigator
|
||||
import compose.icons.FeatherIcons
|
||||
import compose.icons.feathericons.ChevronLeft
|
||||
import compose.icons.feathericons.ChevronRight
|
||||
import compose.icons.feathericons.X
|
||||
import dev.krtirtho.spotube.core.tools.user_agents.UserAgents
|
||||
import kotlinx.coroutines.launch
|
||||
import io.github.kdroidfilter.webview.jsbridge.IJsMessageHandler
|
||||
import io.github.kdroidfilter.webview.jsbridge.JsMessage
|
||||
import io.github.kdroidfilter.webview.jsbridge.rememberWebViewJsBridge
|
||||
import io.github.kdroidfilter.webview.web.WebView
|
||||
import io.github.kdroidfilter.webview.web.WebViewNavigator
|
||||
import io.github.kdroidfilter.webview.web.WebViewState
|
||||
import io.github.kdroidfilter.webview.web.rememberWebViewNavigator
|
||||
|
||||
class PostMessageHandler(
|
||||
private val onMessageReceived: (String) -> Unit = {}
|
||||
@ -98,7 +92,7 @@ fun PlatformWebViewScreen(webViewController: WebViewController) {
|
||||
)
|
||||
}.apply {
|
||||
this.content = webViewController.getWebContent()
|
||||
platformWebviewConfig(this)
|
||||
platformWebviewConfig(this, webViewController.currentPluginId)
|
||||
}
|
||||
|
||||
val navigator = rememberWebViewNavigator()
|
||||
|
||||
@ -141,7 +141,7 @@ open class ZiplinePluginService(
|
||||
}
|
||||
|
||||
private val realHttpClientAPI = RealHttpClientAPI()
|
||||
private val realWebViewAPI = RealWebViewAPI(scope, webViewController)
|
||||
private val realWebViewAPI = RealWebViewAPI(scope, webViewController, pluginInfo.id)
|
||||
|
||||
private val persistedStorageAPI = RealPersistedStorageAPI(pluginInfo)
|
||||
private val cryptoAPI = RealCryptoAPI(scope.coroutineContext)
|
||||
|
||||
@ -22,26 +22,24 @@ import dev.krtirtho.plugin_interfaces.host_apis.WebViewAPI
|
||||
import dev.krtirtho.spotube.core.webview.WebViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class RealWebViewAPI(
|
||||
private val scope: CoroutineScope,
|
||||
private val webViewController: WebViewController,
|
||||
private val pluginId: String,
|
||||
) : WebViewAPI {
|
||||
override fun navigateTo(url: String) {
|
||||
scope.launch(Dispatchers.Main) {
|
||||
webViewController.navigateTo(url)
|
||||
webViewController.navigateTo(url, pluginId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun navigateToHTML(html: String) {
|
||||
scope.launch {
|
||||
webViewController.navigateToHTML(html)
|
||||
webViewController.navigateToHTML(html, pluginId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -735,7 +735,7 @@ fun PluginScreen(
|
||||
selectedService.use { coreAPI.logout() }
|
||||
}
|
||||
// should clear webview data after logout
|
||||
scope.launch { webviewController.clearData() }
|
||||
scope.launch { webviewController.clearData(plugin.id) }
|
||||
}
|
||||
} else {
|
||||
null
|
||||
|
||||
@ -18,6 +18,24 @@
|
||||
package dev.krtirtho.spotube.core.webview
|
||||
|
||||
import io.github.kdroidfilter.webview.web.WebViewState
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import platform.Foundation.NSDate
|
||||
import platform.Foundation.NSHTTPCookieStorage
|
||||
import platform.Foundation.distantPast
|
||||
import platform.WebKit.WKWebsiteDataStore
|
||||
import platform.WebKit.WKWebsiteDataTypeCookies
|
||||
import platform.WebKit.WKWebsiteDataTypeLocalStorage
|
||||
|
||||
actual fun platformWebviewConfig(webView: WebViewState) {
|
||||
actual fun platformWebviewConfig(webView: WebViewState, pluginId: String?) {
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
actual suspend fun platformClearWebviewData(pluginId: String?) {
|
||||
if (pluginId == null) return
|
||||
|
||||
val dataStore = WKWebsiteDataStore.defaultDataStore()
|
||||
val dataTypes = setOf(WKWebsiteDataTypeCookies, WKWebsiteDataTypeLocalStorage)
|
||||
dataStore.removeDataOfTypes(dataTypes, NSDate.distantPast) {}
|
||||
|
||||
NSHTTPCookieStorage.sharedHTTPCookieStorage.removeCookiesSinceDate(NSDate.distantPast)
|
||||
}
|
||||
@ -19,13 +19,24 @@ package dev.krtirtho.spotube.core.webview
|
||||
|
||||
import dev.krtirtho.spotube.core.paths.Paths
|
||||
import io.github.kdroidfilter.webview.web.WebViewState
|
||||
import io.github.vinceglb.filekit.utils.div
|
||||
import io.github.vinceglb.filekit.utils.toPath
|
||||
import okio.FileSystem
|
||||
import okio.Path.Companion.toPath
|
||||
import org.koin.core.context.GlobalContext
|
||||
|
||||
actual fun platformWebviewConfig(webView: WebViewState) {
|
||||
actual fun platformWebviewConfig(webView: WebViewState, pluginId: String?) {
|
||||
val paths = GlobalContext.get().get<Paths>()
|
||||
|
||||
webView.webSettings.desktopWebSettings.dataDirectory =
|
||||
(paths.getApplicationCacheDirPath().toPath() / "webview_data").toString()
|
||||
val baseDir = "${paths.getApplicationCacheDirPath()}/webview_data".toPath()
|
||||
val dataDir = if (pluginId != null) baseDir / pluginId else baseDir
|
||||
webView.webSettings.desktopWebSettings.dataDirectory = dataDir.toString()
|
||||
}
|
||||
|
||||
actual suspend fun platformClearWebviewData(pluginId: String?) {
|
||||
if (pluginId == null) return
|
||||
val paths = GlobalContext.get().get<Paths>()
|
||||
val dataDirStr = "${paths.getApplicationCacheDirPath()}/webview_data/$pluginId"
|
||||
val dataDir = dataDirStr.toPath()
|
||||
if (FileSystem.SYSTEM.exists(dataDir)) {
|
||||
FileSystem.SYSTEM.deleteRecursively(dataDir)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user