mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 12:07:28 +00:00
Pretty print the push rules content before displaying it
The raw push rules returned by the SDK are a single long line of json, which is hard to read on a phone. Re-encode the content with a pretty printer using a two space indentation before handing it to the file viewer. Parsing to a JsonElement and re-encoding preserves the order of the keys, so the rules are still listed in the order the server returned them. Content which cannot be parsed is passed through unchanged, so that a malformed payload remains viewable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -92,6 +92,7 @@ dependencies {
|
||||
implementation(libs.color.picker)
|
||||
implementation(libs.androidx.browser)
|
||||
implementation(libs.androidx.datastore.preferences)
|
||||
implementation(libs.serialization.json)
|
||||
api(projects.features.preferences.api)
|
||||
implementation(libs.showkase)
|
||||
|
||||
|
||||
+20
-1
@@ -32,6 +32,7 @@ import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||
import io.element.android.libraries.core.data.ByteUnit
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase
|
||||
import io.element.android.libraries.matrix.api.core.DeviceId
|
||||
@@ -41,6 +42,9 @@ import kotlinx.collections.immutable.ImmutableMap
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
|
||||
@AssistedInject
|
||||
class DeveloperSettingsPresenter(
|
||||
@@ -190,7 +194,7 @@ class DeveloperSettingsPresenter(
|
||||
pushRulesAction.value = AsyncAction.Uninitialized
|
||||
navigator.openPushRules(
|
||||
filename = pushRulesFilename(),
|
||||
content = content.orEmpty(),
|
||||
content = content.orEmpty().prettyPrintJson(),
|
||||
)
|
||||
}
|
||||
.onFailure {
|
||||
@@ -204,3 +208,18 @@ class DeveloperSettingsPresenter(
|
||||
*/
|
||||
private fun pushRulesFilename() = "push_rules${sessionId.value.replace(':', '_')}.json"
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
private val prettyPrintJson = Json {
|
||||
prettyPrint = true
|
||||
// Keep the indentation small, for a better rendering on mobile.
|
||||
prettyPrintIndent = " "
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty print this json content, so that it is readable when rendered.
|
||||
* Return the content as is if it is not valid json.
|
||||
*/
|
||||
private fun String.prettyPrintJson(): String = runCatchingExceptions {
|
||||
prettyPrintJson.encodeToString(JsonElement.serializer(), prettyPrintJson.parseToJsonElement(this))
|
||||
}.getOrDefault(this)
|
||||
|
||||
+31
-2
@@ -44,7 +44,17 @@ import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
private const val A_PUSH_RULES_CONTENT = "{\"global\":{}}"
|
||||
private const val A_PUSH_RULES_CONTENT = """{"global":{"override":[{"rule_id":".m.rule.master","enabled":false}]}}"""
|
||||
private const val A_PUSH_RULES_CONTENT_PRETTY_PRINTED = """{
|
||||
"global": {
|
||||
"override": [
|
||||
{
|
||||
"rule_id": ".m.rule.master",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}"""
|
||||
private val AN_EXCEPTION = Exception("A failure")
|
||||
|
||||
class DeveloperSettingsPresenterTest {
|
||||
@@ -195,7 +205,26 @@ class DeveloperSettingsPresenterTest {
|
||||
}
|
||||
openPushRulesLambda.assertions().isCalledOnce().with(
|
||||
value("push_rules@alice_server.org.json"),
|
||||
value(A_PUSH_RULES_CONTENT),
|
||||
value(A_PUSH_RULES_CONTENT_PRETTY_PRINTED),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - OpenPushRules event keeps the content as is when it is not valid json`() = runTest {
|
||||
val openPushRulesLambda = lambdaRecorder<String, String, Unit> { _, _ -> }
|
||||
val presenter = createDeveloperSettingsPresenter(
|
||||
navigator = DeveloperSettingsNavigator(openPushRulesLambda),
|
||||
notificationSettingsService = FakeNotificationSettingsService(
|
||||
getRawPushRulesResult = { Result.success("not json") },
|
||||
),
|
||||
)
|
||||
presenter.test {
|
||||
awaitItem().eventSink(DeveloperSettingsEvent.OpenPushRules)
|
||||
skipItems(2)
|
||||
openPushRulesLambda.assertions().isCalledOnce().with(
|
||||
value("push_rules@alice_server.org.json"),
|
||||
value("not json"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user