package com.vpn.fastestvpnservice.customItems import android.os.Looper import android.util.Log import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope 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.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape 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.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope 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.graphics.Color import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import com.vpn.fastestvpnservice.R import com.vpn.fastestvpnservice.beans.CountryServerList import com.vpn.fastestvpnservice.beans.Server import com.vpn.fastestvpnservice.beans.allLocationsList import com.vpn.fastestvpnservice.beans.favList import com.vpn.fastestvpnservice.beans.favListServer import com.vpn.fastestvpnservice.utils.Utils import com.stealthcopter.networktools.Ping import com.stealthcopter.networktools.ping.PingResult import com.stealthcopter.networktools.ping.PingStats import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.onServer import com.vpn.fastestvpnservice.sealedClass.BottomBarScreen import com.vpn.fastestvpnservice.sealedClass.Screen import com.vpn.fastestvpnservice.viewmodels.HomeViewModel import com.vpn.fastestvpnservice.viewmodels.ServerListViewModel import com.vpn.fastestvpnservice.viewmodels.SplashViewModel import java.lang.Exception import java.util.logging.Handler var serverInfoObj: MutableState = mutableStateOf(Server()) @Composable fun CountryItem( server: Server, category: String, countryTotalServers: Int, navHostController: NavHostController ) { Log.d("test_countrySize", "CountryItem Called ${server.server_name} ${server.totalServers}") Box( modifier = Modifier .fillMaxWidth() .background( color = MaterialTheme.colorScheme.background ) .padding(bottom = 1.dp) ) { val context = LocalContext.current val basePreferenceHelper = BasePreferenceHelper(context) val countrySize by rememberSaveable { mutableStateOf(server.totalServers) } var isServerExpanded by rememberSaveable { mutableStateOf(false) } val serverListViewModel: ServerListViewModel = viewModel{ ServerListViewModel(context) } val splashViewModel: SplashViewModel = viewModel{ SplashViewModel(context) } val scope = rememberCoroutineScope() val homeViewModel: HomeViewModel = viewModel { HomeViewModel(context, scope) } var isCountryServerClicked by remember { mutableStateOf(false) } if (isCountryServerClicked) { Log.d("ServerCallbacks", "isServerClicked $isCountryServerClicked") onServer.onServerSelected(context, homeViewModel, onClick = { isCountryServerClicked = false }, true, server ) navHostController.popBackStack() } var isServerServerClicked by remember { mutableStateOf(false) } if (isServerServerClicked) { Log.d("ServerCallbacks", "isServerClicked $isServerServerClicked") onServer.onServerSelected( context, homeViewModel, onClick = { isServerServerClicked = false }, true, server ) navHostController.popBackStack() } countrySize.let { size -> // var locationsSize: Int = 0 // val countriesServersData = basePreferenceHelper.getServerData().get(0).servers // countriesServersData?.let { // val serversGroup = serverListViewModel.getServerGroupList(server, it) // locationsSize = serversGroup.size // } Column { /* Country Location's Row */ Row( verticalAlignment = Alignment.Top, horizontalArrangement = Arrangement.Start, modifier = Modifier .fillMaxWidth() .padding( start = 16.dp, end = 12.dp, top = 12.dp ) .clickable( indication = null, interactionSource = remember { MutableInteractionSource() } ) { if (server.enable == 1) { // basePreferenceHelper.setServerObject(server) isCountryServerClicked = true } else { navHostController.navigate( Screen.Subscription.route ) } } ) { val icon = if (server.enable == 1) Utils.getDrawable(context, server.iso) else Utils.getDrawableGray(context, server.iso) Icon( painter = painterResource(id = icon), contentDescription = "Server Logo", tint = Color.Unspecified, modifier = Modifier .padding(bottom = 16.dp) .size(24.dp) .clip(CircleShape) .paint( painter = painterResource(id = icon), contentScale = ContentScale.FillHeight ) ) Text(text = server.country!!, style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary, modifier = Modifier .padding(start = 16.dp, bottom = 18.dp) .align(Alignment.CenterVertically) ) Spacer(modifier = Modifier.weight(1F)) Text(text = "$countryTotalServers locations", style = MaterialTheme.typography.bodySmall, color = colorResource(id = R.color.dark_blue_gray_text), modifier = Modifier .padding(end = 30.dp, bottom = 18.dp) .align(Alignment.CenterVertically) .alpha(0.4F) ) // Spacer(modifier = Modifier.weight(1F)) Icon( modifier = Modifier .padding(bottom = 18.dp, end = 0.dp) .size(12.dp, 7.dp) .align(Alignment.CenterVertically) .clickable( indication = null, interactionSource = remember { MutableInteractionSource() } ) { isServerExpanded = !isServerExpanded }, painter = if (isServerExpanded) painterResource( id = R.drawable.dragarrow3x) else painterResource( id = R.drawable.downarrow3x), contentDescription = "Server Logo", tint = MaterialTheme.colorScheme.primary, ) } /* Country Expandable's Row */ if (isServerExpanded) { val countriesServersData1 = basePreferenceHelper.getServerData().get(0).servers countriesServersData1?.let { val serversGroup = serverListViewModel.getServerGroupList(server, it) ExpandableRow(server = serversGroup, navHostController) } } } Surface( modifier = Modifier .padding(start = 0.dp, end = 0.dp) .height(1.dp) .fillMaxWidth() .alpha(0.6F) .align(Alignment.BottomCenter), color = colorResource(id = R.color.gray_icon) ) {} // else { // Log.d("test_return_ping","C[1]=> " + server.server_name + server.ping) // Row( // verticalAlignment = Alignment.Top, // horizontalArrangement = Arrangement.Start, // modifier = Modifier // .fillMaxWidth() // .padding(start = 16.dp, end = 7.dp, top = 12.dp) // .clickable( // indication = null, // interactionSource = remember { MutableInteractionSource() } // ) { // basePreferenceHelper.setServerObject(server) // isServerServerClicked = true //// navHostController.popBackStack() // } // ) { // val icon = if (server.enable == 1) Utils.getDrawable(context, server.iso) // else Utils.getDrawableGray(context, server.iso) // // Icon( // painter = painterResource(id = icon), // contentDescription = "Server Logo", // tint = Color.Unspecified, // modifier = Modifier // .padding(bottom = 16.dp) // .size(24.dp) // .clip(CircleShape) // .paint( // painter = painterResource(id = icon), // contentScale = ContentScale.FillHeight // ) // ) // val serverTitle = if (category.lowercase().toString() == "servers") server.country else server.server_name // Text(text = serverTitle!!, // style = MaterialTheme.typography.labelMedium, // color = MaterialTheme.colorScheme.primary, // modifier = Modifier // .padding(start = 16.dp, bottom = 18.dp) // .align(Alignment.CenterVertically) // ) // Spacer(modifier = Modifier.weight(1F)) // val pings = server.ping // Text( // text = "${server.ping} ms", // style = MaterialTheme.typography.displayMedium, // color = colorResource(id = R.color.blue_text), // modifier = Modifier // .padding(end = 30.dp, bottom = 18.dp) // .align(Alignment.CenterVertically) // ) // var isFavorite by rememberSaveable { mutableStateOf(server.isFavourited) } // // IconButton( // modifier = Modifier // .padding(bottom = 18.dp, end = 8.dp) // .size(21.dp, 20.dp) // .align(Alignment.CenterVertically), // onClick = { // isFavorite = !isFavorite!! // serverListViewModel.favAndUnFav(server) // } // ) // { //// val favResponse = serverListViewModel.mutableLiveDataFavUnFav.observeAsState().value //// favResponse?.let { //// Log.d("test_fav_response", it.message.toString()) //// splashViewModel.serverDataApi() //// serverListViewModel.mutableLiveDataFavUnFav.value = null //// } // // Icon( //// .clickable( //// indication = null, //// interactionSource = remember { MutableInteractionSource() } //// ) { }, // // painter = if (isFavorite == true) painterResource( // id = R.drawable.fav_server3x) else painterResource( // id = R.drawable.unfav_server3x), // // contentDescription = "Server Logo", // tint = Color.Unspecified, // ) // } // } // Log.d("test_servers_count", "${server.server_name} ${server.countryServers?.size}") /* Country Location's Row -> 1 Location() */ // var ping by remember { mutableIntStateOf(0) } // Ping.onAddress(server.ip as String).setTimeOutMillis(1000).doPing( // object : Ping.PingListener{ // override fun onResult(pingResult: PingResult?) { // android.os.Handler(Looper.getMainLooper()).post { // val ping = pingResult?.timeTaken?.toInt()!! // server.ping = ping // Log.d("test_ping", "ping = $ping") // } // } // // override fun onError(e: Exception?) {} // override fun onFinished(pingStats: PingStats?) {} // } // ) } } } @Composable fun ColumnScope.ExpandableRow(server: ArrayList, navHostController: NavHostController) { val context = LocalContext.current val basePreferenceHelper = BasePreferenceHelper(context) val serverListViewModel: ServerListViewModel = viewModel{ ServerListViewModel(context) } val splashViewModel: SplashViewModel = viewModel{ SplashViewModel(context) } val scope = rememberCoroutineScope() val homeViewModel: HomeViewModel = viewModel { HomeViewModel(context, scope) } var isExpServerClicked by remember { mutableStateOf(false) } Column( modifier = Modifier .padding( start = 40.dp, end = 26.dp, top = 2.dp, bottom = 28.dp ) .background(Color.Transparent) ) { // Expandable Row server.let { serverData -> serverData.forEachIndexed { index, serverInfo -> Log.d("serverInfo_ping", "serverInfo ${serverInfo.server_name} :: ${serverInfo.ping}") var isFavorite by rememberSaveable { mutableStateOf(serverInfo.isFavourited) } val isServerFavourited: Boolean = serverInfo.isFavourited == true Log.d("test-server_fav_d", "$isFavorite") if (isExpServerClicked) { onServer.onServerSelected( context, homeViewModel, onClick = {isExpServerClicked = false}, true, serverInfoObj.value ) navHostController.popBackStack() } Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start, modifier = Modifier .fillMaxWidth() .padding( vertical = 15.dp ) .background(Color.Transparent) .clickable( indication = null, interactionSource = remember { MutableInteractionSource() } ) { if (serverInfo.enable == 1) { serverInfoObj.value = serverInfo // basePreferenceHelper.setServerObject(serverInfo) isExpServerClicked = true } else { navHostController.navigate( Screen.Subscription.route ) } } ) { Text(text = serverInfo.server_name!!, style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSecondary, modifier = Modifier .padding(start = 16.dp, bottom = 0.dp) .align(Alignment.CenterVertically) .alpha(0.4F) ) Spacer(modifier = Modifier.weight(1F)) Text(text = "${serverInfo.ping} ms", style = MaterialTheme.typography.displayMedium, color = colorResource(id = R.color.blue_text), modifier = Modifier .padding(start = 0.dp, end = 30.dp) .align(Alignment.CenterVertically) ) IconButton( modifier = Modifier .padding(bottom = 0.dp, end = 16.dp) .size(25.dp) .align(Alignment.CenterVertically), onClick = { isFavorite = !isFavorite!! serverListViewModel.favAndUnFav(serverInfo) } ) { Icon( // .clickable( // indication = null, // interactionSource = remember { MutableInteractionSource() } // ) { }, painter = if (isServerFavourited) painterResource( id = R.drawable.fav_server3x) else painterResource( id = R.drawable.unfav_server3x), contentDescription = "Server Logo", tint = Color.Unspecified, modifier = Modifier.size(22.dp, 21.dp) ) } } Surface( modifier = Modifier .padding(top = 0.dp, end = 0.dp) .height(1.dp) .fillMaxWidth() .alpha(0.6F) , color = colorResource(id = R.color.gray_icon) ) {} } } } } fun calculatePing(server: Server, onPingResult: (Int) -> Unit) { Ping.onAddress(server.ip as String).setTimeOutMillis(1000).doPing( object : Ping.PingListener{ override fun onResult(pingResult: PingResult?) { android.os.Handler(Looper.getMainLooper()).post { val ping = pingResult?.timeTaken?.toInt()!! onPingResult(ping) Log.d("test_ping", "ping[0] = $ping") } } override fun onError(e: java.lang.Exception?) {} override fun onFinished(pingStats: PingStats?) {} } ) } @Preview @Composable fun CountryItemPreview() { CountryItem(server = favListServer[0], "servers", 1, rememberNavController()) }