summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/ui/LinkReaderScreen.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/ui/LinkReaderScreen.kt')
-rw-r--r--app/src/main/java/org/terst/feedreader/ui/LinkReaderScreen.kt112
1 files changed, 112 insertions, 0 deletions
diff --git a/app/src/main/java/org/terst/feedreader/ui/LinkReaderScreen.kt b/app/src/main/java/org/terst/feedreader/ui/LinkReaderScreen.kt
new file mode 100644
index 0000000..ff764c4
--- /dev/null
+++ b/app/src/main/java/org/terst/feedreader/ui/LinkReaderScreen.kt
@@ -0,0 +1,112 @@
+package org.terst.feedreader.ui
+
+import android.content.Intent
+import android.net.Uri
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material.icons.filled.OpenInBrowser
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+import org.terst.feedreader.readability.ReaderExtractor
+
+/**
+ * A lightweight, non-persisted reader view for links tapped inside an article's
+ * WebView -- extracts the linked page with the same Readability pipeline as the
+ * main reader, but doesn't touch the DB (it's not a subscribed article), and
+ * recursively re-opens itself for any further links tapped inside, so link-hopping
+ * stays inside the app's reader instead of dropping into a raw WebView or the
+ * system browser.
+ */
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun LinkReaderScreen(url: String, onBack: () -> Unit, onOpenLink: (String) -> Unit) {
+ val context = LocalContext.current
+ var title by remember(url) { mutableStateOf<String?>(null) }
+ var content by remember(url) { mutableStateOf<String?>(null) }
+ var failed by remember(url) { mutableStateOf(false) }
+
+ LaunchedEffect(url) {
+ val extracted = ReaderExtractor.extract(context, url)
+ val extractedContent = extracted?.content
+ if (extractedContent != null) {
+ title = extracted.title
+ content = extractedContent
+ } else {
+ failed = true
+ }
+ }
+
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = {
+ Text(title ?: Uri.parse(url).host ?: "Article", maxLines = 1, overflow = TextOverflow.Ellipsis)
+ },
+ navigationIcon = {
+ IconButton(onClick = onBack) {
+ Icon(Icons.Default.ArrowBack, contentDescription = "Back")
+ }
+ },
+ actions = {
+ IconButton(onClick = {
+ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
+ }) {
+ Icon(Icons.Default.OpenInBrowser, contentDescription = "Open in browser")
+ }
+ }
+ )
+ }
+ ) { padding ->
+ Box(modifier = Modifier.fillMaxSize().padding(padding)) {
+ val currentContent = content
+ when {
+ currentContent != null -> {
+ val loadedContent = remember(url) { mutableStateOf<String?>(null) }
+ AndroidView(
+ modifier = Modifier.fillMaxSize(),
+ factory = { ctx ->
+ newReaderWebView(ctx, onOpenLink).apply {
+ loadDataWithBaseURL(url, wrapReaderHtml(currentContent), "text/html", "UTF-8", null)
+ loadedContent.value = currentContent
+ }
+ },
+ update = { webView ->
+ if (loadedContent.value != currentContent) {
+ webView.loadDataWithBaseURL(url, wrapReaderHtml(currentContent), "text/html", "UTF-8", null)
+ loadedContent.value = currentContent
+ }
+ },
+ onRelease = { webView -> webView.destroy() }
+ )
+ }
+ failed -> Text(
+ "Couldn't extract a reader view for this page -- try \"Open in browser\" instead.",
+ modifier = Modifier.align(Alignment.Center).padding(24.dp),
+ color = MaterialTheme.colorScheme.onSurfaceVariant
+ )
+ else -> CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
+ }
+ }
+ }
+}