Sfoglia il codice sorgente

Use Voyager for WebView in non-reader places

arkon 2 anni fa
parent
commit
6efcb8ccfa

+ 1 - 1
app/src/main/java/eu/kanade/presentation/webview/WebViewScreen.kt → app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt

@@ -31,7 +31,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.util.system.setDefaultSettings
 
 @Composable
-fun WebViewScreen(
+fun WebViewScreenContent(
     onNavigateUp: () -> Unit,
     initialTitle: String?,
     url: String,

+ 8 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt

@@ -33,7 +33,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
 import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel
 import eu.kanade.tachiyomi.ui.home.HomeScreen
 import eu.kanade.tachiyomi.ui.manga.MangaScreen
-import eu.kanade.tachiyomi.ui.webview.WebViewActivity
+import eu.kanade.tachiyomi.ui.webview.WebViewScreen
 import eu.kanade.tachiyomi.util.Constants
 import kotlinx.coroutines.launch
 
@@ -89,8 +89,13 @@ data class SourceSearchScreen(
                 contentPadding = paddingValues,
                 onWebViewClick = {
                     val source = screenModel.source as? HttpSource ?: return@BrowseSourceContent
-                    val intent = WebViewActivity.newIntent(context, source.baseUrl, source.id, source.name)
-                    context.startActivity(intent)
+                    navigator.push(
+                        WebViewScreen(
+                            url = source.baseUrl,
+                            initialTitle = source.name,
+                            sourceId = source.id,
+                        ),
+                    )
                 },
                 onHelpClick = { uriHandler.openUri(Constants.URL_HELP) },
                 onLocalSourceHelpClick = { uriHandler.openUri(LocalSource.HELP_URL) },

+ 8 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt

@@ -53,7 +53,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
 import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing
 import eu.kanade.tachiyomi.ui.category.CategoryScreen
 import eu.kanade.tachiyomi.ui.manga.MangaScreen
-import eu.kanade.tachiyomi.ui.webview.WebViewActivity
+import eu.kanade.tachiyomi.ui.webview.WebViewScreen
 import eu.kanade.tachiyomi.util.Constants
 import eu.kanade.tachiyomi.util.lang.launchIO
 import kotlinx.coroutines.channels.Channel
@@ -95,8 +95,13 @@ data class BrowseSourceScreen(
 
         val onWebViewClick = f@{
             val source = screenModel.source as? HttpSource ?: return@f
-            val intent = WebViewActivity.newIntent(context, source.baseUrl, source.id, source.name)
-            context.startActivity(intent)
+            navigator.push(
+                WebViewScreen(
+                    url = source.baseUrl,
+                    initialTitle = source.name,
+                    sourceId = source.id,
+                ),
+            )
         }
 
         LaunchedEffect(screenModel.source) {

+ 10 - 5
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt

@@ -48,7 +48,7 @@ import eu.kanade.tachiyomi.ui.category.CategoryScreen
 import eu.kanade.tachiyomi.ui.home.HomeScreen
 import eu.kanade.tachiyomi.ui.manga.track.TrackInfoDialogHomeScreen
 import eu.kanade.tachiyomi.ui.reader.ReaderActivity
-import eu.kanade.tachiyomi.ui.webview.WebViewActivity
+import eu.kanade.tachiyomi.ui.webview.WebViewScreen
 import eu.kanade.tachiyomi.util.lang.withIOContext
 import eu.kanade.tachiyomi.util.system.copyToClipboard
 import eu.kanade.tachiyomi.util.system.logcat
@@ -109,7 +109,7 @@ class MangaScreen(
                 screenModel.toggleFavorite()
                 haptic.performHapticFeedback(HapticFeedbackType.LongPress)
             },
-            onWebViewClicked = { openMangaInWebView(context, screenModel.manga, screenModel.source) }.takeIf { isHttpSource },
+            onWebViewClicked = { openMangaInWebView(navigator, screenModel.manga, screenModel.source) }.takeIf { isHttpSource },
             onWebViewLongClicked = { copyMangaUrl(context, screenModel.manga, screenModel.source) }.takeIf { isHttpSource },
             onTrackingClicked = screenModel::showTrackDialog.takeIf { successState.trackingAvailable },
             onTagClicked = { scope.launch { performGenreSearch(navigator, it, screenModel.source!!) } },
@@ -240,10 +240,15 @@ class MangaScreen(
         }
     }
 
-    private fun openMangaInWebView(context: Context, manga_: Manga?, source_: Source?) {
+    private fun openMangaInWebView(navigator: Navigator, manga_: Manga?, source_: Source?) {
         getMangaUrl(manga_, source_)?.let { url ->
-            val intent = WebViewActivity.newIntent(context, url, source_?.id, manga_?.title)
-            context.startActivity(intent)
+            navigator.push(
+                WebViewScreen(
+                    url = url,
+                    initialTitle = manga_?.title,
+                    sourceId = source_?.id,
+                ),
+            )
         }
     }
 

+ 4 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt

@@ -6,7 +6,7 @@ import android.content.Intent
 import android.os.Bundle
 import android.widget.Toast
 import androidx.core.net.toUri
-import eu.kanade.presentation.webview.WebViewScreen
+import eu.kanade.presentation.webview.WebViewScreenContent
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.network.NetworkHelper
 import eu.kanade.tachiyomi.source.SourceManager
@@ -45,13 +45,13 @@ class WebViewActivity : BaseActivity() {
         val url = intent.extras?.getString(URL_KEY) ?: return
         assistUrl = url
 
-        var headers = mutableMapOf<String, String>()
+        var headers = emptyMap<String, String>()
         (sourceManager.get(intent.extras!!.getLong(SOURCE_KEY)) as? HttpSource)?.let { source ->
-            headers = source.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }.toMutableMap()
+            headers = source.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }
         }
 
         setComposeContent {
-            WebViewScreen(
+            WebViewScreenContent(
                 onNavigateUp = { finish() },
                 initialTitle = intent.extras?.getString(TITLE_KEY),
                 url = url,

+ 42 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewScreen.kt

@@ -0,0 +1,42 @@
+package eu.kanade.tachiyomi.ui.webview
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import cafe.adriel.voyager.core.model.rememberScreenModel
+import cafe.adriel.voyager.core.screen.Screen
+import cafe.adriel.voyager.core.screen.uniqueScreenKey
+import cafe.adriel.voyager.navigator.LocalNavigator
+import cafe.adriel.voyager.navigator.currentOrThrow
+import eu.kanade.presentation.util.AssistContentScreen
+import eu.kanade.presentation.webview.WebViewScreenContent
+
+class WebViewScreen(
+    private val url: String,
+    private val initialTitle: String? = null,
+    private val sourceId: Long? = null,
+) : Screen, AssistContentScreen {
+
+    private var assistUrl: String? = null
+
+    override val key = uniqueScreenKey
+
+    override fun onProvideAssistUrl() = assistUrl
+
+    @Composable
+    override fun Content() {
+        val navigator = LocalNavigator.currentOrThrow
+        val context = LocalContext.current
+        val screenModel = rememberScreenModel { WebViewScreenModel(sourceId) }
+
+        WebViewScreenContent(
+            onNavigateUp = { navigator.pop() },
+            initialTitle = initialTitle,
+            url = url,
+            headers = screenModel.headers,
+            onUrlChange = { assistUrl = it },
+            onShare = { screenModel.shareWebpage(context, it) },
+            onOpenInBrowser = { screenModel.openInBrowser(context, it) },
+            onClearCookies = screenModel::clearCookies,
+        )
+    }
+}

+ 48 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewScreenModel.kt

@@ -0,0 +1,48 @@
+package eu.kanade.tachiyomi.ui.webview
+
+import android.content.Context
+import androidx.core.net.toUri
+import cafe.adriel.voyager.core.model.StateScreenModel
+import eu.kanade.presentation.more.stats.StatsScreenState
+import eu.kanade.tachiyomi.network.NetworkHelper
+import eu.kanade.tachiyomi.source.SourceManager
+import eu.kanade.tachiyomi.source.online.HttpSource
+import eu.kanade.tachiyomi.util.system.logcat
+import eu.kanade.tachiyomi.util.system.openInBrowser
+import eu.kanade.tachiyomi.util.system.toShareIntent
+import eu.kanade.tachiyomi.util.system.toast
+import okhttp3.HttpUrl.Companion.toHttpUrl
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+
+class WebViewScreenModel(
+    val sourceId: Long?,
+    private val sourceManager: SourceManager = Injekt.get(),
+    private val network: NetworkHelper = Injekt.get(),
+) : StateScreenModel<StatsScreenState>(StatsScreenState.Loading) {
+
+    var headers = emptyMap<String, String>()
+
+    init {
+        sourceId?.let { sourceManager.get(it) as? HttpSource }?.let { source ->
+            headers = source.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }
+        }
+    }
+
+    fun shareWebpage(context: Context, url: String) {
+        try {
+            context.startActivity(url.toUri().toShareIntent(context, type = "text/plain"))
+        } catch (e: Exception) {
+            context.toast(e.message)
+        }
+    }
+
+    fun openInBrowser(context: Context, url: String) {
+        context.openInBrowser(url, forceDefaultBrowser = true)
+    }
+
+    fun clearCookies(url: String) {
+        val cleared = network.cookieManager.remove(url.toHttpUrl())
+        logcat { "Cleared $cleared cookies for: $url" }
+    }
+}