package com.sffteam.voidclient.preferences import android.os.Bundle import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBackIos import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.size import androidx.compose.material.icons.outlined.Lock import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.platform.LocalContext import com.sffteam.voidclient.AccountManager import com.sffteam.voidclient.OPCode import com.sffteam.voidclient.SocketManager import com.sffteam.voidclient.ui.theme.AppTheme import kotlinx.coroutines.launch import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject class SecurityActivity : ComponentActivity() { @OptIn(ExperimentalMaterial3Api::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() val forSettings = mapOf( "HIDDEN" to mapOf("Контакты" to false, "Никто" to true), "CONTENT_LEVEL_ACCESS" to mapOf("Весь" to false, "Безопасный" to true), "CHATS_INVITE" to mapOf("Все" to "ALL", "Контакты" to "CONTACTS"), "SEARCH_BY_PHONE" to mapOf("Все" to "ALL", "Контакты" to "CONTACTS"), "INCOMING_CALL" to mapOf("Все" to "ALL", "Контакты" to "CONTACTS"), ) setContent { val coroutineScope = rememberCoroutineScope() val settings by AccountManager.settings.collectAsState() val sheetState = rememberModalBottomSheetState() val safeMode = remember { mutableStateOf(settings.safeMode) } val context = LocalContext.current var showBottomSheet by remember { mutableStateOf(false) } val selectedSettings = remember { mutableStateOf("") } if (AccountManager.sessionsList.value.isEmpty()) { val packet = SocketManager.packPacket(OPCode.SESSIONS.opcode, JsonObject(emptyMap())) coroutineScope.launch { SocketManager.sendPacket(packet, { packet -> if (packet.payload is JsonObject) { AccountManager.processSession(packet.payload["sessions"]!!.jsonArray) } }) } } AppTheme { LaunchedEffect(settings) { safeMode.value = settings.safeMode } if (showBottomSheet) { ModalBottomSheet( onDismissRequest = { showBottomSheet = false }, sheetState = sheetState ) { Column( verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.padding(start = 8.dp) ) { forSettings[selectedSettings.value]?.forEach { (index, value) -> Text(index, modifier = Modifier.clickable { val packet = SocketManager.packPacket(OPCode.SETTINGS_CHANGE.opcode, JsonObject( mapOf( "settings" to JsonObject( mapOf( "user" to JsonObject( mapOf( if (value is String) { selectedSettings.value to JsonPrimitive(value) } else if (value is Boolean) { selectedSettings.value to JsonPrimitive(value) } else { selectedSettings.value to JsonPrimitive("") } ) ) ) ) ) )) coroutineScope.launch { SocketManager.sendPacket(packet, { packet -> if (packet.payload is JsonObject) { AccountManager.processSettings(packet.payload["user"]!!.jsonObject) } }) } showBottomSheet = false } .padding(8.dp), fontSize = 24.sp) } } } } Scaffold( topBar = { TopAppBar( colors = TopAppBarDefaults.topAppBarColors( containerColor = colorScheme.surfaceContainer, ), title = { Text("Безопасность") }, navigationIcon = { IconButton({ finish() }) { Icon( Icons.AutoMirrored.Filled.ArrowBackIos, contentDescription = "Меню" ) } }, ) }) { Box( modifier = Modifier .padding(it) .fillMaxSize() ) { LazyColumn( modifier = Modifier .fillMaxSize() .padding(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp), ) { item() { Box( modifier = Modifier .background( colorScheme.secondaryContainer, shape = RoundedCornerShape(20.dp) ) .fillMaxWidth() .padding(start = 4.dp, top = 4.dp, end = 4.dp) ) { Column(modifier = Modifier .padding(bottom = 8.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) { Row(verticalAlignment = Alignment.CenterVertically) { Icon( Icons.Outlined.Lock, contentDescription = "lol", modifier = Modifier.size(40.dp).padding(start = 8.dp) ) Text("Безопасный режим", fontSize = 24.sp, modifier = Modifier.padding(start = 8.dp)) Spacer(modifier = Modifier.weight(1f)) Switch( checked = safeMode.value, onCheckedChange = { val packet = SocketManager.packPacket(OPCode.SETTINGS_CHANGE.opcode, JsonObject( mapOf( "settings" to JsonObject( mapOf( "user" to JsonObject( mapOf( "SAFE_MODE" to JsonPrimitive(it) ) ) ) ) ) )) coroutineScope.launch { SocketManager.sendPacket(packet, { packet -> if (packet.payload is JsonObject) { AccountManager.processSettings(packet.payload["user"]!!.jsonObject) } }) } }, modifier = Modifier.padding(end = 4.dp) ) } Row(modifier = Modifier .clickable { if (settings.safeMode) { Toast.makeText( context, "Отключите безопасный режим, чтобы изменить эту настройку", Toast.LENGTH_SHORT ).show() } else { selectedSettings.value = "SEARCH_BY_PHONE" showBottomSheet = true } }) { Text("Найти меня по номеру", fontSize = 20.sp, modifier = Modifier.padding(start = 8.dp)) val whoCan = if (settings.searchByPhone == "ALL") { "Все" } else { "Контакты" } Spacer(modifier = Modifier.weight(1f)) if (settings.safeMode) { Icon( Icons.Outlined.Lock, contentDescription = "lol", modifier = Modifier.size(25.dp).padding(start = 4.dp, end = 4.dp) ) } Text(whoCan, fontSize = 20.sp, modifier = Modifier.padding(end = 8.dp)) } Row(modifier = Modifier .clickable { if (settings.safeMode) { Toast.makeText( context, "Отключите безопасный режим, чтобы изменить эту настройку", Toast.LENGTH_SHORT ).show() } else { selectedSettings.value = "INCOMING_CALL" showBottomSheet = true } }) { Text("Позвонить", fontSize = 20.sp, modifier = Modifier.padding(start = 8.dp)) val whoCan = if (settings.incomingCall == "ALL") { "Все" } else { "Контакты" } Spacer(modifier = Modifier.weight(1f)) if (settings.safeMode) { Icon( Icons.Outlined.Lock, contentDescription = "lol", modifier = Modifier.size(25.dp).padding(start = 4.dp, end = 4.dp) ) } Text(whoCan, fontSize = 20.sp, modifier = Modifier.padding(end = 8.dp)) } Row(modifier = Modifier .clickable { if (settings.safeMode) { Toast.makeText( context, "Отключите безопасный режим, чтобы изменить эту настройку", Toast.LENGTH_SHORT ).show() } else { selectedSettings.value = "CHATS_INVITE" showBottomSheet = true } }) { Text("Приглашения в чат", fontSize = 20.sp, modifier = Modifier.padding(start = 8.dp)) val whoCan = if (settings.chatsInvite == "ALL") { "Все" } else { "Контакты" } Spacer(modifier = Modifier.weight(1f)) if (settings.safeMode) { Icon( Icons.Outlined.Lock, contentDescription = "lol", modifier = Modifier.size(25.dp).padding(start = 4.dp, end = 4.dp) ) } Text(whoCan, fontSize = 20.sp, modifier = Modifier.padding(end = 8.dp)) } Row(modifier = Modifier .clickable { if (settings.safeMode) { Toast.makeText( context, "Отключите безопасный режим, чтобы изменить эту настройку", Toast.LENGTH_SHORT ).show() } else { selectedSettings.value = "CONTENT_LEVEL_ACCESS" showBottomSheet = true } }) { Text("Показывать контент", fontSize = 20.sp, modifier = Modifier.padding(start = 8.dp)) val content = if (!settings.contentLevelAccess) { "Весь" } else { "Безопасный" } Spacer(modifier = Modifier.weight(1f)) if (settings.safeMode) { Icon( Icons.Outlined.Lock, contentDescription = "lol", modifier = Modifier.size(25.dp).padding(start = 4.dp, end = 4.dp) ) } Text(content, fontSize = 20.sp, modifier = Modifier.padding(end = 8.dp)) } } } } item() { Box( modifier = Modifier .background( colorScheme.secondaryContainer, shape = RoundedCornerShape(20.dp) ) .fillMaxWidth() .padding(start = 4.dp, top = 4.dp, end = 4.dp) ) { Column() { Text( "Информация", fontSize = 22.sp, color = colorScheme.primary, modifier = Modifier.padding(start = 8.dp, bottom = 8.dp) ) Row(modifier = Modifier .clickable { selectedSettings.value = "HIDDEN" showBottomSheet = true } .padding(bottom = 8.dp)) { Text("Статус \"В сети\"", fontSize = 20.sp, modifier = Modifier.padding(start = 8.dp)) val hidden = if (settings.hidden) { "Никто" } else { "Контакты" } Spacer(modifier = Modifier.weight(1f)) Text(hidden, fontSize = 20.sp, modifier = Modifier.padding(end = 8.dp)) } } } } item() {} } } } } } } }