Skip to content

Commit a540428

Browse files
feat: improve markdown format
1 parent 4e82fef commit a540428

File tree

6 files changed

+100
-17
lines changed

6 files changed

+100
-17
lines changed

app/src/main/java/org/androidlabs/applistbackup/BackupService.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ class BackupService : Service() {
718718
val markdownBuilder = StringBuilder()
719719

720720
markdownBuilder.apply {
721-
append("**${getString(R.string.name_title)}")
721+
append("| ${getString(R.string.name_title)}")
722722
if (!isPackageExcluded) append(" | ${getString(R.string.package_title)}")
723723
if (!isSystemExcluded) append(" | ${getString(R.string.system_title)}")
724724
if (!isEnabledExcluded) append(" | ${getString(R.string.enabled_title)}")
@@ -729,14 +729,22 @@ class BackupService : Service() {
729729
if (!isUpdatedAtExcluded) append(" | ${getString(R.string.updated_at_title)}")
730730
if (!isInstallSourceExcluded) append(" | ${getString(R.string.installer)}")
731731
if (!isLinksExcluded) append(" | ${getString(R.string.links_title)}")
732-
append("**")
732+
append(" |")
733733
appendLine()
734+
}
735+
736+
val linesCount = markdownBuilder.toString().split("|").size - 2
737+
markdownBuilder.apply {
738+
append("|")
739+
repeat(linesCount) {
740+
append(" --- |")
741+
}
734742
appendLine()
735743
}
736744

737745
apps.forEach { app ->
738746
markdownBuilder.apply {
739-
append("**${app.name}**")
747+
append("| **${app.name}**")
740748
if (!isPackageExcluded) append(" | ${app.packageName}")
741749
if (!isSystemExcluded) append(" | ${app.isSystem}")
742750
if (!isEnabledExcluded) append(" | ${app.isEnabled}")
@@ -762,7 +770,7 @@ class BackupService : Service() {
762770
if (!isInstallSourceExcluded) append(" | ${app.installerName}")
763771
if (!isLinksExcluded) append(" | [Play](https://play.google.com/store/apps/details?id=${app.packageName}) | [F-Droid](https://f-droid.org/packages/${app.packageName})")
764772

765-
appendLine()
773+
append(" |")
766774
appendLine()
767775
}
768776
}

app/src/main/java/org/androidlabs/applistbackup/reader/BackupMarkdownView.kt

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
package org.androidlabs.applistbackup.reader
22

3+
import android.annotation.SuppressLint
34
import android.net.Uri
5+
import android.text.Spanned
46
import android.view.ViewGroup
57
import android.widget.TextView
68
import androidx.compose.material3.MaterialTheme
79
import androidx.compose.runtime.Composable
810
import androidx.compose.runtime.LaunchedEffect
911
import androidx.compose.runtime.remember
1012
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.draw.clipToBounds
1114
import androidx.compose.ui.graphics.toArgb
1215
import androidx.compose.ui.platform.LocalContext
1316
import androidx.compose.ui.viewinterop.AndroidView
17+
import androidx.recyclerview.widget.LinearLayoutManager
18+
import androidx.recyclerview.widget.RecyclerView
1419
import io.noties.markwon.AbstractMarkwonPlugin
1520
import io.noties.markwon.Markwon
1621
import io.noties.markwon.core.MarkwonTheme
22+
import io.noties.markwon.recycler.MarkwonAdapter
23+
import org.androidlabs.applistbackup.R
24+
import org.commonmark.ext.gfm.tables.TableBlock
25+
import io.noties.markwon.recycler.table.TableEntry
26+
import io.noties.markwon.recycler.table.TableEntryPlugin
27+
import io.noties.markwon.utils.Dip
28+
import kotlinx.coroutines.Dispatchers
29+
import kotlinx.coroutines.withContext
1730

31+
@SuppressLint("NotifyDataSetChanged")
1832
@Composable
1933
fun BackupMarkdownView(
2034
modifier: Modifier = Modifier,
@@ -26,19 +40,34 @@ fun BackupMarkdownView(
2640
val linkColor = MaterialTheme.colorScheme.primary
2741
val codeBackgroundColor = MaterialTheme.colorScheme.surface
2842

29-
val textView = remember(textColor) {
30-
TextView(context).apply {
43+
val recyclerView = remember(textColor) {
44+
RecyclerView(context).apply {
3145
layoutParams = ViewGroup.LayoutParams(
3246
ViewGroup.LayoutParams.MATCH_PARENT,
3347
ViewGroup.LayoutParams.WRAP_CONTENT
3448
)
35-
setTextIsSelectable(true)
36-
setTextColor(textColor.toArgb())
49+
layoutManager = LinearLayoutManager(context)
50+
51+
val adapter = MarkwonAdapter.builder(R.layout.adapter_node, R.id.textView)
52+
.include<TableBlock>(TableBlock::class.java, TableEntry.create { builder ->
53+
builder.tableLayout(R.layout.adapter_table_block, R.id.table_layout)
54+
builder.textLayoutIsRoot(R.layout.view_table_entry_cell)
55+
})
56+
.build()
57+
58+
this.adapter = adapter
3759
}
3860
}
3961

4062
val markwon = remember(textColor, linkColor, codeBackgroundColor) {
4163
Markwon.builder(context)
64+
.usePlugin(TableEntryPlugin.create { builder ->
65+
val dip = Dip.create(context)
66+
builder.tableCellPadding(dip.toPx(12))
67+
builder.tableBorderWidth(dip.toPx(1))
68+
builder.tableBorderColor(textColor.copy(alpha = 75f / 255f).toArgb())
69+
builder.tableEvenRowBackgroundColor(textColor.copy(alpha = 22f / 255f).toArgb())
70+
})
4271
.usePlugin(object : AbstractMarkwonPlugin() {
4372
override fun configureTheme(builder: MarkwonTheme.Builder) {
4473
builder
@@ -49,6 +78,11 @@ fun BackupMarkdownView(
4978
.listItemColor(textColor.toArgb())
5079
.blockQuoteColor(textColor.toArgb())
5180
}
81+
82+
override fun beforeSetText(textView: TextView, markdown: Spanned) {
83+
textView.setTextColor(textColor.toArgb())
84+
super.beforeSetText(textView, markdown)
85+
}
5286
})
5387
.build()
5488
}
@@ -59,12 +93,16 @@ fun BackupMarkdownView(
5993
stream.bufferedReader().readText()
6094
} ?: return@let
6195

62-
markwon.setMarkdown(textView, markdownContent)
96+
withContext(Dispatchers.Main) {
97+
val adapter = recyclerView.adapter as MarkwonAdapter
98+
adapter.setMarkdown(markwon, markdownContent)
99+
adapter.notifyDataSetChanged()
100+
}
63101
}
64102
}
65103

66104
AndroidView(
67-
factory = { textView },
68-
modifier = modifier
105+
factory = { recyclerView },
106+
modifier = modifier.clipToBounds()
69107
)
70108
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
android:id="@+id/textView"
5+
android:layout_width="match_parent"
6+
android:layout_height="wrap_content"
7+
android:layout_marginLeft="16dip"
8+
android:layout_marginRight="16dip"
9+
android:breakStrategy="simple"
10+
android:hyphenationFrequency="none"
11+
android:lineSpacingExtra="2dip"
12+
android:paddingTop="8dip"
13+
android:paddingBottom="8dip"
14+
android:textSize="16sp"
15+
tools:text="Hello" />
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="wrap_content"
5+
android:clipChildren="false"
6+
android:clipToPadding="false"
7+
android:scrollbarStyle="outsideInset">
8+
9+
<TableLayout
10+
android:id="@+id/table_layout"
11+
android:layout_width="wrap_content"
12+
android:layout_height="wrap_content"
13+
android:stretchColumns="*" />
14+
15+
</HorizontalScrollView>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
android:layout_width="wrap_content"
5+
android:layout_height="wrap_content"
6+
android:textSize="16sp"
7+
tools:text="Table content" />

gradle/libs.versions.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[versions]
22
agp = "8.7.3"
33
kotlin = "2.1.0"
4-
coreKtx = "1.15.0"
4+
coreKtx = "1.16.0"
55
junit = "4.13.2"
66
junitVersion = "1.2.1"
77
espressoCore = "3.6.1"
88
lifecycleRuntimeKtx = "2.8.7"
99
activityCompose = "1.10.1"
10-
composeBom = "2025.03.00"
10+
composeBom = "2025.04.00"
1111
workRuntimeKtx = "2.10.0"
1212
runtimeLivedata = "1.7.8"
1313
taskerPluginLibrary = "0.4.10"
@@ -16,7 +16,7 @@ fragmentKtx = "1.8.6"
1616
navigationRuntimeKtx = "2.8.9"
1717
navigationCompose = "2.8.9"
1818
accompanist = "0.28.0"
19-
datastore = "1.1.3"
19+
datastore = "1.1.4"
2020
markwon = "4.6.2"
2121

2222
[libraries]
@@ -44,11 +44,11 @@ androidx-navigation-compose = { group = "androidx.navigation", name = "navigatio
4444
accompanist-drawablepainter = { group = "com.google.accompanist", name = "accompanist-drawablepainter", version.ref = "accompanist" }
4545
datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" }
4646
markwon-core = { group = "io.noties.markwon", name = "core", version.ref = "markwon" }
47-
markwon-html = { group = "io.noties.markwon", name = "html", version.ref = "markwon" }
48-
markwon-image = { group = "io.noties.markwon", name = "image", version.ref = "markwon" }
47+
markwon-recycler-table = { group = "io.noties.markwon", name = "recycler-table", version.ref = "markwon" }
48+
markwon-recycler = { group = "io.noties.markwon", name = "recycler", version.ref = "markwon" }
4949

5050
[bundles]
51-
markwon = ["markwon-core", "markwon-html", "markwon-image"]
51+
markwon = ["markwon-core", "markwon-recycler-table", "markwon-recycler"]
5252

5353
[plugins]
5454
android-application = { id = "com.android.application", version.ref = "agp" }

0 commit comments

Comments
 (0)