Skip to content
Merged
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 @@ -288,8 +288,9 @@ fun DeepfakeShieldNavHost(
// Personalization (after permissions, before home)
composable(Screen.Personalization.route) {
com.deepfakeshield.feature.onboarding.PersonalizationScreen(
onComplete = { priorities ->
onComplete = { priorities, country ->
scope.launch {
userPreferences.setUserCountry(country)
userPreferences.setOnboardingCompleted(true)
navController.navigate(Screen.Home.route) {
popUpTo(Screen.Personalization.route) { inclusive = true }
Expand Down Expand Up @@ -400,7 +401,7 @@ fun DeepfakeShieldNavHost(
}

composable(Screen.Education.route) {
EducationScreen(onNavigateBack = { navController.popBackStack() })
EducationScreen(onNavigateBack = { navController.popBackStack() }, userPreferences = userPreferences)
}

composable(Screen.Diagnostics.route) {
Expand Down Expand Up @@ -517,7 +518,7 @@ fun DeepfakeShieldNavHost(
}

composable(Screen.EmergencySos.route) {
EmergencySosScreen(onNavigateBack = { navController.popBackStack() })
EmergencySosScreen(onNavigateBack = { navController.popBackStack() }, userPreferences = userPreferences)
}
composable(Screen.DarkWebMonitor.route) {
DarkWebMonitorScreen(onNavigateBack = { navController.popBackStack() })
Expand Down Expand Up @@ -570,7 +571,7 @@ fun DeepfakeShieldNavHost(
}

composable(Screen.ScamRecovery.route) {
com.deepfakeshield.feature.home.ScamRecoveryScreen(onNavigateBack = { navController.popBackStack() })
com.deepfakeshield.feature.home.ScamRecoveryScreen(onNavigateBack = { navController.popBackStack() }, userPreferences = userPreferences)
}

composable(Screen.WeeklyReport.route) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.deepfakeshield.feature.education

import com.deepfakeshield.data.preferences.UserPreferences

import android.content.Intent
import androidx.compose.animation.*
import androidx.compose.foundation.background
Expand Down Expand Up @@ -29,7 +31,8 @@ import androidx.compose.ui.unit.sp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EducationScreen(
onNavigateBack: () -> Unit = {}
onNavigateBack: () -> Unit = {},
userPreferences: UserPreferences
) {
var selectedTab by rememberSaveable { mutableIntStateOf(0) }
val tabs = listOf("Learn", "Quiz", "Tips")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.deepfakeshield.feature.home

import com.deepfakeshield.data.preferences.UserPreferences

import android.content.Context
import android.content.Intent
import android.net.Uri
Expand Down Expand Up @@ -37,7 +39,7 @@ import kotlinx.coroutines.delay

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EmergencySosScreen(onNavigateBack: () -> Unit) {
fun EmergencySosScreen(onNavigateBack: () -> Unit, userPreferences: UserPreferences) {
val context = LocalContext.current
var emergencyContacts by remember { mutableStateOf(listOf("Emergency Services (911)", "Local Police", "Cyber Crime Helpline")) }
var showAddDialog by remember { mutableStateOf(false) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.deepfakeshield.feature.home

import com.deepfakeshield.data.preferences.UserPreferences

import android.content.Context
import android.content.Intent
import android.net.Uri
Expand Down Expand Up @@ -33,7 +35,7 @@ private data class RecoveryStep(

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScamRecoveryScreen(onNavigateBack: () -> Unit) {
fun ScamRecoveryScreen(onNavigateBack: () -> Unit, userPreferences: UserPreferences) {
val context = LocalContext.current
var expandedStep by remember { mutableIntStateOf(-1) }
var completedSteps by remember { mutableStateOf(setOf<Int>()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ private data class Priority(val id: String, val title: String, val description:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PersonalizationScreen(onComplete: (Set<String>) -> Unit) {
fun PersonalizationScreen(onComplete: (Set<String>, String) -> Unit) {
val haptic = LocalHapticFeedback.current
var selected by remember { mutableStateOf(setOf<String>()) }
var selectedCountry by remember { mutableStateOf("US") }

val priorities = listOf(
Priority("scam_protection", "Scam Protection", "Block scam calls, SMS & phishing", Icons.Default.PhoneDisabled, Color(0xFFF44336)),
Expand Down Expand Up @@ -81,16 +82,41 @@ fun PersonalizationScreen(onComplete: (Set<String>) -> Unit) {
}
}

Spacer(Modifier.height(8.dp))
Spacer(Modifier.height(16.dp))
Divider(color = MaterialTheme.colorScheme.outlineVariant, thickness = 1.dp)
Spacer(Modifier.height(16.dp))

Text("Where are you located?", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
Text("This helps us route reports to the correct authorities and provide local emergency contacts.", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.Center)

Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
listOf("USA" to "US", "India" to "IN").forEach { (name, code) ->
val isCountrySelected = selectedCountry == code
Card(
Modifier.weight(1f).height(60.dp).clip(RoundedCornerShape(12.dp)).clickable {
selectedCountry = code
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
}.then(if (isCountrySelected) Modifier.border(2.dp, MaterialTheme.colorScheme.primary, RoundedCornerShape(12.dp)) else Modifier),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(containerColor = if (isCountrySelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) else MaterialTheme.colorScheme.surface)
) {
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
Text(name, fontWeight = if (isCountrySelected) FontWeight.Bold else FontWeight.Normal, color = if (isCountrySelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface)
}
}
}
}

Spacer(Modifier.height(16.dp))
Button(
onClick = { onComplete(selected) },
onClick = { onComplete(selected, selectedCountry) },
Modifier.fillMaxWidth().height(52.dp),
shape = RoundedCornerShape(16.dp),
enabled = selected.size >= 3
) {
Text(if (selected.size >= 3) "Continue (${selected.size} selected)" else "Select at least 3", fontWeight = FontWeight.SemiBold)
}
TextButton(onClick = { onComplete(emptySet()) }) {
TextButton(onClick = { onComplete(emptySet(), selectedCountry) }) {
Text("Skip for now", color = MaterialTheme.colorScheme.onSurfaceVariant)
}
}
Expand Down
Loading