|
@@ -1,12 +1,16 @@
|
|
|
package com.vpn.fastestvpnservice.screensTV
|
|
|
|
|
|
import android.app.Activity
|
|
|
+import android.app.LocaleManager
|
|
|
import android.content.Context
|
|
|
import android.content.Intent
|
|
|
+import android.os.Build
|
|
|
import android.os.Bundle
|
|
|
import android.os.Handler
|
|
|
+import android.os.LocaleList
|
|
|
import android.util.Log
|
|
|
import androidx.activity.compose.BackHandler
|
|
|
+import androidx.appcompat.app.AppCompatDelegate
|
|
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
|
import androidx.compose.foundation.Image
|
|
|
import androidx.compose.foundation.LocalOverscrollConfiguration
|
|
@@ -34,6 +38,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|
|
import androidx.compose.foundation.verticalScroll
|
|
|
import androidx.compose.material.icons.Icons
|
|
|
import androidx.compose.material.icons.filled.DarkMode
|
|
|
+import androidx.compose.material.icons.filled.Language
|
|
|
+import androidx.compose.material3.BottomSheetDefaults
|
|
|
import androidx.compose.material3.DockedSearchBar
|
|
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
|
import androidx.compose.material3.Icon
|
|
@@ -85,12 +91,14 @@ import androidx.compose.ui.unit.TextUnit
|
|
|
import androidx.compose.ui.unit.dp
|
|
|
import androidx.compose.ui.unit.sp
|
|
|
import androidx.core.content.ContextCompat
|
|
|
+import androidx.core.os.LocaleListCompat
|
|
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
|
import androidx.navigation.NavHostController
|
|
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
|
import com.vpn.fastestvpnservice.R
|
|
|
import com.vpn.fastestvpnservice.beans.Protocol
|
|
|
import com.vpn.fastestvpnservice.beans.isDarkTheme
|
|
|
+import com.vpn.fastestvpnservice.beans.languages
|
|
|
import com.vpn.fastestvpnservice.beans.themesList
|
|
|
import com.vpn.fastestvpnservice.constants.AppEnum
|
|
|
import com.vpn.fastestvpnservice.constants.smartConnect
|
|
@@ -117,6 +125,7 @@ import com.vpn.fastestvpnservice.viewmodels.SplashViewModel
|
|
|
import de.blinkt.openvpn.core.App
|
|
|
import kotlinx.coroutines.delay
|
|
|
import kotlinx.coroutines.launch
|
|
|
+import java.util.Locale
|
|
|
|
|
|
@OptIn(ExperimentalFoundationApi::class)
|
|
|
@Composable
|
|
@@ -195,7 +204,8 @@ fun SettingsTV(navHostController: NavHostController) {
|
|
|
text = "Settings",
|
|
|
size = 28.sp,
|
|
|
color = MaterialTheme.colorScheme.primary,
|
|
|
- style = MaterialTheme.typography.headlineLarge
|
|
|
+ style = MaterialTheme.typography.headlineLarge,
|
|
|
+ isfocusable = true
|
|
|
)
|
|
|
Spacer(modifier = Modifier.height(22.dp))
|
|
|
|
|
@@ -244,7 +254,12 @@ fun SettingsTV(navHostController: NavHostController) {
|
|
|
)
|
|
|
AddRowDarkLightThemeTV(
|
|
|
icon = Icons.Default.DarkMode,
|
|
|
- text = "Appearance")
|
|
|
+ text = "Appearance"
|
|
|
+ )
|
|
|
+ AddLanguageTV(
|
|
|
+ icon = Icons.Default.Language,
|
|
|
+ text = "Language"
|
|
|
+ )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -372,13 +387,15 @@ fun ColumnScope.AddTextSettingsTV(
|
|
|
color: Color,
|
|
|
bottomPadding: Dp = 0.dp,
|
|
|
startPadding: Dp = 0.dp,
|
|
|
- style: TextStyle
|
|
|
+ style: TextStyle,
|
|
|
+ isfocusable: Boolean = false
|
|
|
) {
|
|
|
Text(
|
|
|
text = text,
|
|
|
style = style,
|
|
|
color = color,
|
|
|
modifier = Modifier.padding(bottom = bottomPadding, start = startPadding)
|
|
|
+ .focusable(isfocusable)
|
|
|
)
|
|
|
}
|
|
|
|
|
@@ -1181,12 +1198,9 @@ fun AddRowDarkLightThemeTV(
|
|
|
.clickable {
|
|
|
isThemeSheetOpen = true
|
|
|
}
|
|
|
- .onKeyEvent {
|
|
|
- if (it.type == KeyEventType.KeyDown && it.key == Key.DirectionDown) {
|
|
|
- isSecondItemPressed.value = true
|
|
|
- }
|
|
|
- false
|
|
|
- }
|
|
|
+// .onKeyEvent {
|
|
|
+// false
|
|
|
+// }
|
|
|
.height(61.dp),
|
|
|
horizontalArrangement = Arrangement.Start,
|
|
|
verticalAlignment = Alignment.CenterVertically
|
|
@@ -1347,4 +1361,233 @@ fun AddRowDarkLightThemeTV(
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+@OptIn(ExperimentalMaterial3Api::class)
|
|
|
+@Composable
|
|
|
+fun AddLanguageTV(
|
|
|
+ icon: ImageVector,
|
|
|
+ text: String,
|
|
|
+) {
|
|
|
+ var isRowFocused by remember { mutableStateOf(false) }
|
|
|
+ var isButtonFocused by remember { mutableStateOf(false) }
|
|
|
+ var isAnyItemFocused by remember { mutableStateOf(false) }
|
|
|
+ var isLanguageSheetOpen by remember { mutableStateOf(false) }
|
|
|
+ var isSelectedLanguage by remember { mutableStateOf(languages[0]) }
|
|
|
+ val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
|
|
+ val context = LocalContext.current
|
|
|
+ val basePreferenceHelper = BasePreferenceHelper(context)
|
|
|
+ var selectedLanguage by remember { mutableStateOf(basePreferenceHelper.getLanguage()) }
|
|
|
+
|
|
|
+ Row(
|
|
|
+ modifier = Modifier
|
|
|
+ .fillMaxWidth()
|
|
|
+ .padding(top = 5.dp, end = 27.dp)
|
|
|
+ .clip(RoundedCornerShape(4.dp))
|
|
|
+ .background(
|
|
|
+ if (isRowFocused) MaterialTheme.colorScheme.inverseOnSurface
|
|
|
+ else MaterialTheme.colorScheme.onBackground
|
|
|
+ )
|
|
|
+ .onFocusChanged {
|
|
|
+ isRowFocused = it.isFocused
|
|
|
+ }
|
|
|
+ .focusable()
|
|
|
+ .clickable {
|
|
|
+ isLanguageSheetOpen = true
|
|
|
+ }
|
|
|
+ .onKeyEvent {
|
|
|
+ if (it.type == KeyEventType.KeyDown && it.key == Key.DirectionDown) {
|
|
|
+ isSecondItemPressed.value = true
|
|
|
+ }
|
|
|
+ false
|
|
|
+ }
|
|
|
+ .height(61.dp),
|
|
|
+ horizontalArrangement = Arrangement.Start,
|
|
|
+ verticalAlignment = Alignment.CenterVertically
|
|
|
+ ) {
|
|
|
+
|
|
|
+ Surface(
|
|
|
+ modifier = Modifier.padding(start = 20.dp),
|
|
|
+ color = Color.Transparent
|
|
|
+ ) {
|
|
|
+ Image(
|
|
|
+ imageVector = icon,
|
|
|
+ contentDescription = "Select Theme",
|
|
|
+ modifier = Modifier
|
|
|
+ .padding(start = 0.dp)
|
|
|
+ .size(24.dp)
|
|
|
+ .weight(1f),
|
|
|
+ colorFilter = ColorFilter.tint(
|
|
|
+ MaterialTheme.colorScheme.primary) )
|
|
|
+ }
|
|
|
+
|
|
|
+ Surface(
|
|
|
+ modifier = Modifier.padding(start = 18.dp),
|
|
|
+ color = Color.Transparent
|
|
|
+ ) {
|
|
|
+ Text(text = text,
|
|
|
+ style = MaterialTheme.typography.titleMedium,
|
|
|
+ color = MaterialTheme.colorScheme.primary,
|
|
|
+ maxLines = 1,
|
|
|
+ modifier = Modifier
|
|
|
+ .padding(start = 0.dp, end = 0.dp)
|
|
|
+ .weight(1f)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ Spacer(modifier = Modifier.weight(1f))
|
|
|
+
|
|
|
+ Surface(
|
|
|
+ modifier = Modifier
|
|
|
+ .padding(end = 20.dp)
|
|
|
+ .align(Alignment.CenterVertically),
|
|
|
+ color = Color.Transparent
|
|
|
+
|
|
|
+ ) {
|
|
|
+ Image(
|
|
|
+ painter = painterResource(id = R.drawable.frontarrow3x),
|
|
|
+ contentDescription = "Front_Arrow",
|
|
|
+ modifier = Modifier
|
|
|
+ .padding(start = 0.dp, end = 3.dp)
|
|
|
+ .size(10.dp, 18.dp)
|
|
|
+ .weight(1f),
|
|
|
+ colorFilter = ColorFilter.tint(
|
|
|
+ MaterialTheme.colorScheme.primary
|
|
|
+ )
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isLanguageSheetOpen) {
|
|
|
+ ModalBottomSheet(
|
|
|
+ onDismissRequest = { isLanguageSheetOpen = false
|
|
|
+ },
|
|
|
+ dragHandle = {
|
|
|
+ BottomSheetDefaults.DragHandle(
|
|
|
+ color = MaterialTheme.colorScheme.primary,
|
|
|
+ )
|
|
|
+ },
|
|
|
+ sheetState = sheetState,
|
|
|
+ containerColor = MaterialTheme.colorScheme.onBackground,
|
|
|
+ modifier = Modifier
|
|
|
+ .padding(top = 15.dp)
|
|
|
+ .fillMaxSize()
|
|
|
+ ) {
|
|
|
+ Box(
|
|
|
+ modifier = Modifier
|
|
|
+ .background(Color.Transparent)
|
|
|
+ .fillMaxSize()
|
|
|
+ .padding(start = 0.dp, top = 10.dp, bottom = 20.dp),
|
|
|
+ ) {
|
|
|
+ Column(
|
|
|
+ verticalArrangement = Arrangement.Top,
|
|
|
+ horizontalAlignment = Alignment.Start,
|
|
|
+ modifier = Modifier
|
|
|
+ .verticalScroll(rememberScrollState())
|
|
|
+ .padding(bottom = 10.dp)
|
|
|
+ ) {
|
|
|
+ AddTextSettings(
|
|
|
+ text = context.getString(R.string.language),
|
|
|
+ size = 18.sp,
|
|
|
+ color = MaterialTheme.colorScheme.primary,
|
|
|
+ bottomPadding = 20.dp,
|
|
|
+ startPadding = 16.dp,
|
|
|
+ style = MaterialTheme.typography.titleSmall,
|
|
|
+ isFocusable = true
|
|
|
+ )
|
|
|
+ languages.forEach { language ->
|
|
|
+ isButtonFocused = isSelectedLanguage == language
|
|
|
+ Row(
|
|
|
+ modifier = Modifier
|
|
|
+ .fillMaxWidth()
|
|
|
+ .background(
|
|
|
+ if (isButtonFocused && isAnyItemFocused) MaterialTheme.colorScheme.inverseOnSurface
|
|
|
+ else Color.Transparent
|
|
|
+ )
|
|
|
+ .padding(start = 2.dp)
|
|
|
+ .onFocusChanged {
|
|
|
+ if (it.isFocused) {
|
|
|
+ isSelectedLanguage = language
|
|
|
+ }
|
|
|
+ isAnyItemFocused = it.isFocused
|
|
|
+ }
|
|
|
+ .selectable(
|
|
|
+ selected = language.name == selectedLanguage,
|
|
|
+ onClick = {
|
|
|
+ selectedLanguage = language.name
|
|
|
+ basePreferenceHelper.saveLanguage(selectedLanguage)
|
|
|
+
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
|
+ context.getSystemService(LocaleManager::class.java).applicationLocales =
|
|
|
+ LocaleList.forLanguageTags(language.code)
|
|
|
+ } else {
|
|
|
+ AppCompatDelegate.setApplicationLocales(
|
|
|
+ LocaleListCompat.forLanguageTags(
|
|
|
+ language.code
|
|
|
+ )
|
|
|
+ )
|
|
|
+ context.resources.updateConfiguration(
|
|
|
+ context.resources.configuration.apply {
|
|
|
+ setLocale(Locale.forLanguageTag(language.code))
|
|
|
+ },
|
|
|
+ context.resources.displayMetrics
|
|
|
+ )
|
|
|
+// changeLanguage(context.getString(R.string.settings))
|
|
|
+ }
|
|
|
+ isLanguageSheetOpen = false
|
|
|
+ },
|
|
|
+ )
|
|
|
+// .indication(
|
|
|
+// indication = null,
|
|
|
+// interactionSource = remember {
|
|
|
+// MutableInteractionSource()
|
|
|
+// }
|
|
|
+// )
|
|
|
+ ,
|
|
|
+ verticalAlignment = Alignment.CenterVertically
|
|
|
+ ) {
|
|
|
+// val themeState = isSystemInDarkTheme()
|
|
|
+// val isSystemInDarkTheme by remember { mutableStateOf(themeState) }
|
|
|
+ RadioButton(
|
|
|
+ selected = language.name == selectedLanguage,
|
|
|
+ onClick = {
|
|
|
+ selectedLanguage = language.name
|
|
|
+ basePreferenceHelper.saveLanguage(selectedLanguage)
|
|
|
+
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
|
+ context.getSystemService(LocaleManager::class.java).applicationLocales =
|
|
|
+ LocaleList.forLanguageTags(language.code)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ AppCompatDelegate.setApplicationLocales(
|
|
|
+ LocaleListCompat.forLanguageTags(
|
|
|
+ language.code
|
|
|
+ )
|
|
|
+ )
|
|
|
+ context.resources.updateConfiguration(
|
|
|
+ context.resources.configuration.apply {
|
|
|
+ setLocale(Locale.forLanguageTag(language.code))
|
|
|
+ },
|
|
|
+ context.resources.displayMetrics
|
|
|
+ )
|
|
|
+// changeLanguage(context.getString(R.string.settings))
|
|
|
+ }
|
|
|
+ isLanguageSheetOpen = false
|
|
|
+ },
|
|
|
+ colors = RadioButtonDefaults.colors(
|
|
|
+ selectedColor = colorResource(id = R.color.radio_button_blue),
|
|
|
+ unselectedColor = colorResource(id = R.color.gray_icon),
|
|
|
+ )
|
|
|
+ )
|
|
|
+ Text(text = language.name,
|
|
|
+ modifier = Modifier.padding(start = 12.dp),
|
|
|
+ style = MaterialTheme.typography.bodySmall,
|
|
|
+ color = MaterialTheme.colorScheme.primary
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|