Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -456,6 +456,9 @@ private fun NavGraphBuilder.nestedHomeGraphs(
tryToDialPhone = externalNavigator::tryToDialPhone,
imageLoader = imageLoader,
appPackageId = hedvigBuildConstants.appPackageId,
onNavigateToNewConversation = { backStackEntry ->
navigateToNewConversation(backStackEntry, null)
},
)
claimDetailsGraph(
navigator = navigator,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.hedvig.feature.claim.chat

import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import coil3.ImageLoader
Expand Down Expand Up @@ -55,6 +56,7 @@ fun NavGraphBuilder.claimChatGraph(
tryToDialPhone: (String) -> Unit,
appPackageId: String,
imageLoader: ImageLoader,
onNavigateToNewConversation: (NavBackStackEntry) -> Unit,
) {
navdestination<ClaimChatDestination> {
ClaimChatDestination(
Expand All @@ -74,24 +76,23 @@ fun NavGraphBuilder.claimChatGraph(
}
},
navigateToDeflect = { deflect: StepContent.Deflect ->
// navController.navigate(UpdateAppDestination) {
// typedPopUpTo<ClaimChatDestination> {
// inclusive = true
// }
// }
navController.navigate(ClaimOutcomeDeflectDestination(deflect = deflect))
},
appPackageId = appPackageId,
imageLoader = imageLoader,
)
}
navdestination<ClaimOutcomeDeflectDestination>(ClaimOutcomeDeflectDestination) {
navdestination<ClaimOutcomeDeflectDestination>(ClaimOutcomeDeflectDestination)
{ backStackEntry ->
ClaimOutcomeDeflectDestination(
deflect = deflect,
imageLoader = imageLoader,
navigateUp = navController::navigateUp,
openUrl = openUrl,
tryToDialPhone = tryToDialPhone,
onNavigateToNewConversation = {
onNavigateToNewConversation(backStackEntry)
}
)
}
navdestination<ClaimOutcomeNewClaimDestination>(ClaimOutcomeNewClaimDestination) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,70 +24,71 @@ import androidx.compose.ui.unit.dp
import kotlin.math.cos
import kotlin.math.sin

@Composable
internal actual fun BlurredGradientBackground(modifier: Modifier, radius: Int) {
Box(
modifier = modifier.graphicsLayer {
compositingStrategy = CompositingStrategy.Offscreen
val radiusPx = radius.dp.toPx()
renderEffect = BlurEffect(
radiusX = radiusPx,
radiusY = radiusPx,
edgeTreatment = TileMode.Decal,
)
},
) {
// 1. Setup Continuous Animation for Movement
val infiniteTransition = rememberInfiniteTransition(label = "GradientMovement")

// Animate a phase shift from 0f to 2 * PI (one full cycle) over 10 seconds (10000ms)
val phase by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = (2 * kotlin.math.PI).toFloat(),
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 10000, easing = LinearEasing),
repeatMode = RepeatMode.Reverse,
),
label = "phaseShift",
)

Box(modifier = modifier.fillMaxSize()) {
// 2. The Blur and Canvas Layer (Combined for Skia/Android)
Canvas(
modifier = Modifier.fillMaxSize(),
) {
val canvasWidth = size.width
val canvasHeight = size.height

// Set radius extremely large so only the blurred, soft edges are visible
val radius = size.minDimension * 2.0f

// --- Shape 1: Purple/Pink (Top Left Corner) ---
val offset1 = Offset(
// Base position + oscillating movement
x = canvasWidth * 0.1f + sin(phase) * (canvasWidth * 0.15f),
y = canvasHeight * 0.1f + cos(phase * 0.5f) * (canvasHeight * 0.1f),
)
drawCircle(
color = Color(0xFFC9A7ED).copy(alpha = 0.6f), // Light purple color
radius = radius,
center = offset1,
// BlendMode.Screen helps the colors brighten when they overlap, matching the video's look
blendMode = BlendMode.Screen,
)

// --- Shape 2: Yellow/Green (Bottom Right Corner) ---
val offset2 = Offset(
x = canvasWidth * 0.9f + cos(phase * 1.5f) * (canvasWidth * 0.1f),
y = canvasHeight * 0.9f + sin(phase * 0.7f) * (canvasHeight * 0.15f),
)
drawCircle(
color = Color(0xFFF9E899).copy(alpha = 0.5f), // Light yellow/cream color
radius = radius * 0.8f,
center = offset2,
blendMode = BlendMode.Screen,
)
}
}
}
}
//todo: leaving it here since we want to have gradient in the future
//@Composable
//internal actual fun BlurredGradientBackground(modifier: Modifier, radius: Int) {
// Box(
// modifier = modifier.graphicsLayer {
// compositingStrategy = CompositingStrategy.Offscreen
// val radiusPx = radius.dp.toPx()
// renderEffect = BlurEffect(
// radiusX = radiusPx,
// radiusY = radiusPx,
// edgeTreatment = TileMode.Decal,
// )
// },
// ) {
// // 1. Setup Continuous Animation for Movement
// val infiniteTransition = rememberInfiniteTransition(label = "GradientMovement")
//
// // Animate a phase shift from 0f to 2 * PI (one full cycle) over 10 seconds (10000ms)
// val phase by infiniteTransition.animateFloat(
// initialValue = 0f,
// targetValue = (2 * kotlin.math.PI).toFloat(),
// animationSpec = infiniteRepeatable(
// animation = tween(durationMillis = 10000, easing = LinearEasing),
// repeatMode = RepeatMode.Reverse,
// ),
// label = "phaseShift",
// )
//
// Box(modifier = modifier.fillMaxSize()) {
// // 2. The Blur and Canvas Layer (Combined for Skia/Android)
// Canvas(
// modifier = Modifier.fillMaxSize(),
// ) {
// val canvasWidth = size.width
// val canvasHeight = size.height
//
// // Set radius extremely large so only the blurred, soft edges are visible
// val radius = size.minDimension * 2.0f
//
// // --- Shape 1: Purple/Pink (Top Left Corner) ---
// val offset1 = Offset(
// // Base position + oscillating movement
// x = canvasWidth * 0.1f + sin(phase) * (canvasWidth * 0.15f),
// y = canvasHeight * 0.1f + cos(phase * 0.5f) * (canvasHeight * 0.1f),
// )
// drawCircle(
// color = Color(0xFFC9A7ED).copy(alpha = 0.6f), // Light purple color
// radius = radius,
// center = offset1,
// // BlendMode.Screen helps the colors brighten when they overlap, matching the video's look
// blendMode = BlendMode.Screen,
// )
//
// // --- Shape 2: Yellow/Green (Bottom Right Corner) ---
// val offset2 = Offset(
// x = canvasWidth * 0.9f + cos(phase * 1.5f) * (canvasWidth * 0.1f),
// y = canvasHeight * 0.9f + sin(phase * 0.7f) * (canvasHeight * 0.15f),
// )
// drawCircle(
// color = Color(0xFFF9E899).copy(alpha = 0.5f), // Light yellow/cream color
// radius = radius * 0.8f,
// center = offset2,
// blendMode = BlendMode.Screen,
// )
// }
// }
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ fragment DeflectionFragment on ClaimIntentStepContentDeflection {
faq {
...DeflectionInfoBlockFragment
}
buttonTitle
}

fragment DeflectionInfoBlockFragment on ClaimIntentStepContentDeflectionInfoBlock {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ internal sealed interface ClaimChatUiState {
val claimIntentId: ClaimIntentId,
val steps: List<ClaimIntentStep>,
val currentStep: ClaimIntentStep?,
val autoNavigateForDeflectStepId: StepId?,
val freeText: String?,
val outcome: ClaimIntentOutcome?,
val errorSubmittingStep: ErrorMessage?,
Expand Down Expand Up @@ -198,7 +197,6 @@ internal class ClaimChatPresenter(
val currentStep by remember {
derivedStateOf { steps.lastOrNull() }
}
var autoNavigateForDeflectStepId: StepId? by remember { mutableStateOf(null) }
var showFreeTextOverlay by remember { mutableStateOf<FreeTextRestrictions?>(null) }
var currentContinueButtonLoading by remember { mutableStateOf(false) }
var currentSkipButtonLoading by remember { mutableStateOf(false) }
Expand All @@ -207,7 +205,6 @@ internal class ClaimChatPresenter(
var showConfirmEditDialogForStep by remember { mutableStateOf<StepId?>(null) }

val setOutcome: (ClaimIntentOutcome) -> Unit = { outcome = it }
val setAutoNavigateForDeflectStepId: (StepId) -> Unit = { autoNavigateForDeflectStepId = it }

if (initializing) {
LaunchedEffect(Unit) {
Expand All @@ -233,7 +230,7 @@ internal class ClaimChatPresenter(

ObserveIncompleteTaskEffect(getClaimIntentUseCase, currentStep, { claimIntentId }, steps)
SubmitCompleteTaskEffect(submitTaskUseCase, currentStep) { claimIntent ->
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
}

CollectEvents { event ->
Expand Down Expand Up @@ -264,7 +261,7 @@ internal class ClaimChatPresenter(
return@launch
}
currentContinueButtonLoading = false
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
},
)
}
Expand Down Expand Up @@ -296,7 +293,7 @@ internal class ClaimChatPresenter(
ifRight = { claimIntent ->
audioRecordingManager.cleanup()
currentContinueButtonLoading = false
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
},
)
}
Expand All @@ -316,7 +313,7 @@ internal class ClaimChatPresenter(
},
ifRight = { claimIntent ->
currentContinueButtonLoading = false
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
},
)
}
Expand Down Expand Up @@ -346,14 +343,19 @@ internal class ClaimChatPresenter(
}

is ClaimChatEvent.AudioRecording.ShowFreeText -> {
val currentContent = currentStep?.stepContent as? StepContent.AudioRecording
?: return@CollectEvents
val textTooShort = freeText?.length?.let {
currentContent.freeTextMinLength > it
} ?: true
steps.updateStepWithSuccess<StepContent.AudioRecording>(event.id) { step, content ->
val canSubmit = !currentContinueButtonLoading && !freeText.isNullOrEmpty() && !textTooShort
step.copy(
stepContent = content.copy(
recordingState = FreeTextDescription(
showOverlay = false,
errorType = null,
canSubmit =
!currentContinueButtonLoading && !freeText.isNullOrEmpty(),
canSubmit = canSubmit,
),
),
)
Expand Down Expand Up @@ -447,7 +449,7 @@ internal class ClaimChatPresenter(
},
ifRight = { claimIntent ->
currentContinueButtonLoading = false
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
},
)
}
Expand Down Expand Up @@ -497,7 +499,7 @@ internal class ClaimChatPresenter(
ifRight = { claimIntent ->
if (!steps.updateStepWithSuccess(event.id) { step -> step.clearContent() }) return@launch
currentSkipButtonLoading = false
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
},
)
}
Expand Down Expand Up @@ -544,7 +546,7 @@ internal class ClaimChatPresenter(
},
ifRight = { claimIntent ->
currentContinueButtonLoading = false
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
},
)
}
Expand Down Expand Up @@ -573,7 +575,7 @@ internal class ClaimChatPresenter(
}
currentContinueButtonLoading = false
currentSkipButtonLoading = false
handleNext(steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next)
handleNext(steps, setOutcome, claimIntent.next)
},
)
}
Expand Down Expand Up @@ -656,7 +658,7 @@ internal class ClaimChatPresenter(
ifRight = { claimIntent ->
currentContinueButtonLoading = false
handleNext(
steps, setOutcome, setAutoNavigateForDeflectStepId, claimIntent.next,
steps, setOutcome, claimIntent.next,
)
},
)
Expand All @@ -680,9 +682,7 @@ internal class ClaimChatPresenter(
}

is ClaimChatEvent.HandledDeflectNavigation -> {
if (autoNavigateForDeflectStepId == event.stepId) {
autoNavigateForDeflectStepId = null
}
//todo or remove
}

ClaimChatEvent.DismissConfirmEditDialog -> showConfirmEditDialogForStep = null
Expand All @@ -697,7 +697,6 @@ internal class ClaimChatPresenter(
claimIntentId = claimIntentId!!,
steps = steps,
currentStep = currentStep,
autoNavigateForDeflectStepId = autoNavigateForDeflectStepId,
outcome = outcome,
showFreeTextOverlay = showFreeTextOverlay,
freeText = freeText,
Expand Down Expand Up @@ -776,7 +775,6 @@ private fun SubmitCompleteTaskEffect(
private fun handleNext(
steps: SnapshotStateList<ClaimIntentStep>,
setOutcome: (outcome: ClaimIntentOutcome) -> Unit,
setAutoNavigateForDeflectStepId: (StepId) -> Unit,
next: ClaimIntent.Next,
) {
when (next) {
Expand All @@ -785,9 +783,6 @@ private fun handleNext(
}

is ClaimIntent.Next.Step -> {
if (next.claimIntentStep.stepContent is StepContent.Deflect) {
setAutoNavigateForDeflectStepId(next.claimIntentStep.id)
}
steps.replaceTaskWithNextStep(next.claimIntentStep)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ internal sealed interface StepContent {
val partnersInfo: InfoBlock?,
val content: InfoBlock,
val faq: List<InfoBlock>,
val buttonText: String
) : StepContent {
override val isSkippable: Boolean = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ private fun ClaimIntentStepContentFragment.toStepContent(locale: CommonLocale):
partnersInfo = partnersInfo?.toInfoBlock(),
content = content.toInfoBlock(),
faq = faq.map { it.toInfoBlock() },
buttonText = buttonTitle
)
}

Expand Down
Loading
Loading