diff options
6 files changed, 58 insertions, 51 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt index 8130e71963..bd50d45c86 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt @@ -216,7 +216,8 @@ fun MullvadMediumTopBar( scrollBehavior = scrollBehavior, colors = TopAppBarDefaults.mediumTopAppBarColors( - containerColor = MaterialTheme.colorScheme.background + containerColor = MaterialTheme.colorScheme.background, + actionIconContentColor = MaterialTheme.colorScheme.onPrimary.copy(AlphaTopBar), ), actions = actions ) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt index 21967c97a3..cbe1f6d0b3 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt @@ -1,21 +1,25 @@ package net.mullvad.mullvadvpn.compose.screen -import androidx.compose.foundation.layout.Column +import android.content.Context +import android.content.Intent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.foundation.verticalScroll +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Share import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold -import androidx.compose.material3.TextField -import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import net.mullvad.mullvadvpn.R @@ -31,7 +35,7 @@ import net.mullvad.mullvadvpn.viewmodel.ViewLogsUiState @Preview @Composable private fun PreviewViewLogsScreen() { - AppTheme { ViewLogsScreen(uiState = ViewLogsUiState("Lorem ipsum")) } + AppTheme { ViewLogsScreen(uiState = ViewLogsUiState(listOf("Lorem ipsum"))) } } @Preview @@ -46,12 +50,18 @@ fun ViewLogsScreen( uiState: ViewLogsUiState, onBackClick: () -> Unit = {}, ) { + val context = LocalContext.current Scaffold( topBar = { MullvadMediumTopBar( title = stringResource(id = R.string.view_logs), - navigationIcon = { NavigateBackIconButton(onBackClick) } + navigationIcon = { NavigateBackIconButton(onBackClick) }, + actions = { + IconButton(onClick = { shareText(context, uiState.text()) }) { + Icon(imageVector = Icons.Default.Share, contentDescription = null) + } + } ) } ) { @@ -72,35 +82,33 @@ fun ViewLogsScreen( color = MaterialTheme.colorScheme.primary ) } else { - SelectionContainer { - val scrollState = rememberScrollState() - Column( - modifier = - Modifier.drawVerticalScrollbar( - scrollState, - color = - MaterialTheme.colorScheme.primary.copy(alpha = AlphaScrollbar) + val state = rememberLazyListState() + LazyColumn( + state = state, + modifier = + Modifier.drawVerticalScrollbar( + state, + MaterialTheme.colorScheme.primary.copy(alpha = AlphaScrollbar) ) - ) { - TextField( - modifier = - Modifier.verticalScroll(scrollState) - .padding(horizontal = Dimens.smallPadding), - value = uiState.allLines, - textStyle = MaterialTheme.typography.bodySmall, - onValueChange = {}, - readOnly = true, - colors = - TextFieldDefaults.colors( - focusedTextColor = Color.Black, - unfocusedTextColor = Color.Black, - disabledTextColor = Color.Black, - cursorColor = MaterialTheme.colorScheme.background, - ) - ) + .padding(horizontal = Dimens.smallPadding) + ) { + items(uiState.allLines) { + Text(text = it, style = MaterialTheme.typography.bodySmall) } } } } } } + +private fun shareText(context: Context, text: String) { + val sendIntent: Intent = + Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_TEXT, text) + type = "text/plain" + } + val shareIntent = Intent.createChooser(sendIntent, null) + + context.startActivity(shareIntent) +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt index 5a490af717..82a98dc310 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt @@ -20,9 +20,8 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.VisualTransformation import kotlinx.coroutines.delay import kotlinx.coroutines.launch - -private const val EMPTY_STRING = "" -private const val NEWLINE_STRING = "\n" +import net.mullvad.mullvadvpn.constant.EMPTY_STRING +import net.mullvad.mullvadvpn.constant.NEWLINE_STRING @Composable fun CustomTextField( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/StringConstant.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/StringConstant.kt new file mode 100644 index 0000000000..472f147732 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/StringConstant.kt @@ -0,0 +1,4 @@ +package net.mullvad.mullvadvpn.constant + +const val EMPTY_STRING = "" +const val NEWLINE_STRING = "\n" diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt index cace9b2b79..2a09964a80 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt @@ -1,4 +1,3 @@ package net.mullvad.mullvadvpn.constant const val MINIMUM_LOADING_TIME_MILLIS = 500L -const val NAVIGATION_DELAY_MILLIS = 500L diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ViewLogsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ViewLogsViewModel.kt index 7b07adc874..618536eaa2 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ViewLogsViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ViewLogsViewModel.kt @@ -2,15 +2,19 @@ package net.mullvad.mullvadvpn.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.constant.NAVIGATION_DELAY_MILLIS +import net.mullvad.mullvadvpn.constant.NEWLINE_STRING import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport -data class ViewLogsUiState(val allLines: String = "", val isLoading: Boolean = true) +data class ViewLogsUiState( + val allLines: List<String> = emptyList(), + val isLoading: Boolean = true +) { + fun text() = allLines.joinToString(NEWLINE_STRING) +} class ViewLogsViewModel(private val mullvadProblemReporter: MullvadProblemReport) : ViewModel() { @@ -19,16 +23,8 @@ class ViewLogsViewModel(private val mullvadProblemReporter: MullvadProblemReport init { viewModelScope.launch { - // Loading this much text takes a while, so we show a loading indicator until the - // fragment transitions is done. I'd very much prefer to use LazyColumn in the view - // which would make the loading way faster but then the SelectionContainer is broken and - // text would not be copyable. - delay(NAVIGATION_DELAY_MILLIS) _uiState.update { - it.copy( - allLines = mullvadProblemReporter.readLogs().joinToString("\n"), - isLoading = false - ) + it.copy(allLines = mullvadProblemReporter.readLogs(), isLoading = false) } } } |
