package com.vpn.fastestvpnservice.screensTV //import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.act import android.content.Context import android.os.Build import android.os.Handler import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.animation.animateColorAsState import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.focusable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.ClickableText import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ThumbDown import androidx.compose.material.icons.outlined.ThumbUp import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.paint import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.input.key.Key import androidx.compose.ui.input.key.KeyEventType import androidx.compose.ui.input.key.key import androidx.compose.ui.input.key.onKeyEvent import androidx.compose.ui.input.key.type import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.window.DialogProperties import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import com.vpn.fastestvpnservice.MainActivity import com.vpn.fastestvpnservice.R import com.vpn.fastestvpnservice.beans.Protocol import com.vpn.fastestvpnservice.beans.Server import com.vpn.fastestvpnservice.beans.isDarkTheme import com.vpn.fastestvpnservice.beans.toChangeServer import com.vpn.fastestvpnservice.constants.AppEnum import com.vpn.fastestvpnservice.constants.smartConnect import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper import com.vpn.fastestvpnservice.interfaces.ServerCallbacksTV import com.vpn.fastestvpnservice.navigation.isFirstItemFocused import com.vpn.fastestvpnservice.navigation.isFirstItemPressed import com.vpn.fastestvpnservice.navigation.isHomeScreenPressed import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.StringDown import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.StringDownUnit import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.StringUp import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.StringUpUnit import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.isServerDialog import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.navHostController1 import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.protocolObj import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.serverObj import com.vpn.fastestvpnservice.screens.serverListViewModelSplash import com.vpn.fastestvpnservice.sealedClass.ScreenTV import com.vpn.fastestvpnservice.ui.theme.customTypography import com.vpn.fastestvpnservice.ui.theme.customTypography2 import com.vpn.fastestvpnservice.utils.Utils import com.vpn.fastestvpnservice.utils.VPNConnectionsUtil import com.vpn.fastestvpnservice.utils.isTablet import com.vpn.fastestvpnservice.viewmodels.HomeViewModel import com.vpn.fastestvpnservice.viewmodels.ServerListViewModel import com.wireguard.android.backend.GoBackend import de.blinkt.openvpn.core.App import java.util.Locale lateinit var vpnConnectionsUtil: VPNConnectionsUtil var isProtocolDialog: MutableState = mutableStateOf(false) var isLocationsEnabled: MutableState = mutableStateOf(false) var isDedicatedIpEnabled: MutableState = mutableStateOf(false) var isStreamingEnabled: MutableState = mutableStateOf(false) var isDvpnEnabled: MutableState = mutableStateOf(false) var isP2pEnabled: MutableState = mutableStateOf(false) var locations: MutableList = ArrayList() var dedicatedIP: MutableList = ArrayList() var streaming: MutableList = ArrayList() var dvpn: MutableList = ArrayList() var p2p: MutableList = ArrayList() val onServerTV = object : ServerCallbacksTV { @Composable override fun onServerSelected( context: Context, homeViewModel: HomeViewModel, onClick: () -> Unit, isServerDialogShown: Boolean, server: Server ) { val vpnConnectionsUtil = VPNConnectionsUtil(context, activityGlobal, homeViewModel) val basePreferenceHelper = BasePreferenceHelper(context) // val serverListViewModel: ServerListViewModel = viewModel{ // ServerListViewModel(context) // } Log.d("ServerCallbacks", "onServerSelected called! : ${server.server_name}") val lastServer = basePreferenceHelper.getConnectedServer() val connectState = basePreferenceHelper.getConnectState() if (isServerDialogShown) { Log.d("ServerCallbacks", "onServerSelected true!") if (connectState == 2) { Log.d("ServerCallbacks", "onServerSelected isVPNConnected!") if (lastServer?.id != server.id) { isServerDialog.value = true serverObj.value = server } else { basePreferenceHelper.setConnectedServer(server) basePreferenceHelper.setServerObject(server) } } else { serverListViewModelSplash.setRecentlyConnectedServer(server) basePreferenceHelper.setConnectedServer(server) basePreferenceHelper.setServerObject(server) vpnConnectionsUtil.startVpn() } } else { Log.d("ServerCallbacks", "onServerSelected else") vpnConnectionsUtil.startVpn() } MainActivity.isSelectedServersShown = true onClick() } override fun onChangeProtocol( protocol: Protocol, context: Context, serverListViewModel: ServerListViewModel ) { val prefHelper = BasePreferenceHelper(context) // val wg = VPNConnectionsUtil(context, act , homeViewModel1) protocolObj.value = protocol val connectState = prefHelper.getConnectState() if (getEnableProtocols(protocol.title, prefHelper)) { Log.d("OnChangeProtocol", "getEnableProtocols yes!") if (prefHelper.getProtocol().index != protocol.index) { if (connectState == 2) { navHostController1.popBackStack() isProtocolDialog.value = true } else { prefHelper.saveProtocol(protocol = protocol) val lastServer = prefHelper.getConnectedServer() val serverList = prefHelper.getServerData() // val serverList = serverListViewModelSplash.liveDataGetServersGlobal.value if (lastServer != null) { val serverProtocol = serverListViewModel.getFilteredServerByProtocolChanged(serverList, lastServer, protocol) if (serverProtocol.isFound) { prefHelper.setServerObject(serverProtocol.server) val lastServer1 = prefHelper.getServerObject() } } serverListViewModelSplash.setCountryDataTV() } } } else { // Screen.Subscription.isTrue = true // navHostController1.let { // it.navigate(Screen.Subscription.route) // } } } } lateinit var activityGlobal: ComponentActivity @Composable fun HomeTV( navHostController: NavHostController, settingsNavHostController: NavHostController, activity: ComponentActivity ) { activityGlobal = activity navHostController1 = navHostController val context = LocalContext.current val basePreferenceHelper = BasePreferenceHelper(context) val prefHelper = BasePreferenceHelper(context) val scope = rememberCoroutineScope() val homeViewModel: HomeViewModel = viewModel{ HomeViewModel(context, scope) } var isConnect: Int? = homeViewModel.isConnect.observeAsState().value isConnect = basePreferenceHelper.getConnectState() val focusRequester1 = remember { FocusRequester() } val focusRequester2 = remember { FocusRequester() } val focusRequester3 = remember { FocusRequester() } var isButtonFocused by remember { mutableStateOf(false) } val vpnConnectionsUtil = VPNConnectionsUtil(context, activity, homeViewModel) OnLifecycleEvent { owner, event -> when (event) { Lifecycle.Event.ON_RESUME -> { Log.d("test_home_resume", "ON_RESUME: Home Screen!") navHostController1 = navHostController try { App.backend?.runningTunnelNames } catch (e: Exception) { val back = GoBackend(context) App.setBackend(back) App.backend = App.getBackend() } vpnConnectionsUtil.onResumeCallBack() homeViewModel.getIp() // var filterServerByConnectionCount = Server() // if (prefHelper.getServerObject() != null) { // prefHelper.getServerObject()?.let { // filterServerByConnectionCount = it // } // } else { // val smartServer = basePreferenceHelper.getSmartServerObject() // smartServer?.let { // filterServerByConnectionCount = it // } // } // // server = filterServerByConnectionCount // //// splashViewModel.serverDataApi() homeViewModel.validatePassword( prefHelper.getUser()?.userinfo?.email.toString(), prefHelper.getPassword().toString(), "TV", Build.VERSION.RELEASE ) } Lifecycle.Event.ON_PAUSE -> { Log.d("test_home_resume", "ON_PAUSE: Home Screen!") vpnConnectionsUtil.onPauseCallBack() } Lifecycle.Event.ON_STOP -> { Log.d("test_home_resume", "ON_STOP: Home Screen!") vpnConnectionsUtil.onStopCallBack() } Lifecycle.Event.ON_DESTROY -> { Log.d("test_home_resume", "ON_DESTROY: Home Screen!") vpnConnectionsUtil.onPauseCallBack() } else -> { Log.d("test_home_resume", "else: Home Screen!") } } } val validateResponse = homeViewModel.liveDataValidate.observeAsState().value validateResponse?.let { Log.d("test_api_validate", "home => ${it.status} ${it.message}") if (!it.status) { basePreferenceHelper.setLoggedInState(false) basePreferenceHelper.clearAllData() settingsNavHostController.popBackStack() settingsNavHostController.navigate(ScreenTV.LoginTV.route) } homeViewModel._mutableLiveDataValidate.value = null } if (isHomeScreenPressed.value) { LaunchedEffect(key1 = Unit) { focusRequester1.requestFocus() } isHomeScreenPressed.value = false } var isLaunched by rememberSaveable { mutableStateOf(true) } if (isLaunched) { Log.d("test_launch","liveDataGetServersGlobal") val countries = serverListViewModelSplash.liveDataGetServersGlobal.value countries?.forEachIndexed { index, serverData -> Log.d("test_serverlist_tv","$index ${serverData?.name} ${serverData?.servers?.size}") if (serverData?.name?.equals("Servers") == true) { serverData.servers?.let { locations = it } if (locations.size > 0) isLocationsEnabled.value = true } else if (serverData?.name?.equals("Dedicated IP") == true) { serverData.servers?.let { dedicatedIP = it } if (dedicatedIP.size > 0) isDedicatedIpEnabled.value = true } else if (serverData?.name?.equals("Streaming") == true) { serverData.servers?.let { streaming = it } if (streaming.size > 0) isStreamingEnabled.value = true } else if (serverData?.name?.equals("D-VPN") == true) { serverData.servers?.let { dvpn = it } if (dvpn.size > 0) isDvpnEnabled.value = true } else if (serverData?.name?.equals("P2P") == true) { serverData.servers?.let { p2p = it } if (p2p.size > 0) isP2pEnabled.value = true } } isLaunched = false } // BackHandler { // Toast.makeText( // context, "BackHandler Home TV", Toast.LENGTH_SHORT // ).show() // } Column( modifier = Modifier .background(MaterialTheme.colorScheme.background) .fillMaxSize(), ) { if (isServerDialog.value) { ShowServerDialogTV( basePreferenceHelper, vpnConnectionsUtil ) } if (isProtocolDialog.value) { isFirstItemPressed.value = true isFirstItemFocused.value = true ShowProtocolDialogTV( basePreferenceHelper, vpnConnectionsUtil, serverListViewModelSplash ) } // 1st box ConstraintLayout(modifier = Modifier .fillMaxSize() .weight(0.6f) .background(Color.Transparent) ) { val (firstComposable, secondComposable) = createRefs() val guideline = createGuidelineFromTop(0.7f) Box( modifier = Modifier .constrainAs(firstComposable) { top.linkTo(parent.top) bottom.linkTo(guideline) start.linkTo(parent.start) end.linkTo(parent.end) width = Dimension.fillToConstraints height = Dimension.fillToConstraints } .background(Color.Transparent) ) { Image( modifier = Modifier .fillMaxWidth() .fillMaxHeight() .padding(top = 0.dp), // painter = if (isConnect == App.CONNECTED) blueBackgroundTV() else pinkBackgroundTV(), painter = if (isConnect == App.CONNECTED) blueBackgroundTV() else pinkBackgroundTV(), contentDescription = "Background Color", contentScale = ContentScale.FillBounds, ) Image( modifier = Modifier .fillMaxWidth() .fillMaxHeight() .padding(bottom = 0.dp) .alpha(if (isDarkTheme.value) 0.1F else 0.6F), // .alpha(0.6F), painter = painterResource(id = R.drawable.map_home3x), contentDescription = "Home Map", contentScale = ContentScale.FillWidth, ) Column( modifier = Modifier .fillMaxWidth() .fillMaxHeight() .padding(bottom = 85.dp) // .offset(y = -(118).dp) .background(Color.Transparent), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Bottom ) { val serverObj = basePreferenceHelper.getConnectedServer() val serverDis = basePreferenceHelper.getIpinfo() var ipInfo = homeViewModel.mutableLiveDataIpInfo.observeAsState().value?.query ipInfo = if (isConnect == App.CONNECTED) serverObj?.ip.toString() else serverDis?.query AddText( text = "IP ${ipInfo ?: ""}", size = 18.sp, // color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary, style = MaterialTheme.typography.customTypography.headlineLarge.copy( fontSize = 18.sp ) ) Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .background(Color.Transparent) .padding(top = 5.dp) ) { if (isConnect == App.CONNECTED) { val image = Utils.getDrawable(context, serverObj?.iso) if (image != 0) { Image( painter = painterResource(id = image), contentDescription = "Country", modifier = Modifier .padding(end = 6.dp) .size(15.dp) .clip(CircleShape) .paint( painter = painterResource(id = image), contentScale = ContentScale.FillBounds ) ) } AddText( text = "${serverObj?.server_name ?: ""}, ${serverObj?.country ?: ""}", size = 16.sp, color = MaterialTheme.colorScheme.primary, isTablet() ) } else { val image = Utils.getDrawable(context, serverDis?.countryCode) Log.d("image_logo", "$image ${serverDis?.countryCode}") if (image != 0) { Image( painter = painterResource(id = image), contentDescription = "Server", modifier = Modifier .padding(end = 6.dp) .size(15.dp) .clip(CircleShape) .paint( painter = painterResource(id = image), contentScale = ContentScale.FillBounds ) ) } AddText( text = "${serverDis?.city ?: ""}, ${serverDis?.country ?: ""}", size = 16.sp, color = MaterialTheme.colorScheme.primary, isTablet() ) } } when (isConnect) { App.CONNECTED -> { AddText( text = "Connected", size = 18.sp, color = MaterialTheme.colorScheme.surfaceContainerHigh, // color = colorResource(id = R.color.light_blue_2), style = MaterialTheme.typography.customTypography.displaySmall.copy( fontSize = 18.sp ) ) } App.DISCONNECTED -> { AddText( text = "Disconnected", size = 18.sp, color = MaterialTheme.colorScheme.surfaceTint, // color = colorResource(id = R.color.maroon_text), style = MaterialTheme.typography.customTypography.displaySmall.copy( fontSize = 18.sp ) ) } App.CONNECTING -> { AddText( text = "Connecting...", size = 18.sp, color = MaterialTheme.colorScheme.surfaceTint, // color = colorResource(id = R.color.maroon_text), style = MaterialTheme.typography.customTypography.displaySmall.copy( fontSize = 18.sp ) ) } } } } Box( modifier = Modifier .constrainAs(secondComposable) { top.linkTo(guideline) bottom.linkTo(firstComposable.bottom) start.linkTo(parent.start) end.linkTo(parent.end) width = Dimension.value(150.dp) height = Dimension.value(150.dp) } .background(Color.Transparent) ) { val color = if (isButtonFocused && isConnect == App.CONNECTED) colorResource(id = R.color.dark_blue_gray_text) else if (isButtonFocused) colorResource(id = R.color.maroon_text) else colorResource(id = R.color.transparent) IconButton( onClick = { // Toast.makeText( // context, "Connect onClick{}", Toast.LENGTH_SHORT // ).show() // val connectedServer = basePreferenceHelper.getConnectedServer() // val serverObject = basePreferenceHelper.getServerObject() // Log.d( // "test_conn_ser_obj", // "cs = ${connectedServer?.server_name} so = ${serverObject?.server_name}" // ) // Log.d("isConnect_State", "onClick{} -> $isConnect") // Log.d("isConnect_State_vpn", "onClick{} -> $isConnect") // prefHelper.getProduct()?.identifier.let { // val identifier = it // // if (identifier == AppEnum.FREE.key) { // Log.d("isConnect_State", "identifier -> $identifier") // Screen.Subscription.isTrue = true // navHostController.navigate( // Screen.Subscription.route // ) // // } else { // // prefHelper.getServerObject()?.let { // prefHelper.setConnectedServer(it) // } // Log.d("isConnect_State", "identifier -> $identifier") // if (isConnect == App.CONNECTED || isConnect == App.CONNECTING) { // Log.d("isConnect_State_vpn", "stopVPN") // vpnConnectionsUtil.stopVpn() // homeViewModel.getIp() // } else { // Log.d("isConnect_State_vpn", "startVPN") // // if (basePreferenceHelper.getServerObject() != null) { // vpnConnectionsUtil.startVpn() // } else { // toChangeServer.value = false // navHostController.navigate( // Screen.ServerList.route // ) // Screen.ServerList.isTrue = true // Log.d("button_click_change", "Pressed") // } // } // // // val widgetIntent = Intent(context, SimpleAppWidget::class.java) // widgetIntent.action = SimpleAppWidget.ACTION_CHANGE_SERVER // context.sendBroadcast(widgetIntent) // } // } }, modifier = Modifier .padding(bottom = 0.dp) .size(150.dp) .onKeyEvent { when (it.key) { Key.DirectionDown -> { Log.d("test_settings_keys", "DirectionDown") if (it.type == KeyEventType.KeyDown) { focusRequester2.requestFocus() } true } else -> { true } } } .focusRequester(focusRequester1) .background(Color.Transparent) .onFocusChanged { isButtonFocused = it.isFocused } .clickable { val connectedServer = basePreferenceHelper.getConnectedServer() val serverObject = basePreferenceHelper.getServerObject() prefHelper.getProduct()?.identifier.let { val identifier = it if (identifier == AppEnum.FREE.key) { } else { Log.d("isConnect_State_vpn", "else connect button $isConnect") prefHelper .getServerObject() ?.let { Log.d( "isConnect_State_vpn", "getServerObject ${it.server_name}" ) prefHelper.setConnectedServer(it) } if (isConnect == App.CONNECTED || isConnect == App.CONNECTING) { Log.d("isConnect_State_vpn", "stopVPN") vpnConnectionsUtil.stopVpn() homeViewModel.getIp() } else { Log.d("isConnect_State_vpn", "Disconnected") if (basePreferenceHelper.getServerObject() != null) { Log.d("isConnect_State_vpn", "startVpn") vpnConnectionsUtil.startVpn() } else { Log.d("isConnect_State_vpn", "else ServerListTV") toChangeServer.value = false navHostController.navigate( ScreenTV.ServerListTV.route ) } } } } // if (isConnect == App.DISCONNECTED) homeViewModel.setConnectState(App.CONNECTED) // else if (isConnect == App.CONNECTED) homeViewModel.setConnectState(App.DISCONNECTED) } .focusable() , ) { if (isConnect == App.CONNECTED) { Image( painter = if (isDarkTheme.value) painterResource(id = R.drawable.iv_connect_dark) else painterResource(id = R.drawable.iv_connect), // painter = painterResource(id = R.drawable.iv_connect), contentDescription = "Home Map", contentScale = ContentScale.FillBounds, modifier = Modifier .size(150.dp) .border( BorderStroke( 2.dp, color ), shape = CircleShape ) ) } else { Image( painter = if (isDarkTheme.value) painterResource(id = R.drawable.iv_disconnect_dark) else painterResource(id = R.drawable.iv_disconnect), // painter = painterResource(id = R.drawable.iv_disconnect), contentDescription = "Home Map", contentScale = ContentScale.FillBounds, modifier = Modifier .size(150.dp) .border( BorderStroke( 2.dp, color ), shape = CircleShape ) ) } } } } // 2nd box Box( modifier = Modifier .background(MaterialTheme.colorScheme.background) .fillMaxSize() .weight(0.4f) // .background(Color.Transparent), ) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center ) { if (isConnect != App.CONNECTED) { Box( modifier = Modifier .fillMaxWidth(fraction = 0.4f) .padding(horizontal = 0.dp) .padding(vertical = 2.dp) .height(90.dp) .border( border = BorderStroke(2.dp, MaterialTheme.colorScheme.onBackground), shape = RoundedCornerShape(28.dp) ) .background( shape = RoundedCornerShape(28.dp), color = MaterialTheme.colorScheme.onBackground ) .align(Alignment.CenterHorizontally), ) { AddRowSmartTV( navHostController, basePreferenceHelper, context, isTablet(), focusRequester2, homeViewModel ) var smartServer = basePreferenceHelper.getSmartServerObject() val recommended = basePreferenceHelper.getRecommendedServerObject() val selectedSmartList = basePreferenceHelper.getSmartList() var isSmartButtonFocused by remember { mutableStateOf(false) } when(selectedSmartList) { smartConnect[0] -> { smartServer = basePreferenceHelper.getRecommendedServerObject() } smartConnect[1] -> { smartServer = basePreferenceHelper.getSmartServerObject() ?: recommended } smartConnect[2] -> { smartServer = basePreferenceHelper.getSmartServerObject() ?: recommended } else -> {} } val color = if (isSmartButtonFocused && isConnect == App.CONNECTED) MaterialTheme.colorScheme.primary else if (isSmartButtonFocused) MaterialTheme.colorScheme.primary else colorResource(id = R.color.blue_text) Button( onClick = {}, modifier = Modifier .padding(start = 14.dp, end = 14.dp, bottom = 6.dp, top = 12.dp) .align(Alignment.BottomCenter) .background( MaterialTheme.colorScheme.onBackground, RoundedCornerShape(16.dp) ) .border(2.dp, color, RoundedCornerShape(16.dp)) .onFocusChanged { isSmartButtonFocused = it.isFocused } .onKeyEvent { when (it.key) { Key.DirectionLeft -> { true } Key.DirectionRight -> { true } else -> false } } // .focusable() .clickable { Log.d( "test_button", "onClick Smart Connect ${smartServer?.server_name}" ) basePreferenceHelper.setSmartServerObject(smartServer) if (isConnect == App.CONNECTED) { Log.d("isConnect_State_vpn", "stopVPN") val lastServer = basePreferenceHelper.getConnectedServer() Log.d( "test_conn_ser_obj", "smart => ${lastServer?.server_name} ${smartServer?.server_name}" ) if (lastServer?.id != smartServer?.id) { isServerDialog.value = true if (smartServer != null) { serverObj.value = smartServer } } else { vpnConnectionsUtil.stopVpn() } // vpnConnectionsUtil.stopVpn() // Handler().postDelayed(Runnable { // vpnConnectionsUtil.startVpn() // }, 500) // homeViewModel.getIp() } else if (isConnect == App.CONNECTING) { vpnConnectionsUtil.stopVpn() } else if (isConnect == App.DISCONNECTED) { Log.d("isConnect_State_vpn", "startVPN") basePreferenceHelper.setConnectedServer(smartServer) if (smartServer != null) { serverListViewModelSplash.setRecentlyConnectedServer( smartServer ) } vpnConnectionsUtil.startVpn() } } .fillMaxWidth() .height(35.dp), shape = RoundedCornerShape(16.dp), colors = ButtonDefaults.buttonColors( contentColor = colorResource(id = R.color.white), containerColor = colorResource(id = R.color.blue_text), ), ) { Text( text = "Smart Connect", style = MaterialTheme.typography.customTypography.labelLarge.copy( fontSize = 16.sp, lineHeight = 0.sp ), modifier = Modifier.background(Color.Transparent) ) } } /* Select Server Box*/ // if (isConnect != App.CONNECTED) { } // Spacer(modifier = Modifier.weight(1f)) var isLayoutFocused by remember { mutableStateOf(false) } val color = if (isLayoutFocused && isConnect == App.CONNECTED) MaterialTheme.colorScheme.primary else if (isLayoutFocused) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onBackground Box( modifier = Modifier .fillMaxWidth(fraction = 0.4f) .padding(horizontal = 0.dp, vertical = 2.dp) .padding(top = 0.dp) .height(50.dp) .onKeyEvent { if (it.type == KeyEventType.KeyDown && it.key == Key.DirectionDown) { isFirstItemPressed.value = true true } else { false } } .onFocusChanged { isLayoutFocused = it.isFocused } .focusable() .clickable( indication = null, interactionSource = remember { MutableInteractionSource() } ) { toChangeServer.value = false navHostController.navigate( ScreenTV.ServerListTV.route ) } .border( border = BorderStroke(2.dp, color), shape = RoundedCornerShape(28.dp) ) .background( shape = RoundedCornerShape(28.dp), color = MaterialTheme.colorScheme.onBackground ) .align(Alignment.CenterHorizontally), contentAlignment = Alignment.CenterStart, ) { AddRowSelectServerTV(navHostController, isTablet()) } } else { var isFeedbackClicked by remember { mutableStateOf(prefHelper.getFeedbackState()) } var isDelayedFeedbackClicked by remember { mutableStateOf(isFeedbackClicked) } var isThumbUpClicked by remember { mutableStateOf(App.isThumbUpClicked) } var isThumbDownClicked by remember { mutableStateOf(App.isThumbDownClicked) } var isRipple = false var isThumbUpFocused by remember { mutableStateOf(false) } var isThumbDownFocused by remember { mutableStateOf(false) } Box( modifier = Modifier .fillMaxWidth(fraction = 0.4f) .padding(horizontal = 0.dp) .padding(vertical = 5.dp) .height(90.dp) .align(Alignment.CenterHorizontally) // .border( // border = BorderStroke(0.dp, Color.Blue), // shape = RoundedCornerShape(28.dp) // ) .background( color = Color.Transparent ), ) { Row( modifier = Modifier .padding(0.dp) .background(Color.Transparent), horizontalArrangement = Arrangement.SpaceAround, verticalAlignment = Alignment.CenterVertically ) { Surface( modifier = Modifier .weight(1f) .fillMaxHeight() .padding(end = 5.dp) .border( width = 1.dp, color = MaterialTheme.colorScheme.onBackground, shape = RoundedCornerShape(24.dp) ) .background(Color.Transparent), shape = RoundedCornerShape(24.dp) ) { Column( modifier = Modifier .background(MaterialTheme.colorScheme.onBackground) .border( width = 1.dp, color = MaterialTheme.colorScheme.onBackground, shape = RoundedCornerShape(24.dp) ), verticalArrangement = Arrangement.SpaceEvenly, horizontalAlignment = Alignment.CenterHorizontally, ) { Image( painter = painterResource(id = R.drawable.greenarrow3x), contentDescription = "Green Arrow", modifier = Modifier .size(30.dp) ) Text( text = "Download", style = MaterialTheme.typography.customTypography.displayMedium.copy( color = MaterialTheme.colorScheme.onTertiary ), modifier = Modifier.alpha(0.6F) ) Row( horizontalArrangement = Arrangement.SpaceAround, verticalAlignment = Alignment.CenterVertically ) { Text( text = String.format(Locale.US, "%.2f", StringDown.value), style = MaterialTheme.typography.customTypography.displayLarge.copy( color = MaterialTheme.colorScheme.primary ) ) Text( text = " ${StringDownUnit.value}", style = MaterialTheme.typography.customTypography2.labelSmall.copy( color = MaterialTheme.colorScheme.primary ), modifier = Modifier.alpha(0.5F) ) } } } Surface( modifier = Modifier .weight(1f) .fillMaxHeight() .padding(start = 5.dp) .border( width = 1.dp, color = MaterialTheme.colorScheme.onBackground, shape = RoundedCornerShape(24.dp) ) .background(Color.Transparent), shape = RoundedCornerShape(24.dp) ) { Column( modifier = Modifier .background(MaterialTheme.colorScheme.onBackground) .border( width = 1.dp, color = MaterialTheme.colorScheme.onBackground, shape = RoundedCornerShape(24.dp) ), verticalArrangement = Arrangement.SpaceEvenly, horizontalAlignment = Alignment.CenterHorizontally ) { Image( painter = painterResource(id = R.drawable.yellowarrow3x), contentDescription = "Yellow Arrow", modifier = Modifier .size(30.dp) ) Text( text = "Upload", style = MaterialTheme.typography.customTypography.displayMedium.copy( color = MaterialTheme.colorScheme.onTertiary ), modifier = Modifier.alpha(0.6F) ) Row( horizontalArrangement = Arrangement.SpaceAround, verticalAlignment = Alignment.CenterVertically ) { Text( text = String.format(Locale.US,"%.2f", StringUp.value), style = MaterialTheme.typography.customTypography.displayLarge.copy( color = MaterialTheme.colorScheme.primary ) ) Text( text = " ${StringUpUnit.value}", style = MaterialTheme.typography.customTypography2.labelSmall.copy( color = MaterialTheme.colorScheme.primary ), modifier = Modifier.alpha(0.5F) ) } } } } } val backgroundColor by animateColorAsState( targetValue = if (isDelayedFeedbackClicked) colorResource(id = R.color.yellow_feedback) else MaterialTheme.colorScheme.outlineVariant, label = "Color" ) Box( modifier = Modifier .padding(horizontal = 0.dp) .padding(vertical = 5.dp) .fillMaxWidth(fraction = 0.4f) .height(55.dp) .background( backgroundColor, shape = RoundedCornerShape(12.dp) ) .border( width = 1.dp, color = Color.Transparent, shape = RoundedCornerShape(12.dp) ) .align(Alignment.CenterHorizontally) ) { Row( modifier = Modifier .fillMaxSize() .padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text( text = "How's your connection?", style = MaterialTheme.typography.customTypography.titleSmall.copy( color = Color.White ) ) Row( modifier = Modifier .background(Color.Transparent), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { Image( imageVector = Icons.Outlined.ThumbUp, contentDescription = "Thumb Up", modifier = Modifier .padding(end = 25.dp) .size(24.dp) .focusRequester(focusRequester2) .onKeyEvent { if (it.type == KeyEventType.KeyDown && it.key == Key.DirectionDown) { isFirstItemPressed.value = true true } else if (it.type == KeyEventType.KeyDown && it.key == Key.DirectionLeft) { true } else { false } } .onFocusChanged { isThumbUpFocused = it.isFocused } .focusable() .clickable( indication = rememberRipple( bounded = true, color = colorResource(id = R.color.switch_green) ), interactionSource = remember { MutableInteractionSource() } ) { val connectedServer = basePreferenceHelper.getConnectedServer() val selectedProtocol = basePreferenceHelper.getProtocol().full_name if (!isFeedbackClicked) { isFeedbackClicked = true prefHelper.setFeedbackState(true) isThumbUpClicked = true App.isThumbUpClicked = true isRipple = true homeViewModel.feedback( rating = 1, server_id = connectedServer?.id, server_ip = connectedServer?.ip.toString(), protocol = selectedProtocol ) } } , colorFilter = ColorFilter.tint( if (isFeedbackClicked && isThumbUpClicked) colorResource(id = R.color.switch_green) else if (isThumbUpFocused) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.white) ) ) Image( imageVector = Icons.Outlined.ThumbDown, contentDescription = "Thumb Down", modifier = Modifier .padding(end = 10.dp) .size(24.dp) .onFocusChanged { isThumbDownFocused = it.isFocused } .onKeyEvent { if (it.type == KeyEventType.KeyDown && it.key == Key.DirectionDown) { isFirstItemPressed.value = true true } else if (it.type == KeyEventType.KeyDown && it.key == Key.DirectionRight) { true } else { false } } .focusable() .clickable( indication = rememberRipple( bounded = true, color = colorResource(id = R.color.Red) ), interactionSource = remember { MutableInteractionSource() } ) { val connectedServer = basePreferenceHelper.getConnectedServer() val selectedProtocol = basePreferenceHelper.getProtocol().full_name if (!isFeedbackClicked) { isFeedbackClicked = true prefHelper.setFeedbackState(true) isThumbDownClicked = true App.isThumbDownClicked = true homeViewModel.feedback( rating = 0, server_id = connectedServer?.id, server_ip = connectedServer?.ip.toString(), protocol = selectedProtocol ) } }, colorFilter = ColorFilter.tint( if (isFeedbackClicked && isThumbDownClicked) colorResource(id = R.color.Red) else if (isThumbDownFocused) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.white) ) ) } } } } } } } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun ColumnScope.ShowProtocolDialogTV( prefHelper: BasePreferenceHelper, wg: VPNConnectionsUtil, serverListViewModel: ServerListViewModel ) { var isButtonFocused1 by remember { mutableStateOf(false) } var isButtonFocused2 by remember { mutableStateOf(false) } AlertDialog( onDismissRequest = { isProtocolDialog.value = false }, properties = DialogProperties(), modifier = Modifier .fillMaxWidth() .wrapContentHeight() ) { val lastServer = prefHelper.getConnectedServer() val selectedProtocol = prefHelper.getProtocol() val oldProtocolTitle = if (selectedProtocol.index == 0) AppEnum.AUTO_PROTOCOL.key else selectedProtocol.title val newProtocolTitle = if (protocolObj.value.index == 0) AppEnum.AUTO_PROTOCOL.key else protocolObj.value.title val serverList = prefHelper.getServerData() // val serverList = serverListViewModelSplash.liveDataGetServersGlobal.value var desiredServer = Server() var isServerFound: Boolean = false if (lastServer != null) { val serverProtocol = serverListViewModel.getFilteredServerByProtocolChanged(serverList, lastServer, protocolObj.value) if (serverProtocol.isFound) { desiredServer = serverProtocol.server isServerFound = true } } // serverListViewModelSplash.setCountryData() // Log.d("server_protocol", "Home: $isServerFound ${desiredServer.id} ${desiredServer.server_name} ${desiredServer.ip} ${desiredServer.protocol} ${desiredServer.remoteId}") Surface( color = colorResource(id = R.color.white), modifier = Modifier .background(Color.Transparent) .fillMaxWidth() , shape = RoundedCornerShape(18.dp) ) { Column( verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .background(colorResource(id = R.color.white)) ) { Log.d("islogoutClicked", "AlertDialog") Text(text = "Confirm", color = colorResource(id = R.color.dark_blue_gray_text), style = MaterialTheme.typography.bodyMedium, modifier = Modifier.padding(top = 45.dp) ) Text(text = "Are you sure to switch from $oldProtocolTitle to $newProtocolTitle?", color = colorResource(id = R.color.dark_blue_gray_text), style = MaterialTheme.typography.labelSmall, maxLines = 2, modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 26.dp) ) Row ( modifier = Modifier .padding(top = 34.dp, bottom = 20.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.Bottom ) { Button( onClick = { Log.d("ServerCallbacks", "No") isProtocolDialog.value = false }, modifier = Modifier .padding( start = 15.dp, end = 5.dp, bottom = 0.dp, top = 0.dp ) .onFocusChanged { isButtonFocused1 = it.isFocused } .background(colorResource(id = R.color.transparent)) .weight(1F) .height(52.dp), shape = RoundedCornerShape(15.dp), colors = ButtonDefaults.buttonColors( contentColor = if (isButtonFocused1) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.white), containerColor = colorResource(id = R.color.light_blue), ), border = BorderStroke(2.dp, if (isButtonFocused1) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.light_blue)) ) { Text(text = "No", style = MaterialTheme.typography.labelLarge) Log.d("test_button", "RowScope") } Button( onClick = { Log.d("ServerCallbacks", "Yes") val server = if (isServerFound) desiredServer else prefHelper.getConnectedServer() prefHelper.setServerObject(server) prefHelper.setConnectedServer(server) prefHelper.saveProtocol(protocol = protocolObj.value) wg.stopVpn() Handler().postDelayed(Runnable { wg.startVpn() }, 500) Log.d("ServerCallbacks", "Yes click => ${isProtocolDialog.value}") isProtocolDialog.value = false serverListViewModelSplash.setCountryData() }, modifier = Modifier .padding( start = 5.dp, end = 15.dp, bottom = 0.dp, top = 0.dp ) .onFocusChanged { isButtonFocused2 = it.isFocused } .background(colorResource(id = R.color.transparent)) .weight(1F) .height(52.dp), shape = RoundedCornerShape(15.dp), colors = ButtonDefaults.buttonColors( contentColor = if (isButtonFocused2) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.white), containerColor = colorResource(id = R.color.red), ), border = BorderStroke(2.dp, if (isButtonFocused2) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.red)) // border = BorderStroke(2.dp, // colorResource(id = R.color.gray_icon)) ) { Text(text = "Yes", style = MaterialTheme.typography.labelLarge) Log.d("test_button", "RowScope") // val logoutResponse = accountViewModel.liveDataLogout.observeAsState().value // if (logoutResponse == true) { // accountViewModel.setLogoutStatus(false) // Log.d("test_api_response","Logout live: $logoutResponse") // basePreferenceHelper.setLoggedInState(false) // settingsNavHostController.popBackStack() // settingsNavHostController.navigate(Screen.Started.route) // } // else { //// accountViewModel.setLogoutStatus(false) //// onCancel() // } } } } } } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun ColumnScope.ShowServerDialogTV( prefHelper: BasePreferenceHelper, wg: VPNConnectionsUtil ) { var isButtonFocused1 by remember { mutableStateOf(false) } var isButtonFocused2 by remember { mutableStateOf(false) } AlertDialog( onDismissRequest = { isServerDialog.value = false }, properties = DialogProperties(), modifier = Modifier .fillMaxWidth() .wrapContentHeight() ) { val lastServer = prefHelper.getConnectedServer() val context = LocalContext.current // val serverListViewModel: ServerListViewModel = viewModel { // ServerListViewModel(context) // } Surface( color = colorResource(id = R.color.white), modifier = Modifier .background(Color.Transparent) .fillMaxWidth() , shape = RoundedCornerShape(18.dp) ) { Column( verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .background(colorResource(id = R.color.white)) ) { Log.d("islogoutClicked", "AlertDialog") Text(text = "Confirm", color = colorResource(id = R.color.dark_blue_gray_text), style = MaterialTheme.typography.bodyMedium, modifier = Modifier.padding(top = 45.dp) ) Text(text = "Are you sure to switch from ${lastServer?.server_name} to ${serverObj.value.server_name}?", color = colorResource(id = R.color.dark_blue_gray_text), style = MaterialTheme.typography.labelSmall, maxLines = 2, modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 26.dp) ) Row ( modifier = Modifier .padding(top = 34.dp, bottom = 20.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.Bottom ) { Button( onClick = { Log.d("test_button", "No") isServerDialog.value = false }, modifier = Modifier .padding( start = 15.dp, end = 5.dp, bottom = 0.dp, top = 0.dp ) .onFocusChanged { isButtonFocused1 = it.isFocused } .background(colorResource(id = R.color.transparent)) .weight(1F) .height(52.dp), shape = RoundedCornerShape(15.dp), colors = ButtonDefaults.buttonColors( contentColor = if (isButtonFocused1) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.white), containerColor = colorResource(id = R.color.light_blue), ), border = BorderStroke(2.dp, if (isButtonFocused1) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.light_blue)) ) { Text(text = "No", style = MaterialTheme.typography.labelLarge) Log.d("test_button", "RowScope") } Button( onClick = { Log.d("test_button", "Yes") isServerDialog.value = false prefHelper.setServerObject(serverObj.value) prefHelper.setConnectedServer(serverObj.value) serverListViewModelSplash.setRecentlyConnectedServer(serverObj.value) wg.stopVpn() Handler().postDelayed(Runnable { wg.startVpn() }, 500) Log.d("ServerCallbacks", "Yes click => ${isServerDialog.value}") }, modifier = Modifier .padding( start = 5.dp, end = 15.dp, bottom = 0.dp, top = 0.dp ) .onFocusChanged { isButtonFocused2 = it.isFocused } .background(colorResource(id = R.color.transparent)) .weight(1F) .height(52.dp), shape = RoundedCornerShape(15.dp), colors = ButtonDefaults.buttonColors( contentColor = if (isButtonFocused2) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.white), containerColor = colorResource(id = R.color.red), ), border = BorderStroke(2.dp, if (isButtonFocused2) colorResource(id = R.color.dark_blue_gray_text) else colorResource(id = R.color.red)) ) { Text(text = "Yes", style = MaterialTheme.typography.labelLarge) Log.d("test_button", "RowScope") // val logoutResponse = accountViewModel.liveDataLogout.observeAsState().value // if (logoutResponse == true) { // accountViewModel.setLogoutStatus(false) // Log.d("test_api_response","Logout live: $logoutResponse") // basePreferenceHelper.setLoggedInState(false) // settingsNavHostController.popBackStack() // settingsNavHostController.navigate(Screen.Started.route) // } // else { //// accountViewModel.setLogoutStatus(false) //// onCancel() // } } } } } } } @Composable fun BoxScope.AddRowSmartTV( navHostController: NavHostController, basePreferenceHelper: BasePreferenceHelper, context: Context, isTablet: Boolean, focusRequester2: FocusRequester, homeViewModel: HomeViewModel ) { val smart = basePreferenceHelper.getSmartServerObject() val recommended = basePreferenceHelper.getRecommendedServerObject() val recently = basePreferenceHelper.getConnectedServer() val anySpecific = basePreferenceHelper.getSmartServerObject() val ipInfo = basePreferenceHelper.getIpinfo() val selectedSmartList = basePreferenceHelper.getSmartList() var selectedServer = basePreferenceHelper.getRecommendedServerObject() var selectedSmartServer = basePreferenceHelper.getSmartServerObject() var isButtonFocused by remember { mutableStateOf(false) } Log.d("smartLocationList", "Home:: server = ${selectedServer?.server_name}") var icon = Utils.getDrawable(context, selectedServer?.iso) when(selectedSmartList) { smartConnect[0] -> { icon = Utils.getDrawable(context, recommended?.iso) selectedServer = recommended selectedSmartServer = recommended } smartConnect[1] -> { icon = Utils.getDrawable(context, recently?.iso ?: recommended?.iso) selectedServer = recently ?: recommended selectedSmartServer = recently } smartConnect[2] -> { icon = Utils.getDrawable(context, anySpecific?.iso ?: recommended?.iso) selectedServer = anySpecific ?: recommended selectedSmartServer = anySpecific } else -> {} } Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 15.dp, vertical = 5.dp) .background(Color.Transparent), horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ) { Surface( modifier = Modifier.padding(start = 0.dp), color = Color.Transparent ) { if (icon != 0) { Icon( painter = painterResource(id = icon), contentDescription = "Country Logo", tint = Color.Unspecified, modifier = Modifier .padding(start = 0.dp) .size(30.dp) .weight(1f) .clip(CircleShape) .border(1.dp, colorResource(id = R.color.gray_opac_04), CircleShape) .paint( painter = painterResource(id = icon), contentScale = ContentScale.FillBounds ) ) } } Column( modifier = Modifier .padding(start = 12.dp) ) { ColumnText( text = selectedSmartList, color = MaterialTheme.colorScheme.surfaceContainerLow, // color = colorResource(id = R.color.blue_text), size = 12.sp, style = MaterialTheme.typography.customTypography.headlineSmall.copy( fontSize = 16.sp ) ) ColumnText( text = "${selectedServer?.server_name}", color = MaterialTheme.colorScheme.primary, // color = colorResource(id = R.color.dark_blue_gray_text), size = 16.sp, style = MaterialTheme.typography.labelMedium.copy( fontSize = 16.sp ) ) } Spacer(modifier = Modifier.weight(1F)) Surface( modifier = Modifier .padding(start = 15.dp), color = Color.Transparent ) { var isConnect: Int? = homeViewModel.isConnect.observeAsState().value isConnect = basePreferenceHelper.getConnectState() val color = if (isButtonFocused && isConnect == App.CONNECTED) MaterialTheme.colorScheme.primary else if (isButtonFocused) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceContainerLow ClickableText( modifier = Modifier .onKeyEvent { when (it.key) { Key.DirectionLeft -> { true } Key.DirectionRight -> { true } else -> { false } } } .focusRequester(focusRequester2) .onFocusChanged { isButtonFocused = it.isFocused } .clickable { toChangeServer.value = true navHostController.navigate( ScreenTV.ServerListTV.route ) } .focusable(), text = AnnotatedString("Change"), style = MaterialTheme.typography.customTypography.headlineMedium.copy( // color = MaterialTheme.colorScheme.surfaceContainerLow, color = color, fontSize = 18.sp ), onClick = {}, ) } } } @Composable fun BoxScope.AddRowSelectServerTV(navHostController: NavHostController, isTablet: Boolean) { val context = LocalContext.current Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 15.dp) .background(Color.Transparent) // .pointerInput(Unit) { // detectTapGestures { // toChangeServer.value = false // navHostController.navigate( // Screen.ServerList.route // ) // Screen.ServerList.isTrue = true // Log.d("button_click_change", "Pressed") // } // } , horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ) { Surface( modifier = Modifier.padding(start = 0.dp), color = Color.Transparent ) { Image( painter = painterResource(id = R.drawable.worldmap3x), contentDescription = "World", modifier = Modifier .padding(start = 0.dp) .size(30.dp) .weight(1f) ) } Surface( modifier = Modifier.padding(start = 0.dp), color = Color.Transparent ) { Text(text = "See All Locations", style = MaterialTheme.typography.labelMedium.copy( fontSize = if (isTablet()) 20.sp else 16.sp ), color = MaterialTheme.colorScheme.primary, // color = colorResource(id = R.color.dark_blue_gray_text), maxLines = 2, modifier = Modifier .padding(start = 12.dp, end = 0.dp) .weight(1f) ) } Spacer(modifier = Modifier.weight(1F)) Surface( modifier = Modifier.padding(start = 15.dp), color = Color.Transparent ) { Image( painter = painterResource(id = R.drawable.frontarrow3x), contentDescription = "Front_Arrow", colorFilter = ColorFilter.tint(colorResource(id = R.color.dark_blue_gray_text)), modifier = Modifier .padding(start = 0.dp, end = 5.dp) .size(10.dp, 18.dp) .weight(1f) ) } } } @Composable fun ColumnScope.AddText( text: String, size: TextUnit, color: Color, style: TextStyle ) { Text( text = text, style = style, color = color, modifier = Modifier.padding(top = 5.dp) ) } @Composable fun ColumnScope.ColumnText( text: String, color: Color, size: TextUnit, style: TextStyle ) { Surface( modifier = Modifier.padding(start = 0.dp), color = Color.Transparent ) { Text(text = text, style = style, color = color, maxLines = 1, modifier = Modifier .padding(start = 0.dp, end = 0.dp) .weight(1f) ) } } @Composable fun RowScope.AddText( text: String, size: TextUnit, color: Color, isTablet: Boolean ) { Text( text = text, style = MaterialTheme.typography.labelMedium.copy( fontSize = 18.sp ), color = color, modifier = Modifier.padding(top = 0.dp) ) } @Composable fun OnLifecycleEvent(onEvent: ( owner: LifecycleOwner, event: Lifecycle.Event ) -> Unit) { val eventHandler = rememberUpdatedState(onEvent) val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current) DisposableEffect(lifecycleOwner.value) { val lifecycle = lifecycleOwner.value.lifecycle val observer = LifecycleEventObserver { owner, event -> eventHandler.value(owner, event) } lifecycle.addObserver(observer) onDispose { lifecycle.removeObserver(observer) } } } private fun getEnableProtocols(protocol_name: String, prefHelper: BasePreferenceHelper): Boolean { prefHelper.getEnabledProtocols().let { if (it.contains(protocol_name)) { return true } } return false } @Composable fun pinkBackgroundTV(): Painter { return if (isDarkTheme.value) painterResource(id = R.drawable.darkpinkbackground) else painterResource(id = R.drawable.pinkbackground3x) } @Composable fun blueBackgroundTV(): Painter { return if (isDarkTheme.value) painterResource(id = R.drawable.darkbluebackground) else painterResource(id = R.drawable.bluebackground3x) }