feat(blogs): Add markup

This commit is contained in:
sweetbread 2024-03-23 12:48:59 +03:00
parent 040474cc1d
commit 54602be9dd
4 changed files with 54 additions and 8 deletions

View File

@ -91,7 +91,7 @@ dependencies {
implementation(libs.compose) implementation(libs.compose)
implementation(libs.commons.text) implementation(libs.kefirbb)
implementation(libs.acra.http) implementation(libs.acra.http)
} }

View File

@ -6,7 +6,6 @@ import io.ktor.client.request.header
import io.ktor.client.request.parameter import io.ktor.client.request.parameter
import io.ktor.client.statement.bodyAsText import io.ktor.client.statement.bodyAsText
import io.ktor.http.parameters import io.ktor.http.parameters
import org.apache.commons.text.StringEscapeUtils
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import ru.sweetbread.unn.R import ru.sweetbread.unn.R
@ -267,7 +266,7 @@ suspend fun getBlogposts(): ArrayList<Post> {
el.getString("DATE_PUBLISH"), el.getString("DATE_PUBLISH"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'+03:00'") DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'+03:00'")
), ),
content = StringEscapeUtils.escapeHtml4(el.getString("DETAIL_TEXT")) content = el.getString("DETAIL_TEXT")
) )
) )
} }

View File

@ -1,5 +1,6 @@
package ru.sweetbread.unn.ui.composes package ru.sweetbread.unn.ui.composes
import android.text.util.Linkify
import android.util.Log import android.util.Log
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -12,6 +13,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
@ -27,17 +29,24 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.google.android.material.textview.MaterialTextView
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import org.kefirsf.bb.BBProcessorFactory
import org.kefirsf.bb.TextProcessor
import ru.sweetbread.unn.R import ru.sweetbread.unn.R
import ru.sweetbread.unn.ui.ImageSet import ru.sweetbread.unn.ui.ImageSet
import ru.sweetbread.unn.ui.Post import ru.sweetbread.unn.ui.Post
@ -52,6 +61,7 @@ import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle import java.time.format.FormatStyle
val defUser = User( val defUser = User(
null, null,
123, 123,
@ -153,13 +163,16 @@ fun UserItem(modifier: Modifier = Modifier, user: User, info: String? = null) {
@NonRestartableComposable @NonRestartableComposable
fun PostItem(modifier: Modifier = Modifier, post: Post) { fun PostItem(modifier: Modifier = Modifier, post: Post) {
var user: User? by remember { mutableStateOf(null) } var user: User? by remember { mutableStateOf(null) }
val processor = remember { BBProcessorFactory.getInstance().create() }
var html: String by remember { mutableStateOf("") }
LaunchedEffect(post) { LaunchedEffect(post) {
html = toHtml(processor, post)
user = getUserByBitrixId(post.authorId) user = getUserByBitrixId(post.authorId)
} }
Column(modifier.padding(16.dp)) { Column(modifier.padding(16.dp)) {
Log.d("FUUUUUUUUUUUCK", user.toString())
if (user != null) if (user != null)
UserItem(user = user!!) UserItem(user = user!!)
else else
@ -171,9 +184,41 @@ fun PostItem(modifier: Modifier = Modifier, post: Post) {
trackColor = MaterialTheme.colorScheme.secondary, trackColor = MaterialTheme.colorScheme.secondary,
) )
Text(text = post.content) AndroidView(
Text(text = post.date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))) factory = {
MaterialTextView(it).apply {
autoLinkMask = Linkify.WEB_URLS
linksClickable = true
setLinkTextColor(Color.White.toArgb())
} }
},
update = {
it.maxLines = 25
it.text = HtmlCompat.fromHtml(html, 0)
}
)
HorizontalDivider(
modifier = Modifier.padding(vertical = 16.dp),
thickness = 1.dp,
color = MaterialTheme.colorScheme.onBackground
)
Text(text = post.date.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)))
}
}
private fun toHtml(
processor: TextProcessor,
post: Post
): String {
val html = processor.process(post.content)
return html.replace("""\[URL=(.+)](.+)\[/URL]""".toRegex()) {
Log.d("replace", it.groups.toString())
"<a href='${it.groups[1]?.value}'>${it.groups[2]?.value}</a>"
}.replace("""(\[FONT=.+]|\[CENTER])(.+)(\[/FONT]|\[/CENTER])""".toRegex()) {
it.groups[2]?.value.toString()
}.replace("""\[IMG .+].+\[/IMG]""".toRegex(), "")
} }

View File

@ -24,9 +24,10 @@ lifecycleLivedataKtx = "2.7.0"
lifecycleViewmodelKtx = "2.7.0" lifecycleViewmodelKtx = "2.7.0"
activity = "1.8.2" activity = "1.8.2"
navigationCompose = "2.7.7" navigationCompose = "2.7.7"
richeditorCompose = "1.0.0-rc01"
secretsGradlePlugin = "2.0.1" secretsGradlePlugin = "2.0.1"
splittiesFunPackAndroidBaseWithViewsDsl = "3.0.0" splittiesFunPackAndroidBaseWithViewsDsl = "3.0.0"
commonsText = "1.11.0" kefirbb = "1.5"
[libraries] [libraries]
acra-http = { module = "ch.acra:acra-http", version.ref = "acraHttp" } acra-http = { module = "ch.acra:acra-http", version.ref = "acraHttp" }
@ -59,9 +60,10 @@ androidx-constraintlayout = { group = "androidx.constraintlayout", name = "const
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" } androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" } androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
richeditor-compose = { module = "com.mohamedrejeb.richeditor:richeditor-compose", version.ref = "richeditorCompose" }
secrets-gradle-plugin = { module = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin", version.ref = "secretsGradlePlugin" } secrets-gradle-plugin = { module = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin", version.ref = "secretsGradlePlugin" }
splitties-funpack-android-base-with-views-dsl = { module = "com.louiscad.splitties:splitties-fun-pack-android-base-with-views-dsl", version.ref = "splittiesFunPackAndroidBaseWithViewsDsl" } splitties-funpack-android-base-with-views-dsl = { module = "com.louiscad.splitties:splitties-fun-pack-android-base-with-views-dsl", version.ref = "splittiesFunPackAndroidBaseWithViewsDsl" }
commons-text = { group = "org.apache.commons", name = "commons-text", version.ref = "commonsText" } kefirbb = { group = "org.kefirsf", name = "kefirbb", version.ref = "kefirbb" }
[plugins] [plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" } androidApplication = { id = "com.android.application", version.ref = "agp" }