diff options
| author | David Göransson <david.goransson90@gmail.com> | 2023-09-27 14:01:11 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson90@gmail.com> | 2023-10-04 09:19:41 +0200 |
| commit | c6141f82e5d49ff8220b927deb322b4af8fd6608 (patch) | |
| tree | 703bc4cbf2bfa0f9e780387af401d08a4cebbc6d /android | |
| parent | e3ed0ac859542dfe048b4434c84b2b356ea560d4 (diff) | |
| download | mullvadvpn-c6141f82e5d49ff8220b927deb322b4af8fd6608.tar.xz mullvadvpn-c6141f82e5d49ff8220b927deb322b4af8fd6608.zip | |
Align behaviour with design
Diffstat (limited to 'android')
16 files changed, 113 insertions, 582 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt index ff9b658211..cdfb5989e1 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemNoEmailDialog.kt @@ -3,32 +3,31 @@ package net.mullvad.mullvadvpn.compose.dialog import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.size import androidx.compose.material3.AlertDialog import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.MaterialTheme 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.res.colorResource -import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.button.ActionButton +import net.mullvad.mullvadvpn.lib.theme.AppTheme +import net.mullvad.mullvadvpn.lib.theme.Dimens @Preview @Composable private fun PreviewReportProblemNoEmailDialog() { - ReportProblemNoEmailDialog( - onDismiss = {}, - onConfirm = {}, - ) + AppTheme { + ReportProblemNoEmailDialog( + onDismiss = {}, + onConfirm = {}, + ) + } } @Composable @@ -42,17 +41,16 @@ fun ReportProblemNoEmailDialog(onDismiss: () -> Unit, onConfirm: () -> Unit) { ) { Image( painter = painterResource(id = R.drawable.icon_alert), - contentDescription = "Remove", - modifier = Modifier.width(50.dp).height(50.dp) + contentDescription = null, + modifier = Modifier.size(Dimens.dialogIconSize) ) } }, text = { Text( text = stringResource(id = R.string.confirm_no_email), - color = colorResource(id = R.color.white), - fontSize = dimensionResource(id = R.dimen.text_small).value.sp, - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), + style = MaterialTheme.typography.bodySmall ) }, dismissButton = { @@ -60,27 +58,25 @@ fun ReportProblemNoEmailDialog(onDismiss: () -> Unit, onConfirm: () -> Unit) { modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( - containerColor = colorResource(id = R.color.red), - contentColor = Color.White + containerColor = MaterialTheme.colorScheme.error, + contentColor = MaterialTheme.colorScheme.onError, ), onClick = onConfirm, - ) { - Text(text = stringResource(id = R.string.send_anyway), fontSize = 18.sp) - } + text = stringResource(id = R.string.send_anyway) + ) }, confirmButton = { ActionButton( modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( - containerColor = colorResource(id = R.color.blue), - contentColor = Color.White + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary, ), onClick = { onDismiss() }, - ) { - Text(text = stringResource(id = R.string.back), fontSize = 18.sp) - } + text = stringResource(id = R.string.back) + ) }, - containerColor = colorResource(id = R.color.darkBlue) + containerColor = MaterialTheme.colorScheme.background ) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt index 6a63423399..a7b9182aea 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ReportProblemStateDialog.kt @@ -3,34 +3,31 @@ package net.mullvad.mullvadvpn.compose.dialog import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.material3.AlertDialog import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.window.DialogProperties +import androidx.compose.ui.window.SecureFlagPolicy import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.button.ActionButton +import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.Dimens import net.mullvad.mullvadvpn.viewmodel.SendingReportUiState @@ -59,7 +56,7 @@ fun ShowReportProblemStateDialog( @Preview @Composable private fun PreviewReportProblemSendingDialog() { - ReportProblemSendingDialog() + AppTheme { ReportProblemSendingDialog() } } @Composable @@ -80,10 +77,7 @@ private fun ReportProblemSendingDialog() { ) { Text( text = stringResource(id = R.string.sending), - color = colorResource(id = R.color.white), - fontSize = dimensionResource(id = R.dimen.text_small).value.sp, - fontStyle = FontStyle.Normal, - textAlign = TextAlign.Start, + style = MaterialTheme.typography.bodySmall, modifier = Modifier.fillMaxWidth() ) } @@ -94,17 +88,19 @@ private fun ReportProblemSendingDialog() { dismissOnClickOutside = false, dismissOnBackPress = false, ), - containerColor = colorResource(id = R.color.darkBlue) + containerColor = MaterialTheme.colorScheme.background ) } @Preview @Composable private fun PreviewReportProblemSuccessDialog() { - ReportProblemSuccessDialog( - "Email@em.com", - onConfirm = {}, - ) + AppTheme { + ReportProblemSuccessDialog( + "Email@em.com", + onConfirm = {}, + ) + } } @Composable @@ -118,52 +114,75 @@ fun ReportProblemSuccessDialog(email: String?, onConfirm: () -> Unit) { ) { Image( painter = painterResource(id = R.drawable.icon_success), - contentDescription = "Remove", - modifier = Modifier.width(50.dp).height(50.dp) + contentDescription = null, + modifier = Modifier.size(Dimens.dialogIconSize) ) } }, text = { - Text( - text = - buildAnnotatedString { - withStyle(SpanStyle(color = colorResource(id = R.color.green))) { - append(stringResource(id = R.string.sent_thanks)) - } - append(" ") + Column { + Text( + text = + buildAnnotatedString { + withStyle(SpanStyle(color = MaterialTheme.colorScheme.surface)) { + append(stringResource(id = R.string.sent_thanks)) + } + append(" ") + withStyle(SpanStyle(color = MaterialTheme.colorScheme.onPrimary)) { + append(stringResource(id = R.string.we_will_look_into_this)) + } + }, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.fillMaxWidth() + ) + + Spacer(modifier = Modifier.height(Dimens.smallPadding)) + email?.let { + val emailTemplate = stringResource(R.string.sent_contact) + val annotatedEmailString = + remember(it) { + val emailStart = emailTemplate.indexOf('%') - withStyle(SpanStyle(color = colorResource(id = R.color.white))) { - append(stringResource(id = R.string.we_will_look_into_this)) + buildAnnotatedString { + append(emailTemplate.substring(0, emailStart)) + withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append(email) } + } } - }, - fontSize = dimensionResource(id = R.dimen.text_small).value.sp, - modifier = Modifier.fillMaxWidth() - ) + + Text( + text = annotatedEmailString, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.fillMaxWidth() + ) + } + } }, confirmButton = { ActionButton( modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( - containerColor = colorResource(id = R.color.blue), - contentColor = Color.White + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary, ), onClick = { onConfirm() }, - ) { - Text(text = stringResource(id = R.string.dismiss), fontSize = 18.sp) - } + text = stringResource(id = R.string.dismiss) + ) }, - containerColor = colorResource(id = R.color.darkBlue) + containerColor = MaterialTheme.colorScheme.background, + properties = DialogProperties(securePolicy = if (email != null) SecureFlagPolicy.SecureOn else SecureFlagPolicy.Inherit) ) } @Preview @Composable private fun PreviewReportProblemErrorDialog() { - ReportProblemErrorDialog( - onDismiss = {}, - retry = {}, - ) + AppTheme { + ReportProblemErrorDialog( + onDismiss = {}, + retry = {}, + ) + } } @Composable @@ -178,15 +197,14 @@ fun ReportProblemErrorDialog(onDismiss: () -> Unit, retry: () -> Unit) { Image( painter = painterResource(id = R.drawable.icon_fail), contentDescription = null, - modifier = Modifier.width(50.dp).height(50.dp) + modifier = Modifier.size(Dimens.dialogIconSize) ) } }, text = { Text( text = stringResource(id = R.string.failed_to_send_details), - color = colorResource(id = R.color.white), - fontSize = dimensionResource(id = R.dimen.text_small).value.sp, + style = MaterialTheme.typography.bodySmall, modifier = Modifier.fillMaxWidth() ) }, @@ -195,27 +213,25 @@ fun ReportProblemErrorDialog(onDismiss: () -> Unit, retry: () -> Unit) { modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( - containerColor = colorResource(id = R.color.blue), - contentColor = Color.White + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary, ), onClick = onDismiss, - ) { - Text(text = stringResource(id = R.string.edit_message), fontSize = 18.sp) - } + text = stringResource(id = R.string.edit_message) + ) }, confirmButton = { ActionButton( modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( - containerColor = colorResource(id = R.color.green), - contentColor = Color.White + containerColor = MaterialTheme.colorScheme.surface, + contentColor = MaterialTheme.colorScheme.onPrimary, ), onClick = retry, - ) { - Text(text = stringResource(id = R.string.try_again), fontSize = 18.sp) - } + text = stringResource(id = R.string.try_again) + ) }, - containerColor = colorResource(id = R.color.darkBlue) + containerColor = MaterialTheme.colorScheme.background ) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt index 6f030f37fe..1a06c3ae77 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt @@ -139,8 +139,9 @@ fun ReportProblemScreen( Column( modifier = Modifier.padding( - horizontal = Dimens.sideMargin, - vertical = Dimens.screenVerticalMargin + start = Dimens.sideMargin, + end = Dimens.sideMargin, + bottom = Dimens.verticalSpace, ), verticalArrangement = Arrangement.spacedBy(Dimens.mediumPadding) ) { 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 80bb49f1af..53c3f9ff0c 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 @@ -72,8 +72,9 @@ fun ViewLogsScreen( modifier = Modifier.fillMaxSize() .padding( - vertical = Dimens.sideMargin, - horizontal = Dimens.screenVerticalMargin + start = Dimens.sideMargin, + end = Dimens.sideMargin, + bottom = Dimens.screenVerticalMargin ), ) { if (uiState.isLoading) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/MinLoadingConstant.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/MinLoadingConstant.kt deleted file mode 100644 index a93422d3f6..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/MinLoadingConstant.kt +++ /dev/null @@ -1,3 +0,0 @@ -package net.mullvad.mullvadvpn.constant - -const val MINIMUM_LOADING_SPINNER_TIME_MILLIS = 500L 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 new file mode 100644 index 0000000000..cace9b2b79 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt @@ -0,0 +1,4 @@ +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/ui/CollapsibleTitleController.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CollapsibleTitleController.kt deleted file mode 100644 index 1c37945602..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CollapsibleTitleController.kt +++ /dev/null @@ -1,219 +0,0 @@ -package net.mullvad.mullvadvpn.ui - -import android.view.View -import android.view.View.OnLayoutChangeListener -import android.view.ViewGroup.MarginLayoutParams -import kotlin.properties.Delegates.observable -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.util.LinearInterpolation -import net.mullvad.mullvadvpn.util.ListenableScrollableView - -// In order to use this view controller, the parent view must contain four views with specific IDs: -// -// 1. A scroll area `View` with the `scrollAreaId` that implements `ListenableScrollableView`, which -// is used to animate the title based on the scroll offset. -// 2. A view inside the scroll area with the ID `expanded_title`. This view is made invisible so -// that it's not drawn, but it is used to measure the layout and the animation positions. -// 3. A view outside the scroll area with the ID `collapsed_title`. This view is also made -// invisible just like the `expanded_view`. -// 4. A view with the ID `title`. This is the view that's actually drawn, and it's position and size -// are interpolated from the expanded title to the collapsed title. This view should be placed -// somewhere where it is drawn over all other views. -// -// The animation interpolation is calculated based on the Y scroll offset of the scroll area. Once -// the offset reaches a value that completely hides the expanded title inside the scroll view, the -// animation finishes with the title being in the collapsed state. -class CollapsibleTitleController(val parentView: View, scrollAreaId: Int = R.id.scroll_area) { - private inner class LayoutListener(val listener: (View) -> Unit) : OnLayoutChangeListener { - override fun onLayoutChange( - view: View, - left: Int, - top: Int, - right: Int, - bottom: Int, - oldLeft: Int, - oldTop: Int, - oldRight: Int, - oldBottom: Int - ) { - listener.invoke(view) - update() - } - } - - private val scaleInterpolation = LinearInterpolation() - private val scrollInterpolation = LinearInterpolation() - private val xOffsetInterpolation = LinearInterpolation() - private val yOffsetInterpolation = LinearInterpolation() - - private val collapsedTitleLayoutListener: LayoutListener = LayoutListener { collapsedTitle -> - val (x, y) = calculateViewCoordinates(collapsedTitle) - - collapsedTitleHeight = collapsedTitle.height.toFloat() - - scaleInterpolation.end = collapsedTitleHeight / maxOf(1.0f, titleHeight) - xOffsetInterpolation.end = x - yOffsetInterpolation.end = y - } - - private val collapsedTitleView = - parentView.findViewById<View>(R.id.collapsed_title).apply { - addOnLayoutChangeListener(collapsedTitleLayoutListener) - visibility = View.INVISIBLE - } - - private val expandedTitleLayoutListener: LayoutListener = LayoutListener { expandedTitle -> - val (x, y) = calculateViewCoordinates(expandedTitle) - - val expandedTitleMarginTop = - when (val layoutParams = expandedTitle.layoutParams) { - is MarginLayoutParams -> layoutParams.topMargin - else -> 0 - } - - expandedTitleHeight = expandedTitle.height.toFloat() - - scaleInterpolation.start = expandedTitleHeight / maxOf(1.0f, titleHeight) - xOffsetInterpolation.start = x - yOffsetInterpolation.start = y - - scrollInterpolation.end = expandedTitleHeight + expandedTitleMarginTop - } - - private val titleLayoutListener: LayoutListener = LayoutListener { title -> - val (x, y) = calculateViewCoordinates(title) - - titleWidth = title.width.toFloat() - titleHeight = title.height.toFloat() - - scaleInterpolation.start = expandedTitleHeight / maxOf(1.0f, titleHeight) - scaleInterpolation.end = collapsedTitleHeight / maxOf(1.0f, titleHeight) - xOffsetInterpolation.reference = x - yOffsetInterpolation.reference = y - } - - private val titleView = - parentView.findViewById<View>(R.id.title).apply { - addOnLayoutChangeListener(titleLayoutListener) - - // Setting the scale pivot point to the left corner simplifies the calculations - pivotX = 0.0f - pivotY = 0.0f - } - - private val scrollAreaLayoutListener: LayoutListener = LayoutListener { - scrollOffset = scrollArea.verticalScrollOffset.toFloat() - } - - private val scrollArea = - parentView.findViewById<View>(scrollAreaId).let { view -> - val scrollableView = view as ListenableScrollableView - - view.addOnLayoutChangeListener(scrollAreaLayoutListener) - - scrollableView.onScrollListener = { _, top, _, _ -> - scrollOffset = top.toFloat() - update() - } - - scrollableView - } - - private var scrollOffsetUpdated = false - get() { - if (field == true) { - field = false - return true - } else { - return false - } - } - - private var collapsedTitleHeight = 0.0f - private var expandedTitleHeight = 0.0f - private var titleWidth = 0.0f - private var titleHeight = 0.0f - - private var scrollOffset: Float by - observable(0.0f) { _, old, new -> - if (scrollOffsetUpdated == false && old != new) { - scrollOffsetUpdated = true - } - } - - val fullCollapseScrollOffset: Float - get() = scrollInterpolation.end - - var expandedTitleView by - observable<View?>(null) { _, oldView, newView -> - oldView?.removeOnLayoutChangeListener(expandedTitleLayoutListener) - newView?.apply { - addOnLayoutChangeListener(expandedTitleLayoutListener) - expandedTitleLayoutListener.listener(this) - visibility = View.INVISIBLE - } - } - - init { - expandedTitleView = parentView.findViewById<View>(R.id.expanded_title) - update() - } - - fun onDestroy() { - scrollArea.onScrollListener = null - (scrollArea as View).removeOnLayoutChangeListener(scrollAreaLayoutListener) - - collapsedTitleView.removeOnLayoutChangeListener(collapsedTitleLayoutListener) - expandedTitleView?.removeOnLayoutChangeListener(expandedTitleLayoutListener) - titleView.removeOnLayoutChangeListener(titleLayoutListener) - } - - private fun update() { - val shouldUpdate = - scrollOffsetUpdated || - scaleInterpolation.updated || - xOffsetInterpolation.updated || - yOffsetInterpolation.updated - - if (shouldUpdate) { - val progress = - if (expandedTitleView != null) { - maxOf(0.0f, minOf(1.0f, scrollInterpolation.progress(scrollOffset))) - } else { - 1.0f - } - - val scale = scaleInterpolation.interpolate(progress) - val offsetX = xOffsetInterpolation.interpolate(progress) - val offsetY = yOffsetInterpolation.interpolate(progress) - - titleView.apply { - scaleX = scale - scaleY = scale - translationX = offsetX - translationY = offsetY - } - } - } - - private fun calculateViewCoordinates(view: View): Pair<Float, Float> { - var currentView = view - var x = 0.0f - var y = 0.0f - - while (currentView != parentView) { - val parent = currentView.parent - - x += currentView.x - currentView.translationX - y += currentView.y - currentView.translationY - - if (parent is View) { - currentView = parent - } else { - break - } - } - - return Pair(x, y) - } -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemDividerDecoration.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemDividerDecoration.kt deleted file mode 100644 index 4fcde0e314..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemDividerDecoration.kt +++ /dev/null @@ -1,16 +0,0 @@ -package net.mullvad.mullvadvpn.ui - -import android.graphics.Rect -import android.view.View -import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.RecyclerView.ItemDecoration -import androidx.recyclerview.widget.RecyclerView.State - -class ListItemDividerDecoration(private val bottomOffset: Int = 0, private val topOffset: Int = 0) : - ItemDecoration() { - - override fun getItemOffsets(offsets: Rect, view: View, parent: RecyclerView, state: State) { - offsets.bottom = bottomOffset - offsets.top = topOffset - } -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt index aba7bd860a..397039719c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt @@ -12,10 +12,6 @@ import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.viewmodel.ReportProblemViewModel import org.koin.androidx.viewmodel.ext.android.viewModel -// TODO -// [ ] - Showing enable email secure screen? -// [ ] - Decide to save logs? - class ProblemReportFragment : BaseFragment() { private val vm by viewModel<ReportProblemViewModel>() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/EditTextExt.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/EditTextExt.kt deleted file mode 100644 index b90201edfe..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/EditTextExt.kt +++ /dev/null @@ -1,15 +0,0 @@ -package net.mullvad.mullvadvpn.util - -import android.view.KeyEvent -import android.view.inputmethod.EditorInfo -import android.widget.EditText - -fun EditText.setOnEnterOrDoneAction(callback: () -> Unit) { - setOnEditorActionListener { _, action, event -> - if (action == EditorInfo.IME_ACTION_DONE || event?.keyCode == KeyEvent.KEYCODE_ENTER) { - callback() - } - - false - } -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModel.kt index 5b69ec9317..a7daf9e8d9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModel.kt @@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.constant.MINIMUM_LOADING_SPINNER_TIME_MILLIS +import net.mullvad.mullvadvpn.constant.MINIMUM_LOADING_TIME_MILLIS import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport import net.mullvad.mullvadvpn.dataproxy.SendProblemReportResult import net.mullvad.mullvadvpn.dataproxy.UserReport @@ -46,11 +46,11 @@ class ReportProblemViewModel(private val mullvadProblemReporter: MullvadProblemR it.copy(sendingState = SendingReportUiState.Sending, showConfirmNoEmail = false) } - // Ensure we show loading for at least 500 ms + // Ensure we show loading for at least MINIMUM_LOADING_TIME_MILLIS val deferredResult = async { mullvadProblemReporter.sendReport(UserReport(nullableEmail, description)) } - delay(MINIMUM_LOADING_SPINNER_TIME_MILLIS) + delay(MINIMUM_LOADING_TIME_MILLIS) _uiState.update { it.copy(sendingState = deferredResult.await().toUiResult(nullableEmail)) 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 8ceae43289..7b07adc874 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 @@ -7,6 +7,7 @@ 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.dataproxy.MullvadProblemReport data class ViewLogsUiState(val allLines: String = "", val isLoading: Boolean = true) @@ -22,7 +23,7 @@ class ViewLogsViewModel(private val mullvadProblemReporter: MullvadProblemReport // 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(500) + delay(NAVIGATION_DELAY_MILLIS) _uiState.update { it.copy( allLines = mullvadProblemReporter.readLogs().joinToString("\n"), diff --git a/android/app/src/main/res/layout/confirm_no_email.xml b/android/app/src/main/res/layout/confirm_no_email.xml deleted file mode 100644 index bd6be5f4a4..0000000000 --- a/android/app/src/main/res/layout/confirm_no_email.xml +++ /dev/null @@ -1,31 +0,0 @@ -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:scrollbars="none"> - <LinearLayout android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="30dp" - android:background="@drawable/dialog_background" - android:orientation="vertical" - android:gravity="start"> - <ImageView android:layout_width="44dp" - android:layout_height="44dp" - android:layout_marginTop="8dp" - android:layout_gravity="center" - android:src="@drawable/icon_alert" /> - <TextView android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:layout_marginTop="16dp" - android:textColor="@color/white80" - android:textSize="@dimen/text_small" - android:text="@string/confirm_no_email" /> - <Button android:id="@+id/send_button" - android:layout_marginVertical="@dimen/button_separation" - android:text="@string/send_anyway" - style="@style/RedButton" /> - <Button android:id="@+id/back_button" - android:text="@string/back" - style="@style/BlueButton" /> - </LinearLayout> -</ScrollView> diff --git a/android/app/src/main/res/layout/problem_report.xml b/android/app/src/main/res/layout/problem_report.xml deleted file mode 100644 index 5832b1a893..0000000000 --- a/android/app/src/main/res/layout/problem_report.xml +++ /dev/null @@ -1,163 +0,0 @@ -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:mullvad="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/darkBlue" - android:gravity="start"> - <TextView android:id="@+id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/report_a_problem" - style="@style/SettingsCollapsedHeader" /> - <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - <FrameLayout android:layout_width="match_parent" - android:layout_height="wrap_content"> - <net.mullvad.mullvadvpn.ui.widget.BackButton android:id="@+id/back" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - mullvad:text="@string/settings" /> - <TextView android:id="@+id/collapsed_title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginHorizontal="4dp" - android:layout_gravity="center" - android:text="@string/report_a_problem" - style="@style/SettingsCollapsedHeader" /> - </FrameLayout> - <net.mullvad.mullvadvpn.ui.widget.ListenableScrollView android:id="@+id/scroll_area" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:fillViewport="true"> - <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - <TextView android:id="@+id/expanded_title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:layout_marginTop="2dp" - android:layout_marginBottom="8dp" - android:layout_marginHorizontal="@dimen/side_margin" - android:lines="1" - android:text="@string/report_a_problem" - style="@style/SettingsExpandedHeader" /> - <ViewSwitcher android:id="@+id/body_container" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - <TextView android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:layout_marginBottom="@dimen/vertical_space" - android:layout_marginHorizontal="@dimen/side_margin" - android:textColor="@color/white80" - android:textSize="@dimen/text_small" - android:text="@string/problem_report_description" /> - <EditText android:id="@+id/user_email" - android:inputType="textEmailAddress" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_weight="0" - android:layout_marginBottom="12dp" - android:layout_marginHorizontal="22dp" - android:singleLine="true" - android:hint="@string/user_email_hint" - style="@style/InputText" /> - <EditText android:id="@+id/user_message" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:layout_marginHorizontal="@dimen/side_margin" - android:singleLine="false" - android:hint="@string/user_message_hint" - android:gravity="top" - style="@style/InputText" /> - <Button android:id="@+id/view_logs" - android:layout_marginHorizontal="@dimen/side_margin" - android:layout_marginVertical="@dimen/button_separation" - android:enabled="true" - android:text="@string/view_logs" - style="@style/BlueButton" /> - <Button android:id="@+id/send_button" - android:layout_marginHorizontal="@dimen/side_margin" - android:layout_marginBottom="@dimen/screen_vertical_margin" - android:enabled="false" - android:text="@string/send" - style="@style/GreenButton" /> - </LinearLayout> - <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_marginTop="16dp" - android:layout_marginBottom="@dimen/screen_vertical_margin" - android:layout_marginHorizontal="@dimen/side_margin" - android:orientation="vertical"> - <FrameLayout android:layout_width="60dp" - android:layout_height="60dp" - android:layout_gravity="center_horizontal" - android:layout_marginBottom="32dp"> - <ProgressBar android:id="@+id/sending_spinner" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center" - android:indeterminate="true" - android:indeterminateOnly="true" - android:indeterminateDuration="600" - android:indeterminateDrawable="@drawable/icon_spinner" /> - <ImageView android:id="@+id/sent_successfully_icon" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center" - android:src="@drawable/icon_success" - android:visibility="gone" /> - <ImageView android:id="@+id/failed_to_send_icon" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center" - android:src="@drawable/icon_fail" - android:visibility="gone" /> - </FrameLayout> - <TextView android:id="@+id/send_status" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="4dp" - android:textColor="@color/white" - android:textSize="@dimen/text_huge" - android:textStyle="bold" - android:text="@string/sending" /> - <TextView android:id="@+id/send_details" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColor="@color/white60" - android:textSize="@dimen/text_small" - android:text="@string/sent_thanks" - android:visibility="gone" /> - <TextView android:id="@+id/response_message" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColor="@color/white60" - android:textSize="@dimen/text_small" - android:text="@string/sent_contact" - android:visibility="gone" /> - <Space android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" /> - <Button android:id="@+id/edit_message_button" - android:layout_marginTop="@dimen/button_separation" - android:text="@string/edit_message" - android:visibility="gone" - style="@style/BlueButton" /> - <Button android:id="@+id/try_again_button" - android:layout_marginTop="@dimen/button_separation" - android:text="@string/try_again" - android:visibility="gone" - style="@style/GreenButton" /> - </LinearLayout> - </ViewSwitcher> - </LinearLayout> - </net.mullvad.mullvadvpn.ui.widget.ListenableScrollView> - </LinearLayout> -</FrameLayout> diff --git a/android/app/src/main/res/layout/view_logs.xml b/android/app/src/main/res/layout/view_logs.xml deleted file mode 100644 index 2011c8b5c9..0000000000 --- a/android/app/src/main/res/layout/view_logs.xml +++ /dev/null @@ -1,38 +0,0 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:mullvad="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/darkBlue" - android:gravity="start" - android:orientation="vertical"> - <net.mullvad.mullvadvpn.ui.widget.BackButton android:id="@+id/back" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - mullvad:text="@string/report_a_problem" /> - <TextView android:id="@+id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:layout_marginTop="2dp" - android:layout_marginHorizontal="@dimen/side_margin" - android:text="@string/view_logs" - style="@style/SettingsExpandedHeader" /> - <ScrollView android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:layout_marginTop="@dimen/vertical_space" - android:layout_marginHorizontal="@dimen/side_margin" - android:layout_marginBottom="@dimen/screen_vertical_margin" - android:scrollbarThumbVertical="@color/blue" - android:background="@drawable/input_text_background"> - <EditText android:id="@+id/log_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:editable="false" - android:textIsSelectable="true" - android:singleLine="false" - android:gravity="top" - android:background="@null" - style="@style/InputText" /> - </ScrollView> -</LinearLayout> diff --git a/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt b/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt index 99c2132719..6445c51b56 100644 --- a/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt +++ b/android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt @@ -56,7 +56,8 @@ data class Dimensions( val titleIconSize: Dp = 24.dp, val topBarHeight: Dp = 64.dp, val verticalSpace: Dp = 20.dp, - val verticalSpacer: Dp = 1.dp + val verticalSpacer: Dp = 1.dp, + val dialogIconSize: Dp = 48.dp ) val defaultDimensions = Dimensions() |
