From feed0ada86988cfcdbff0cb6078f2dcfd7ed5bc6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 26 Jan 2024 11:42:21 +0100 Subject: [PATCH] FileViewer: fix coloration issue for logs files. --- .../viewfolder/impl/file/ViewFilePresenter.kt | 10 +++++ .../viewfolder/impl/file/ViewFileState.kt | 7 ++++ .../impl/file/ViewFileStateProvider.kt | 1 + .../viewfolder/impl/file/ViewFileView.kt | 42 ++++++++++++++----- .../test/file/ViewFilePresenterTest.kt | 26 ++++++++++++ 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFilePresenter.kt b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFilePresenter.kt index 91cc59ec05..0337d9044a 100644 --- a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFilePresenter.kt +++ b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFilePresenter.kt @@ -49,6 +49,7 @@ class ViewFilePresenter @AssistedInject constructor( @Composable override fun present(): ViewFileState { val coroutineScope = rememberCoroutineScope() + val colorationMode = remember { name.toColorationMode() } fun handleEvent(event: ViewFileEvents) { when (event) { @@ -67,6 +68,7 @@ class ViewFilePresenter @AssistedInject constructor( return ViewFileState( name = name, lines = lines, + colorationMode = colorationMode, eventSink = ::handleEvent, ) } @@ -79,3 +81,11 @@ class ViewFilePresenter @AssistedInject constructor( fileSave.save(path) } } + +private fun String.toColorationMode(): ColorationMode { + return when { + equals("logcat.log") -> ColorationMode.Logcat + startsWith("logs.") -> ColorationMode.Logs + else -> ColorationMode.None + } +} diff --git a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileState.kt b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileState.kt index 9fb531c478..8529655139 100644 --- a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileState.kt +++ b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileState.kt @@ -21,5 +21,12 @@ import io.element.android.libraries.architecture.AsyncData data class ViewFileState( val name: String, val lines: AsyncData>, + val colorationMode: ColorationMode, val eventSink: (ViewFileEvents) -> Unit, ) + +enum class ColorationMode { + Logcat, + Logs, + None, +} diff --git a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileStateProvider.kt b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileStateProvider.kt index f0612c0714..9859528511 100644 --- a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileStateProvider.kt +++ b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileStateProvider.kt @@ -51,5 +51,6 @@ fun aViewFileState( ) = ViewFileState( name = name, lines = lines, + colorationMode = ColorationMode.Logcat, eventSink = {}, ) diff --git a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileView.kt b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileView.kt index f58f5399d7..eea8f64b6e 100644 --- a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileView.kt +++ b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/ViewFileView.kt @@ -114,6 +114,7 @@ fun ViewFileView( is AsyncData.Success -> FileContent( modifier = Modifier.weight(1f), lines = state.lines.data.toImmutableList(), + colorationMode = state.colorationMode, ) is AsyncData.Failure -> AsyncFailure(throwable = state.lines.error, onRetry = null) } @@ -125,6 +126,7 @@ fun ViewFileView( @Composable private fun FileContent( lines: ImmutableList, + colorationMode: ColorationMode, modifier: Modifier = Modifier, ) { LazyColumn( @@ -147,6 +149,7 @@ private fun FileContent( LineRow( lineNumber = index + 1, line = line, + colorationMode = colorationMode, ) } } @@ -157,6 +160,7 @@ private fun FileContent( private fun LineRow( lineNumber: Int, line: String, + colorationMode: ColorationMode, ) { val context = LocalContext.current Row( @@ -195,25 +199,41 @@ private fun LineRow( } .padding(horizontal = 4.dp), text = line, - color = line.toColor(), + color = line.toColor(colorationMode), style = ElementTheme.typography.fontBodyMdRegular ) } } /** - * Convert a logcat line to a color. - * Ex: `01-23 13:14:50.740 25818 25818 D org.matrix.rust.sdk: elementx: SyncIndicator = Hide | RustRoomListService.kt:81` + * Convert a line to a color. + * Ex for logcat: + * `01-23 13:14:50.740 25818 25818 D org.matrix.rust.sdk: elementx: SyncIndicator = Hide | RustRoomListService.kt:81` + * ^ use this char to determine the color + * Ex for logs: + * `2024-01-26T10:22:26.947416Z WARN elementx: Restore with non-empty map | MatrixClientsHolder.kt:68` + * ^ use this char to determine the color, see [LogLevel] */ @Composable -private fun String.toColor(): Color { - return when (getOrNull(31)) { - 'D' -> Color(0xFF299999) - 'I' -> Color(0xFFABC023) - 'W' -> Color(0xFFBBB529) - 'E' -> Color(0xFFFF6B68) - 'A' -> Color(0xFFFF6B68) - else -> ElementTheme.colors.textPrimary +private fun String.toColor(colorationMode: ColorationMode): Color { + return when (colorationMode) { + ColorationMode.Logcat -> when (getOrNull(31)) { + 'D' -> Color(0xFF299999) + 'I' -> Color(0xFFABC023) + 'W' -> Color(0xFFBBB529) + 'E' -> Color(0xFFFF6B68) + 'A' -> Color(0xFFFF6B68) + else -> ElementTheme.colors.textPrimary + } + ColorationMode.Logs -> when (getOrNull(32)) { + 'E' -> ElementTheme.colors.textPrimary + 'G' -> Color(0xFF299999) + '0' -> Color(0xFFABC023) + 'N' -> Color(0xFFBBB529) + 'R' -> Color(0xFFFF6B68) + else -> ElementTheme.colors.textPrimary + } + ColorationMode.None -> ElementTheme.colors.textPrimary } } diff --git a/features/viewfolder/impl/src/test/kotlin/io/element/android/features/viewfolder/test/file/ViewFilePresenterTest.kt b/features/viewfolder/impl/src/test/kotlin/io/element/android/features/viewfolder/test/file/ViewFilePresenterTest.kt index 3b593410b2..bfff21a71f 100644 --- a/features/viewfolder/impl/src/test/kotlin/io/element/android/features/viewfolder/test/file/ViewFilePresenterTest.kt +++ b/features/viewfolder/impl/src/test/kotlin/io/element/android/features/viewfolder/test/file/ViewFilePresenterTest.kt @@ -20,6 +20,7 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.features.viewfolder.impl.file.ColorationMode import io.element.android.features.viewfolder.impl.file.FileContentReader import io.element.android.features.viewfolder.impl.file.FileSave import io.element.android.features.viewfolder.impl.file.FileShare @@ -48,6 +49,7 @@ class ViewFilePresenterTest { val initialState = awaitItem() assertThat(initialState.name).isEqualTo("aName") assertThat(initialState.lines).isInstanceOf(AsyncData.Loading::class.java) + assertThat(initialState.colorationMode).isEqualTo(ColorationMode.None) val loadedState = awaitItem() val lines = (loadedState.lines as AsyncData.Success).data assertThat(lines.size).isEqualTo(1) @@ -55,6 +57,30 @@ class ViewFilePresenterTest { } } + @Test + fun `present - coloration mode for logcat`() = runTest { + val presenter = createPresenter(name = "logcat.log") + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.colorationMode).isEqualTo(ColorationMode.Logcat) + cancelAndConsumeRemainingEvents() + } + } + + @Test + fun `present - coloration mode for logs`() = runTest { + val presenter = createPresenter(name = "logs.date") + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.colorationMode).isEqualTo(ColorationMode.Logs) + cancelAndConsumeRemainingEvents() + } + } + @Test fun `present - share should not have any side effect`() = runTest { val fileContentReader = FakeFileContentReader().apply {