409 lines
22 KiB
Kotlin
409 lines
22 KiB
Kotlin
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() {}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |