Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moving flow fixes before release #1835

Merged
merged 19 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a7f1ec3
Enable octopus moving flow with movingFlowClient feature flag
StylianosGakis Oct 17, 2023
dce6c58
Remove unused deep links list to moving_flow feature
StylianosGakis Oct 17, 2023
d15ed60
Use `Icon` instead of `Image` to support dark mode
StylianosGakis Oct 18, 2023
2e6c2c8
Fixes in ExtraBuildingContainer
StylianosGakis Oct 18, 2023
b9ec654
Fix crash when entering an empty string for size input
StylianosGakis Oct 18, 2023
05680d5
Make keyboard easier to use by only showing numbers for number input
StylianosGakis Oct 18, 2023
9de4fb4
Fix bug with using `List<T>.replace`
StylianosGakis Oct 18, 2023
fe2fe5d
Make implementation better show that it just clears the error message
StylianosGakis Oct 18, 2023
1bea07a
Refactor functions to use early returns for readability
StylianosGakis Oct 18, 2023
0372f51
Refactor more functions to use early returns for readability
StylianosGakis Oct 18, 2023
3a1ad58
Use onPlaced since we don't need onGloballyPositioned here
StylianosGakis Oct 18, 2023
4101b40
Change destination names slightly
StylianosGakis Oct 18, 2023
5dcc826
Fix moving flow back handling
StylianosGakis Oct 18, 2023
14385bc
Change references to .sp values to tokens from typography
StylianosGakis Oct 18, 2023
b77bb0a
Tiny UI fixes for offer
StylianosGakis Oct 18, 2023
5af7a22
Fix documents to use default hedvig card colors
StylianosGakis Oct 18, 2023
a1f88f7
Fix visibility modifiers in all feature-changeaddress
StylianosGakis Oct 18, 2023
daf6a58
Fix ktlint error
StylianosGakis Oct 19, 2023
14a8191
Fix breaking GQL schema change
StylianosGakis Oct 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class ChatRepositoryNewImpl(
contentType: String,
) = either {
val fileUpload = file.toUpload(contentType)
val input = ChatMessageFileInput(fileUpload)
// val input = ChatMessageFileInput(fileUpload) // todo here upload file directly through HTTP instead
val input = ChatMessageFileInput("")
val mutation = ChatSendFileMutation(input)

val result = apolloClientOctopus.mutation(mutation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
import com.hedvig.android.core.designsystem.material3.infoContainer
import com.hedvig.android.core.designsystem.material3.onInfoContainer
Expand All @@ -22,10 +23,11 @@ fun HedvigInfoCard(
containerColor = MaterialTheme.colorScheme.infoContainer,
contentColor = MaterialTheme.colorScheme.onInfoContainer,
),
shape: Shape = MaterialTheme.shapes.squircleMedium,
content: @Composable RowScope.() -> Unit,
) {
HedvigCard(
shape = MaterialTheme.shapes.squircleMedium,
shape = shape,
colors = colors,
modifier = modifier,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
Expand All @@ -44,10 +42,6 @@ fun ExpandablePlusCard(
) {
HedvigCard(
onClick = onClick,
colors = CardDefaults.outlinedCardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant,
contentColor = MaterialTheme.colorScheme.onSurface,
),
modifier = modifier,
) {
Column {
Expand Down
1 change: 1 addition & 0 deletions app/feature/feature-changeaddress/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
implementation(projects.apolloOctopusPublic)
implementation(projects.coreCommonPublic)
implementation(projects.coreDesignSystem)
implementation(projects.coreIcons)
implementation(projects.coreResources)
implementation(projects.coreUi)
implementation(projects.coreUiData)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ internal data class ChangeAddressUiState(
val moveFromAddressId: AddressId? = null,
val quotes: List<MoveQuote> = emptyList(),
val successfulMoveResult: SuccessfulMove? = null,

/**
* When we receive the moveIntentId, we want to navigate to the next step. We keep this signal here so that we can
* still go back to the previous screen and not introduce an infinite navigation loop
*/
val navigateToFirstStepAfterHavingReceivedMoveIntentId: Boolean = false,

/**
* When we receive some quotes from submitting all the data, we want to navigate to the offer destination. We keep
* this signal so that we can go back to the previous screen and not introduce an infinite navigation loop.
*/
val navigateToOfferScreenAfterHavingReceivedQuotes: Boolean = false,
) {

val isHousingTypeValid: Boolean
Expand Down Expand Up @@ -132,24 +144,24 @@ internal data class ChangeAddressUiState(
)
}

private fun isSquareMetersWithinBounds(squareMeters: Int?) = if (maxSquareMeters != null) {
private fun isSquareMetersWithinBounds(squareMeters: Int?): Boolean {
if (maxSquareMeters == null) {
return true
}
if (squareMeters == null) {
false
} else {
squareMeters <= maxSquareMeters
return false
}
} else {
true
return squareMeters <= maxSquareMeters
}

private fun isNumberCoInsuredWithinBounds(numberCoInsured: Int?) = if (maxNumberCoInsured != null) {
private fun isNumberCoInsuredWithinBounds(numberCoInsured: Int?): Boolean {
if (maxNumberCoInsured == null) {
return true
}
if (numberCoInsured == null) {
false
} else {
numberCoInsured <= maxNumberCoInsured
return false
}
} else {
true
return numberCoInsured <= maxNumberCoInsured
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ internal class ChangeAddressViewModel(
_uiState.update { it.copy(isSublet = ValidatedInput(isSublet)) }
}

fun onQuotesCleared() {
_uiState.update { it.copy(quotes = emptyList()) }
}

fun validateAddressInput(): Boolean {
_uiState.update { it.validateAddressInput() }
return _uiState.value.isAddressInputValid
Expand All @@ -79,6 +75,26 @@ internal class ChangeAddressViewModel(
return _uiState.value.isHouseInputValid
}

/**
* After we've received the MoveIntentId, `startMovingFlowAfterHavingReceivedMoveIntentId` is used to trigger the
* navigation to the next question. When this function is called, it means the navigation event has been handled.
*/
fun onNavigatedToFirstStepAfterHavingReceivedMoveIntentId() {
_uiState.update {
it.copy(navigateToFirstStepAfterHavingReceivedMoveIntentId = false)
}
}

/**
* After we've received the offer quotes, `navigateToOfferScreenAfterHavingReceivedQuotes` is used to trigger the
* navigation to the offer page. When this function is called, it means the navigation event has been handled.
*/
fun onNavigatedToOfferScreenAfterHavingReceivedQuotes() {
_uiState.update {
it.copy(navigateToOfferScreenAfterHavingReceivedQuotes = false)
}
}

fun onSubmitNewAddress() {
if (uiState.value.moveIntentId == null) {
_uiState.update {
Expand All @@ -102,6 +118,7 @@ internal class ChangeAddressViewModel(
_uiState.update {
it.copy(
isLoading = false,
navigateToOfferScreenAfterHavingReceivedQuotes = true,
quotes = quotes,
)
}
Expand All @@ -111,12 +128,11 @@ internal class ChangeAddressViewModel(
}

fun onExpandQuote(moveQuote: MoveQuote) {
_uiState.update {
it.copy(
quotes = it.quotes.replace(
newValue = moveQuote.copy(isExpanded = !moveQuote.isExpanded),
block = { it == moveQuote },
),
_uiState.update { uiState: ChangeAddressUiState ->
uiState.copy(
quotes = uiState.quotes.map { quote: MoveQuote ->
if (quote == moveQuote) moveQuote.copy(isExpanded = !moveQuote.isExpanded) else quote
},
)
}
}
Expand Down Expand Up @@ -167,7 +183,7 @@ internal class ChangeAddressViewModel(
}

fun onHousingTypeErrorDialogDismissed() {
_uiState.update { it.copy(housingType = ValidatedInput(it.housingType.input)) }
_uiState.update { it.copy(housingType = it.housingType.copy(errorMessageRes = null)) }
}

fun onHousingTypeSubmitted() {
Expand All @@ -186,6 +202,7 @@ internal class ChangeAddressViewModel(
_uiState.update {
it.copy(
moveIntentId = moveIntent.id,
navigateToFirstStepAfterHavingReceivedMoveIntentId = true,
numberInsured = ValidatedInput(moveIntent.suggestedNumberInsured.toString()),
moveFromAddressId = moveIntent.currentHomeAddresses.firstOrNull()?.id,
extraBuildingTypes = moveIntent.extraBuildingTypes,
Expand Down Expand Up @@ -229,10 +246,12 @@ internal class ChangeAddressViewModel(
fun addExtraBuilding(extraBuilding: ExtraBuilding) {
_uiState.update {
val extraBuildings = it.extraBuildings.toMutableList()
extraBuildings.find { it.id == extraBuilding.id }?.let {
extraBuildings.replace(extraBuilding) { it.id == extraBuilding.id }
} ?: extraBuildings.add(extraBuilding)
it.copy(extraBuildings = extraBuildings)
val existingBuildingWithSameId = extraBuildings.find { it.id == extraBuilding.id }
if (existingBuildingWithSameId != null) {
extraBuildings.remove(existingBuildingWithSameId)
}
extraBuildings.add(extraBuilding)
it.copy(extraBuildings = extraBuildings.toList())
}
}
}
Expand Down Expand Up @@ -275,9 +294,3 @@ private fun ChangeAddressUiState.toQuoteInput() = when (housingType.input) {

null -> throw IllegalArgumentException("No housing type found when creating input")
}

fun <T> List<T>.replace(newValue: T, block: (T) -> Boolean): List<T> {
return map {
if (block(it)) newValue else it
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import kotlinx.serialization.Serializable

@JvmInline
@Serializable
value class AddressId(val id: String)
internal value class AddressId(val id: String)

@Serializable
data class Address(
internal data class Address(
val id: AddressId,
val apartmentNumber: String? = null,
val bbrId: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package com.hedvig.android.feature.changeaddress.data

import arrow.core.Either
import arrow.core.raise.either
import arrow.core.raise.ensureNotNull
import com.apollographql.apollo3.ApolloClient
import com.hedvig.android.apollo.safeExecute
import com.hedvig.android.apollo.toEither
import com.hedvig.android.core.common.ErrorMessage
import com.hedvig.android.core.ui.insurance.toProductVariant
import com.hedvig.android.core.uidata.UiMoney
import com.hedvig.android.logger.logcat
import kotlinx.collections.immutable.toImmutableList
import octopus.MoveIntentCommitMutation
import octopus.MoveIntentCreateMutation
Expand All @@ -19,12 +21,13 @@ internal interface ChangeAddressRepository {
suspend fun commitMove(id: MoveIntentId): Either<ErrorMessage, SuccessfulMove>
}

data object SuccessfulMove
internal data object SuccessfulMove

internal class NetworkChangeAddressRepository(
private val apolloClient: ApolloClient,
) : ChangeAddressRepository {
override suspend fun createMoveIntent(): Either<ErrorMessage, MoveIntent> {
logcat { "Moving Flow: createMoveIntent" }
return either {
val result = apolloClient
.mutation(MoveIntentCreateMutation())
Expand All @@ -33,18 +36,20 @@ internal class NetworkChangeAddressRepository(
.bind()
.moveIntentCreate

val moveIntent = result.moveIntent
val userError = result.userError

when {
moveIntent != null -> moveIntent.toMoveIntent()
userError != null -> raise(ErrorMessage(userError.message))
else -> raise(ErrorMessage("No data found in MoveIntent"))
if (userError != null) {
raise(ErrorMessage(userError.message))
}
val moveIntent = result.moveIntent
ensureNotNull(moveIntent) {
ErrorMessage("No data found in MoveIntent")
}
moveIntent.toMoveIntent()
}
}

override suspend fun createQuotes(input: QuoteInput): Either<ErrorMessage, List<MoveQuote>> {
logcat { "Moving Flow: createQuotes with input:$input" }
return either {
val result = apolloClient
.mutation(input.toMoveIntentRequestMutation())
Expand All @@ -53,18 +58,21 @@ internal class NetworkChangeAddressRepository(
.bind()
.moveIntentRequest

val moveIntent = result.moveIntent
val userError = result.userError
if (userError != null) {
raise(ErrorMessage(userError.message))
}

when {
userError != null -> raise(ErrorMessage(userError.message))
moveIntent != null -> moveIntent.toMoveQuotes()
else -> raise(ErrorMessage("No data found in MoveIntent"))
val moveIntent = result.moveIntent
ensureNotNull(moveIntent) {
ErrorMessage("No data found in MoveIntent")
}
moveIntent.toMoveQuotes()
}
}

override suspend fun commitMove(id: MoveIntentId): Either<ErrorMessage, SuccessfulMove> {
logcat { "Moving Flow: commitMove with id:$id" }
return either {
val result = apolloClient
.mutation(MoveIntentCommitMutation(id.id))
Expand All @@ -74,16 +82,15 @@ internal class NetworkChangeAddressRepository(
.moveIntentCommit

val userError = result.userError

when {
userError != null -> raise(ErrorMessage(userError.message))
else -> SuccessfulMove
if (userError != null) {
raise(ErrorMessage(userError.message))
}
SuccessfulMove
}
}
}

private fun MoveIntentCreateMutation.Data.MoveIntentCreate.MoveIntent.toMoveIntent() = MoveIntent(
private fun MoveIntentCreateMutation.Data.MoveIntentCreate.MoveIntent.toMoveIntent(): MoveIntent = MoveIntent(
id = MoveIntentId(id),
currentHomeAddresses = currentHomeAddresses.map { currentHomeAddress ->
Address(
Expand All @@ -102,19 +109,21 @@ private fun MoveIntentCreateMutation.Data.MoveIntentCreate.MoveIntent.toMoveInte
extraBuildingTypes = extraBuildingTypes.map { it.toExtraBuildingType() },
)

private fun MoveIntentRequestMutation.Data.MoveIntentRequest.MoveIntent.toMoveQuotes() = quotes.map { quote ->
MoveQuote(
id = id,
insuranceName = quote.exposureName ?: quote.productVariant.displayName,
moveIntentId = MoveIntentId(id),
premium = UiMoney(
amount = quote.premium.amount,
currencyCode = quote.premium.currencyCode,
),
startDate = quote.startDate,
productVariant = quote.productVariant.toProductVariant(),
displayItems = quote.displayItems
.map { it.displayTitle to it.displayValue }
.toImmutableList(),
)
private fun MoveIntentRequestMutation.Data.MoveIntentRequest.MoveIntent.toMoveQuotes(): List<MoveQuote> {
return quotes.map { quote ->
MoveQuote(
id = id,
insuranceName = quote.exposureName ?: quote.productVariant.displayName,
moveIntentId = MoveIntentId(id),
premium = UiMoney(
amount = quote.premium.amount,
currencyCode = quote.premium.currencyCode,
),
startDate = quote.startDate,
productVariant = quote.productVariant.toProductVariant(),
displayItems = quote.displayItems
.map { it.displayTitle to it.displayValue }
.toImmutableList(),
)
}
}
Loading
Loading