Skip to content

Commit 31f18f5

Browse files
committed
support colored descriptions and terminal logs
colored descriptions can only used with config.json in the module root
1 parent e01c3ce commit 31f18f5

File tree

4 files changed

+129
-15
lines changed

4 files changed

+129
-15
lines changed

app/src/main/kotlin/com/dergoogler/mmrl/ui/screens/modules/ModuleItem.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import androidx.compose.ui.graphics.StrokeCap
3838
import androidx.compose.ui.platform.LocalContext
3939
import androidx.compose.ui.res.painterResource
4040
import androidx.compose.ui.res.stringResource
41+
import androidx.compose.ui.text.AnnotatedString
4142
import androidx.compose.ui.text.style.TextAlign
4243
import androidx.compose.ui.text.style.TextDecoration
4344
import androidx.compose.ui.text.style.TextOverflow
@@ -56,6 +57,7 @@ import com.dergoogler.mmrl.ui.component.card.CardDefaults.cardStyle
5657
import com.dergoogler.mmrl.ui.providable.LocalUserPreferences
5758
import com.dergoogler.mmrl.ext.nullable
5859
import com.dergoogler.mmrl.ext.takeTrue
60+
import com.dergoogler.mmrl.ext.toStyleMarkup
5961
import com.dergoogler.mmrl.platform.content.LocalModule.Companion.config
6062
import com.dergoogler.mmrl.platform.content.LocalModule.Companion.hasWebUI
6163
import com.dergoogler.mmrl.platform.file.SuFile
@@ -193,11 +195,17 @@ fun ModuleItem(
193195
switch?.invoke()
194196
}
195197

198+
val description = if (module.config.description != null) {
199+
module.config.description!!.toStyleMarkup()
200+
} else {
201+
AnnotatedString(module.description)
202+
}
203+
196204
Text(
197205
modifier = Modifier
198206
.alpha(alpha = alpha)
199207
.padding(horizontal = 16.dp),
200-
text = module.config.description ?: module.description,
208+
text = description,
201209
style = MaterialTheme.typography.bodySmall,
202210
maxLines = 5,
203211
overflow = TextOverflow.Ellipsis,

app/src/main/res/values/strings_terminal.xml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@
66
<string name="installation_aborted_due_to_an_error">! Installation aborted due to an error</string>
77
<string name="install_view_path">- Path: %1$s</string>
88
<string name="copying_zip_to_temp_directory">- Copying zip to temp directory</string>
9-
<string name="install_view_module_info">- Module info: %1$s</string>
9+
<string name="install_view_module_info">- Module info: [underline]%1$s</string>
1010
<string name="copying_failed">! Copying failed</string>
1111
<string name="unable_to_gather_module_info">! Unable to gather module info</string>
12-
<string name="install_view_installing">- Installing %1$s</string>
13-
<string name="module_not_found">! Module not found.</string>
12+
<string name="install_view_installing">- Installing [color=primary]%1$s</string>
13+
<string name="module_not_found">[color=error]! Module not found.</string>
1414
<string name="this_module_don_t_have_an_action">! This module don\'t have an action.</string>
1515
<string name="module_is_disabled_or_removed_unable_to_execute_action">! Module is disabled or removed. Unable to execute action.</string>
1616
<string name="execution_failed_try_to_use_shell_for_the_action_execution_settings_module_use_shell_for_module_action">- Execution failed. Try to use Shell for the Action execution, Settings → Module → Use Shell for Module Action.</string>
17-
<string name="unable_to_find_path_for_uri">! Unable to find path for uri: %1$s</string>
17+
<string name="unable_to_find_path_for_uri">[color=error]! Unable to find path for uri: %1$s</string>
1818
<string name="is_not_a_module_file_magisk_modules_must_be_zip_files_skipping">! %1$s is not a module file. Magisk modules must be .zip files. Skipping...</string>
1919
<string name="removed_updated_folder">- Removed updated folder</string>
20-
<string name="failed_to_remove_updated_folder">! Failed to remove updated folder</string>
21-
<string name="non_root_platform_is_not_supported">! Unrooted platforms are not supported</string>
20+
<string name="failed_to_remove_updated_folder">[color=error]! Failed to remove updated folder</string>
21+
<string name="non_root_platform_is_not_supported">[color=error]! Unrooted platforms are not supported</string>
2222
<string name="module_manager_is_null">! Module manager is null</string>
2323
<string name="file_manager_is_null">! File manager is null</string>
24-
<string name="waiting_for_platformmanager_to_initialize">- Waiting for PlatformManager to initialize...</string>
25-
<string name="failed_to_initialize_platform">! Failed to initialize Platform</string>
26-
<string name="platform_initialized">- Platform initialized</string>
27-
<string name="platform_initialization_failed_cannot_install">! Platform initialization failed. Cannot proceed with installation.</string>
28-
<string name="platform_not_alive_cannot_install">! Platform is not active. Cannot proceed with installation.</string>
24+
<string name="waiting_for_platformmanager_to_initialize">[bold]- Waiting for PlatformManager to initialize</string>
25+
<string name="failed_to_initialize_platform">[color=error]! Failed to initialize Platform</string>
26+
<string name="platform_initialized">[bold]- Platform initialized</string>
27+
<string name="platform_initialization_failed_cannot_install">[color=error]! Platform initialization failed. Cannot proceed with installation.</string>
28+
<string name="platform_not_alive_cannot_install">[color=error]! Platform is not active. Cannot proceed with installation.</string>
2929
<string name="deleted_zip_file">- Deleted ZIP file: %s</string>
3030
</resources>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.dergoogler.mmrl.ext
2+
3+
import androidx.compose.material3.MaterialTheme
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.ui.graphics.Color
6+
import androidx.compose.ui.text.AnnotatedString
7+
import androidx.compose.ui.text.SpanStyle
8+
import androidx.compose.ui.text.font.FontStyle
9+
import androidx.compose.ui.text.font.FontWeight
10+
import androidx.compose.ui.text.style.TextDecoration
11+
12+
@Composable
13+
fun String.toStyleMarkup(): AnnotatedString {
14+
val builder = AnnotatedString.Builder()
15+
val regex = Regex("""\[(color|bg|bold|italic|underline)(=([^]]+))?]""")
16+
17+
var lastIndex = 0
18+
var currentColor: Color? = null
19+
var currentBg: Color? = null
20+
var isBold = false
21+
var isItalic = false
22+
var isUnderline = false
23+
24+
regex.findAll(this).forEach { match ->
25+
val start = match.range.first
26+
27+
if (lastIndex < start) {
28+
builder.append(
29+
AnnotatedString(
30+
this.substring(lastIndex, start),
31+
spanStyle = SpanStyle(
32+
color = currentColor ?: Color.Unspecified,
33+
background = currentBg ?: Color.Unspecified,
34+
fontWeight = if (isBold) FontWeight.Bold else null,
35+
fontStyle = if (isItalic) FontStyle.Italic else null,
36+
textDecoration = if (isUnderline) TextDecoration.Underline else null
37+
)
38+
)
39+
)
40+
}
41+
42+
// Parse tag
43+
when (match.groupValues[1]) {
44+
"color" -> currentColor = colorFromName(match.groupValues[3])
45+
"bg" -> currentBg = colorFromName(match.groupValues[3])
46+
"bold" -> isBold = true
47+
"italic" -> isItalic = true
48+
"underline" -> isUnderline = true
49+
}
50+
51+
lastIndex = match.range.last + 1
52+
}
53+
54+
// Remaining text
55+
if (lastIndex < this.length) {
56+
builder.append(
57+
AnnotatedString(
58+
this.substring(lastIndex),
59+
spanStyle = SpanStyle(
60+
color = currentColor ?: Color.Unspecified,
61+
background = currentBg ?: Color.Unspecified,
62+
fontWeight = if (isBold) FontWeight.Bold else null,
63+
fontStyle = if (isItalic) FontStyle.Italic else null,
64+
textDecoration = if (isUnderline) TextDecoration.Underline else null
65+
)
66+
)
67+
)
68+
}
69+
70+
return builder.toAnnotatedString()
71+
}
72+
73+
@Composable
74+
fun colorFromName(name: String?): Color {
75+
return when (name?.lowercase()) {
76+
"black" -> Color.Black
77+
"red" -> Color.Red
78+
"green" -> Color.Green
79+
"yellow" -> Color.Yellow
80+
"blue" -> Color.Blue
81+
"magenta" -> Color.Magenta
82+
"cyan" -> Color.Cyan
83+
"white" -> Color.White
84+
"gray", "grey" -> Color.Gray
85+
"lightgray" -> Color.LightGray
86+
"primary" -> MaterialTheme.colorScheme.primary
87+
"secondary" -> MaterialTheme.colorScheme.secondary
88+
"tertiary" -> MaterialTheme.colorScheme.tertiary
89+
"background" -> MaterialTheme.colorScheme.background
90+
"surface" -> MaterialTheme.colorScheme.surface
91+
"error" -> MaterialTheme.colorScheme.error
92+
"outline" -> MaterialTheme.colorScheme.outline
93+
"inverse_surface" -> MaterialTheme.colorScheme.inverseSurface
94+
"inverse_on_surface" -> MaterialTheme.colorScheme.inverseOnSurface
95+
"inverse_primary" -> MaterialTheme.colorScheme.inversePrimary
96+
"surface_variant" -> MaterialTheme.colorScheme.surfaceVariant
97+
"on_surface_variant" -> MaterialTheme.colorScheme.onSurfaceVariant
98+
"surface_tint" -> MaterialTheme.colorScheme.surfaceTint
99+
"on_surface" -> MaterialTheme.colorScheme.onSurface
100+
"on_primary" -> MaterialTheme.colorScheme.onPrimary
101+
"on_secondary" -> MaterialTheme.colorScheme.onSecondary
102+
"on_tertiary" -> MaterialTheme.colorScheme.onTertiary
103+
"on_background" -> MaterialTheme.colorScheme.onBackground
104+
"on_error" -> MaterialTheme.colorScheme.onError
105+
else -> Color.Unspecified
106+
}
107+
}

ui/src/main/kotlin/com/dergoogler/mmrl/ui/component/Console.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.dergoogler.mmrl.ui.component
22

33
import androidx.compose.foundation.background
4-
import androidx.compose.foundation.border
54
import androidx.compose.foundation.horizontalScroll
65
import androidx.compose.foundation.hoverable
76
import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -11,7 +10,6 @@ import androidx.compose.foundation.layout.padding
1110
import androidx.compose.foundation.layout.width
1211
import androidx.compose.foundation.lazy.LazyColumn
1312
import androidx.compose.foundation.lazy.LazyListState
14-
import androidx.compose.foundation.lazy.items
1513
import androidx.compose.foundation.lazy.itemsIndexed
1614
import androidx.compose.foundation.rememberScrollState
1715
import androidx.compose.foundation.text.selection.DisableSelection
@@ -28,6 +26,7 @@ import androidx.compose.ui.graphics.Color
2826
import androidx.compose.ui.text.TextStyle
2927
import androidx.compose.ui.text.font.FontFamily
3028
import androidx.compose.ui.unit.dp
29+
import com.dergoogler.mmrl.ext.toStyleMarkup
3130

3231
@Composable
3332
fun Console(
@@ -82,7 +81,7 @@ fun Console(
8281
}
8382

8483
Text(
85-
text = item,
84+
text = item.toStyleMarkup(),
8685
color = style.color,
8786
style = style
8887
)

0 commit comments

Comments
 (0)