diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9045aed..a9c373a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -91,7 +91,7 @@ dependencies { implementation(libs.compose) - implementation(libs.commons.text) + implementation(libs.kefirbb) implementation(libs.acra.http) } \ No newline at end of file diff --git a/app/src/main/java/ru/sweetbread/unn/ui/API.kt b/app/src/main/java/ru/sweetbread/unn/ui/API.kt index e08986c..7394680 100644 --- a/app/src/main/java/ru/sweetbread/unn/ui/API.kt +++ b/app/src/main/java/ru/sweetbread/unn/ui/API.kt @@ -6,7 +6,6 @@ import io.ktor.client.request.header import io.ktor.client.request.parameter import io.ktor.client.statement.bodyAsText import io.ktor.http.parameters -import org.apache.commons.text.StringEscapeUtils import org.json.JSONArray import org.json.JSONObject import ru.sweetbread.unn.R @@ -267,7 +266,7 @@ suspend fun getBlogposts(): ArrayList { el.getString("DATE_PUBLISH"), DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'+03:00'") ), - content = StringEscapeUtils.escapeHtml4(el.getString("DETAIL_TEXT")) + content = el.getString("DETAIL_TEXT") ) ) } diff --git a/app/src/main/java/ru/sweetbread/unn/ui/composes/Blogpost.kt b/app/src/main/java/ru/sweetbread/unn/ui/composes/Blogpost.kt index 1c7f1b1..b38aa37 100644 --- a/app/src/main/java/ru/sweetbread/unn/ui/composes/Blogpost.kt +++ b/app/src/main/java/ru/sweetbread/unn/ui/composes/Blogpost.kt @@ -1,5 +1,6 @@ package ru.sweetbread.unn.ui.composes +import android.text.util.Linkify import android.util.Log import androidx.compose.foundation.background 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.items import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -27,17 +29,24 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier 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.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview 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.compose.viewModel import coil.compose.AsyncImage +import com.google.android.material.textview.MaterialTextView import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import org.kefirsf.bb.BBProcessorFactory +import org.kefirsf.bb.TextProcessor import ru.sweetbread.unn.R import ru.sweetbread.unn.ui.ImageSet import ru.sweetbread.unn.ui.Post @@ -52,6 +61,7 @@ import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.time.format.FormatStyle + val defUser = User( null, 123, @@ -153,13 +163,16 @@ fun UserItem(modifier: Modifier = Modifier, user: User, info: String? = null) { @NonRestartableComposable fun PostItem(modifier: Modifier = Modifier, post: Post) { var user: User? by remember { mutableStateOf(null) } + val processor = remember { BBProcessorFactory.getInstance().create() } + var html: String by remember { mutableStateOf("") } + LaunchedEffect(post) { + html = toHtml(processor, post) user = getUserByBitrixId(post.authorId) } Column(modifier.padding(16.dp)) { - Log.d("FUUUUUUUUUUUCK", user.toString()) if (user != null) UserItem(user = user!!) else @@ -171,11 +184,43 @@ fun PostItem(modifier: Modifier = Modifier, post: Post) { trackColor = MaterialTheme.colorScheme.secondary, ) - Text(text = post.content) - Text(text = post.date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))) + AndroidView( + 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()) + "${it.groups[2]?.value}" + }.replace("""(\[FONT=.+]|\[CENTER])(.+)(\[/FONT]|\[/CENTER])""".toRegex()) { + it.groups[2]?.value.toString() + }.replace("""\[IMG .+].+\[/IMG]""".toRegex(), "") +} + @Preview @Composable diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 54a3695..4bf3443 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,9 +24,10 @@ lifecycleLivedataKtx = "2.7.0" lifecycleViewmodelKtx = "2.7.0" activity = "1.8.2" navigationCompose = "2.7.7" +richeditorCompose = "1.0.0-rc01" secretsGradlePlugin = "2.0.1" splittiesFunPackAndroidBaseWithViewsDsl = "3.0.0" -commonsText = "1.11.0" +kefirbb = "1.5" [libraries] 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-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" } 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" } 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] androidApplication = { id = "com.android.application", version.ref = "agp" }