feat(jbm): ast inspector
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
c8cb3c4aff
commit
420fba2c45
|
|
@ -20,7 +20,8 @@ fun SheetButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
supportingContent: @Composable (() -> Unit)? = null,
|
supportingContent: @Composable (() -> Unit)? = null,
|
||||||
trailingContent: @Composable (() -> Unit)? = null,
|
trailingContent: @Composable (() -> Unit)? = null,
|
||||||
dangerous: Boolean = false
|
dangerous: Boolean = false,
|
||||||
|
special: Boolean = false
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|
@ -33,6 +34,8 @@ fun SheetButton(
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
value = if (dangerous) {
|
value = if (dangerous) {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.error
|
LocalContentColor provides MaterialTheme.colorScheme.error
|
||||||
|
} else if (special) {
|
||||||
|
LocalContentColor provides MaterialTheme.colorScheme.primary
|
||||||
} else {
|
} else {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +47,8 @@ fun SheetButton(
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
value = if (dangerous) {
|
value = if (dangerous) {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.error
|
LocalContentColor provides MaterialTheme.colorScheme.error
|
||||||
|
} else if (special) {
|
||||||
|
LocalContentColor provides MaterialTheme.colorScheme.primary
|
||||||
} else {
|
} else {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +61,8 @@ fun SheetButton(
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
value = if (dangerous) {
|
value = if (dangerous) {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.error
|
LocalContentColor provides MaterialTheme.colorScheme.error
|
||||||
|
} else if (special) {
|
||||||
|
LocalContentColor provides MaterialTheme.colorScheme.primary
|
||||||
} else {
|
} else {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
||||||
}
|
}
|
||||||
|
|
@ -69,6 +76,8 @@ fun SheetButton(
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
value = if (dangerous) {
|
value = if (dangerous) {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.error
|
LocalContentColor provides MaterialTheme.colorScheme.error
|
||||||
|
} else if (special) {
|
||||||
|
LocalContentColor provides MaterialTheme.colorScheme.primary
|
||||||
} else {
|
} else {
|
||||||
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
LocalContentColor provides MaterialTheme.colorScheme.onSurface
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
package chat.revolt.sheets
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.drawBehind
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import chat.revolt.components.generic.SheetHeaderPadding
|
||||||
|
import chat.revolt.markdown.jbm.JBM
|
||||||
|
import chat.revolt.markdown.jbm.JBMApi
|
||||||
|
import org.intellij.markdown.ast.ASTNode
|
||||||
|
import org.intellij.markdown.ast.getTextInNode
|
||||||
|
|
||||||
|
@OptIn(JBM::class)
|
||||||
|
@Composable
|
||||||
|
fun JBMDebuggerSheet(content: String, modifier: Modifier = Modifier) {
|
||||||
|
val rendered = remember(content) { JBMApi.parse(content) }
|
||||||
|
Column {
|
||||||
|
SheetHeaderPadding {
|
||||||
|
Text(
|
||||||
|
text = "Inspect AST",
|
||||||
|
style = MaterialTheme.typography.headlineSmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(modifier.verticalScroll(rememberScrollState())) {
|
||||||
|
JBMDebugTree(rendered, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun JBMDebugTree(node: ASTNode, source: String, modifier: Modifier = Modifier) {
|
||||||
|
var showChildren by remember { mutableStateOf(false) }
|
||||||
|
val scheme = MaterialTheme.colorScheme
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier
|
||||||
|
.padding(start = 16.dp)
|
||||||
|
.clickable { showChildren = !showChildren }) {
|
||||||
|
JBMDebugNode(node, source, showChildren)
|
||||||
|
if (showChildren && node.children.isNotEmpty()) {
|
||||||
|
Column(Modifier.drawBehind {
|
||||||
|
drawLine(
|
||||||
|
color = scheme.primary,
|
||||||
|
start = Offset(0f, 0f),
|
||||||
|
end = Offset(0f, size.height),
|
||||||
|
strokeWidth = 2.dp.toPx()
|
||||||
|
)
|
||||||
|
}) {
|
||||||
|
node.children.forEach { JBMDebugTree(it, source) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
|
@Composable
|
||||||
|
fun JBMDebugNode(node: ASTNode, source: String, showingChildren: Boolean) {
|
||||||
|
Column {
|
||||||
|
FlowRow {
|
||||||
|
if (node.children.isNotEmpty()) {
|
||||||
|
Text(if (showingChildren) "▼ " else "▶ ")
|
||||||
|
}
|
||||||
|
Text(node.type.toString())
|
||||||
|
Text(" - ")
|
||||||
|
if (node.children.isNotEmpty()) {
|
||||||
|
Text("${node.children.size} " + if (node.children.size == 1) "child" else "children")
|
||||||
|
} else {
|
||||||
|
Text("No children")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val text = try {
|
||||||
|
node.getTextInNode(source)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
"<exception>"
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text.take(50).toString() + if (text.length > 50) "…" else "",
|
||||||
|
color = if (text == "<exception>") MaterialTheme.colorScheme.error else LocalContentColor.current,
|
||||||
|
modifier = Modifier.padding(4.dp)
|
||||||
|
)
|
||||||
|
HorizontalDivider(
|
||||||
|
Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,6 +36,7 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import chat.revolt.BuildConfig
|
||||||
import chat.revolt.R
|
import chat.revolt.R
|
||||||
import chat.revolt.api.REVOLT_APP
|
import chat.revolt.api.REVOLT_APP
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
|
|
@ -44,6 +45,7 @@ import chat.revolt.api.internals.Roles
|
||||||
import chat.revolt.api.internals.has
|
import chat.revolt.api.internals.has
|
||||||
import chat.revolt.api.routes.channel.deleteMessage
|
import chat.revolt.api.routes.channel.deleteMessage
|
||||||
import chat.revolt.api.routes.channel.react
|
import chat.revolt.api.routes.channel.react
|
||||||
|
import chat.revolt.api.settings.Experiments
|
||||||
import chat.revolt.callbacks.UiCallbacks
|
import chat.revolt.callbacks.UiCallbacks
|
||||||
import chat.revolt.components.chat.Message
|
import chat.revolt.components.chat.Message
|
||||||
import chat.revolt.components.generic.SheetButton
|
import chat.revolt.components.generic.SheetButton
|
||||||
|
|
@ -76,6 +78,9 @@ fun MessageContextSheet(
|
||||||
var showShareSheet by remember { mutableStateOf(false) }
|
var showShareSheet by remember { mutableStateOf(false) }
|
||||||
var showReactSheet by remember { mutableStateOf(false) }
|
var showReactSheet by remember { mutableStateOf(false) }
|
||||||
var showDeleteMessageConfirmation by remember { mutableStateOf(false) }
|
var showDeleteMessageConfirmation by remember { mutableStateOf(false) }
|
||||||
|
var showInspectASTSheet by remember { mutableStateOf(false) }
|
||||||
|
val showInspectASTSheetButton =
|
||||||
|
BuildConfig.DEBUG || (message.content != null && Experiments.useKotlinBasedMarkdownRenderer.isEnabled)
|
||||||
|
|
||||||
if (showShareSheet) {
|
if (showShareSheet) {
|
||||||
val shareSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
val shareSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
|
|
@ -305,6 +310,19 @@ fun MessageContextSheet(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showInspectASTSheet) {
|
||||||
|
val inspectASTSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
|
|
||||||
|
ModalBottomSheet(
|
||||||
|
sheetState = inspectASTSheetState,
|
||||||
|
onDismissRequest = {
|
||||||
|
showInspectASTSheet = false
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
JBMDebuggerSheet(message.content ?: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
|
|
@ -407,6 +425,26 @@ fun MessageContextSheet(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (showInspectASTSheetButton) {
|
||||||
|
SheetButton(
|
||||||
|
leadingContent = {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_file_tree_24dp),
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
},
|
||||||
|
headlineContent = {
|
||||||
|
Text(
|
||||||
|
text = "Inspect AST"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
showInspectASTSheet = true
|
||||||
|
},
|
||||||
|
special = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
SheetButton(
|
SheetButton(
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#ffffff"
|
||||||
|
android:pathData="M3,3H9V7H3V3M15,10H21V14H15V10M15,17H21V21H15V17M13,13H7V18H13V20H7L5,20V9H7V11H13V13Z" />
|
||||||
|
</vector>
|
||||||
Loading…
Reference in New Issue