Extract views from ItemScreen
This commit is contained in:
parent
91378f0a54
commit
02a3f82b72
@ -1,12 +1,7 @@
|
||||
package com.readrops.app.compose.item
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.Base64
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -33,12 +28,10 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.painterResource
|
||||
@ -46,15 +39,14 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import coil.compose.AsyncImage
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.app.compose.R
|
||||
import com.readrops.app.compose.util.Utils
|
||||
import com.readrops.app.compose.item.view.ItemNestedScrollView
|
||||
import com.readrops.app.compose.item.view.ItemWebView
|
||||
import com.readrops.app.compose.util.components.AndroidScreen
|
||||
import com.readrops.app.compose.util.components.CenteredProgressIndicator
|
||||
import com.readrops.app.compose.util.components.IconText
|
||||
@ -69,7 +61,6 @@ class ItemScreen(
|
||||
private val itemId: Int
|
||||
) : AndroidScreen() {
|
||||
|
||||
@SuppressLint("ResourceType", "SetJavaScriptEnabled")
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val context = LocalContext.current
|
||||
@ -150,92 +141,44 @@ class ItemScreen(
|
||||
) {
|
||||
AndroidView(
|
||||
factory = { context ->
|
||||
NestedScrollView(context).apply {
|
||||
val treeObserver = viewTreeObserver
|
||||
treeObserver.addOnGlobalLayoutListener {
|
||||
val viewHeight = this.measuredHeight
|
||||
val contentHeight = getChildAt(0).height
|
||||
|
||||
ItemNestedScrollView(
|
||||
context = context,
|
||||
onGlobalLayoutListener = { viewHeight, contentHeight ->
|
||||
isScrollable = viewHeight - contentHeight < 0
|
||||
|
||||
}
|
||||
|
||||
addView(
|
||||
RelativeLayout(context).apply {
|
||||
ViewCompat.setNestedScrollingEnabled(this, true)
|
||||
|
||||
val composeView = ComposeView(context).apply {
|
||||
id = 1
|
||||
|
||||
setContent {
|
||||
if (item.imageLink != null) {
|
||||
BackgroundTitle(
|
||||
itemWithFeed = itemWithFeed
|
||||
)
|
||||
} else {
|
||||
val tintColor =
|
||||
if (itemWithFeed.bgColor != 0) {
|
||||
Color(itemWithFeed.bgColor)
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onBackground
|
||||
}
|
||||
|
||||
SimpleTitle(
|
||||
itemWithFeed = itemWithFeed,
|
||||
titleColor = tintColor,
|
||||
accentColor = tintColor,
|
||||
baseColor = MaterialTheme.colorScheme.onBackground,
|
||||
bottomPadding = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val webView = WebView(context).apply {
|
||||
id = 2
|
||||
ViewCompat.setNestedScrollingEnabled(this, true)
|
||||
|
||||
settings.javaScriptEnabled = true
|
||||
webViewClient = WebViewClient()
|
||||
|
||||
settings.builtInZoomControls = true
|
||||
settings.displayZoomControls = false
|
||||
settings.setSupportZoom(false)
|
||||
|
||||
isVerticalScrollBarEnabled = false
|
||||
setBackgroundColor(backgroundColor.toArgb())
|
||||
}
|
||||
|
||||
val params = RelativeLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
|
||||
params.addRule(RelativeLayout.BELOW, composeView.id)
|
||||
webView.layoutParams = params
|
||||
|
||||
addView(composeView)
|
||||
addView(webView)
|
||||
) {
|
||||
if (item.imageLink != null) {
|
||||
BackgroundTitle(
|
||||
itemWithFeed = itemWithFeed
|
||||
)
|
||||
} else {
|
||||
val tintColor = if (itemWithFeed.bgColor != 0) {
|
||||
Color(itemWithFeed.bgColor)
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onBackground
|
||||
}
|
||||
)
|
||||
|
||||
SimpleTitle(
|
||||
itemWithFeed = itemWithFeed,
|
||||
titleColor = tintColor,
|
||||
accentColor = tintColor,
|
||||
baseColor = MaterialTheme.colorScheme.onBackground,
|
||||
bottomPadding = true
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
update = { nestedScrollView ->
|
||||
val relativeLayout =
|
||||
(nestedScrollView.children.toList()[0] as RelativeLayout)
|
||||
val webView = relativeLayout.children.toList()[1] as WebView
|
||||
val webView = relativeLayout.children.toList()[1] as ItemWebView
|
||||
|
||||
val string = context.getString(
|
||||
R.string.webview_html_template,
|
||||
Utils.getCssColor(accentColor.toArgb()),
|
||||
Utils.getCssColor(onBackgroundColor.toArgb()),
|
||||
Utils.getCssColor(backgroundColor.toArgb()),
|
||||
screenModel.formatText()
|
||||
webView.loadText(
|
||||
itemWithFeed = itemWithFeed,
|
||||
accentColor = accentColor,
|
||||
backgroundColor = backgroundColor,
|
||||
onBackgroundColor = onBackgroundColor
|
||||
)
|
||||
val data =
|
||||
Base64.encodeToString(string.encodeToByteArray(), Base64.NO_PADDING)
|
||||
|
||||
webView.loadData(data, "text/html; charset=utf-8", "base64")
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -326,7 +269,8 @@ fun SimpleTitle(
|
||||
Text(
|
||||
text = itemWithFeed.feedName,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = baseColor
|
||||
color = baseColor,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
ShortSpacer()
|
||||
|
@ -0,0 +1,63 @@
|
||||
package com.readrops.app.compose.item.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.widget.NestedScrollView
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
class ItemNestedScrollView(
|
||||
context: Context,
|
||||
onGlobalLayoutListener: (viewHeight: Int, contentHeight: Int) -> Unit,
|
||||
composeViewContent: @Composable () -> Unit
|
||||
) : NestedScrollView(context) {
|
||||
|
||||
init {
|
||||
addView(
|
||||
RelativeLayout(context).apply {
|
||||
ViewCompat.setNestedScrollingEnabled(this, true)
|
||||
|
||||
val composeView = ComposeView(context).apply {
|
||||
id = 1
|
||||
|
||||
setContent {
|
||||
composeViewContent()
|
||||
}
|
||||
}
|
||||
|
||||
val composeViewParams = RelativeLayout.LayoutParams(
|
||||
LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
composeViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL)
|
||||
composeView.layoutParams = composeViewParams
|
||||
|
||||
val webView = ItemWebView(context).apply {
|
||||
id = 2
|
||||
ViewCompat.setNestedScrollingEnabled(this, true)
|
||||
}
|
||||
|
||||
val webViewParams = RelativeLayout.LayoutParams(
|
||||
LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
|
||||
webViewParams.addRule(RelativeLayout.BELOW, composeView.id)
|
||||
webView.layoutParams = webViewParams
|
||||
|
||||
addView(composeView)
|
||||
addView(webView)
|
||||
}
|
||||
)
|
||||
|
||||
viewTreeObserver.addOnGlobalLayoutListener {
|
||||
val viewHeight = this.measuredHeight
|
||||
val contentHeight = getChildAt(0).height
|
||||
|
||||
onGlobalLayoutListener(viewHeight, contentHeight)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.readrops.app.compose.item.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Base64
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import com.readrops.app.compose.R
|
||||
import com.readrops.app.compose.util.Utils
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.parser.Parser
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
class ItemWebView(
|
||||
context: Context,
|
||||
attrs: AttributeSet?,
|
||||
) : WebView(context, attrs) {
|
||||
|
||||
constructor(context: Context): this(context, null)
|
||||
|
||||
init {
|
||||
settings.javaScriptEnabled = true
|
||||
settings.builtInZoomControls = true
|
||||
settings.displayZoomControls = false
|
||||
settings.setSupportZoom(false)
|
||||
|
||||
webViewClient = WebViewClient()
|
||||
isVerticalScrollBarEnabled = false
|
||||
}
|
||||
|
||||
fun loadText(
|
||||
itemWithFeed: ItemWithFeed,
|
||||
accentColor: Color,
|
||||
backgroundColor: Color,
|
||||
onBackgroundColor: Color
|
||||
) {
|
||||
val string = context.getString(
|
||||
R.string.webview_html_template,
|
||||
Utils.getCssColor(accentColor.toArgb()),
|
||||
Utils.getCssColor(onBackgroundColor.toArgb()),
|
||||
Utils.getCssColor(backgroundColor.toArgb()),
|
||||
formatText(itemWithFeed)
|
||||
)
|
||||
|
||||
val data = Base64.encodeToString(string.encodeToByteArray(), Base64.NO_PADDING)
|
||||
loadData(data, "text/html; charset=utf-8", "base64")
|
||||
}
|
||||
|
||||
private fun formatText(itemWithFeed: ItemWithFeed): String {
|
||||
return if (itemWithFeed.item.content != null) {
|
||||
val document = if (itemWithFeed.websiteUrl != null) Jsoup.parse(
|
||||
Parser.unescapeEntities(itemWithFeed.item.text, false), itemWithFeed.websiteUrl
|
||||
) else Jsoup.parse(
|
||||
Parser.unescapeEntities(itemWithFeed.item.text, false)
|
||||
)
|
||||
|
||||
document.select("div,span").forEach { it.clearAttributes() }
|
||||
return document.body().html()
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user