Use Voyager for WebView in non-reader places

This commit is contained in:
arkon 2022-12-04 17:23:24 -05:00
parent 0d128b75e2
commit 6efcb8ccfa
7 changed files with 121 additions and 16 deletions

View file

@ -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,

View file

@ -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) },

View file

@ -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) {

View file

@ -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,
),
)
}
}

View file

@ -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,

View file

@ -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,
)
}
}

View file

@ -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" }
}
}