Sfoglia il codice sorgente

working on serverlist to be saved on viewmodel so that it should pre load, make viewmodels Global on splash screens

Khubaib 11 mesi fa
parent
commit
0afdfc43bf

+ 1 - 0
app/src/main/java/com/vpn/fastestvpnservice/MainActivity.kt

@@ -43,6 +43,7 @@ import com.vpn.fastestvpnservice.screens.helpScreensAll.fileChooserCallback
 import com.vpn.fastestvpnservice.ui.theme.FastestVPNTheme
 import com.vpn.fastestvpnservice.utils.StaticMethods
 import com.vpn.fastestvpnservice.viewmodels.LoginViewModel
+import com.vpn.fastestvpnservice.viewmodels.SplashViewModel
 import de.blinkt.openvpn.core.App
 
 open class MainActivity : DockActivity(), ConnectivityReceiver.ConnectivityReceiverListener {

+ 9 - 8
app/src/main/java/com/vpn/fastestvpnservice/customItems/ServerItem.kt

@@ -55,6 +55,7 @@ import com.vpn.fastestvpnservice.beans.toChangeServer
 import com.vpn.fastestvpnservice.constants.smartConnect
 import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
 import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.onServer
+import com.vpn.fastestvpnservice.screens.serverListViewModelSplash
 import com.vpn.fastestvpnservice.sealedClass.BottomBarScreen
 import com.vpn.fastestvpnservice.sealedClass.Screen
 import com.vpn.fastestvpnservice.utils.Utils
@@ -81,12 +82,12 @@ fun ServerItem(server: Server, navHostController: NavHostController, serverPing:
             .background(color = MaterialTheme.colorScheme.background)
             .padding(bottom = 1.dp)
     ) {
-        val serverListViewModel: ServerListViewModel = viewModel{
-            ServerListViewModel(context)
-        }
-        val splashViewModel: SplashViewModel = viewModel{
-            SplashViewModel(context)
-        }
+//        val serverListViewModel: ServerListViewModel = viewModel{
+//            ServerListViewModel(context)
+//        }
+//        val splashViewModel: SplashViewModel = viewModel{
+//            SplashViewModel(context)
+//        }
 
         if (isServerClicked) {
             Log.d("ServerCallbacks", "isServerClicked $isServerClicked")
@@ -179,7 +180,7 @@ fun ServerItem(server: Server, navHostController: NavHostController, serverPing:
                     .align(Alignment.CenterVertically)
                 )
             Spacer(modifier = Modifier.weight(1F))
-            Text(text = "$ping ms",
+            Text(text = "$serverPing ms",
                 style = MaterialTheme.typography.displayMedium,
                 color = colorResource(id = R.color.blue_text),
                 modifier = Modifier
@@ -194,7 +195,7 @@ fun ServerItem(server: Server, navHostController: NavHostController, serverPing:
                     .size(25.dp),
                 onClick = {
                     isFavorite = !isFavorite!!
-                    serverListViewModel.favAndUnFav(server)
+                    serverListViewModelSplash.favAndUnFav(server)
                 }
             ) {
                 Icon(

+ 6 - 0
app/src/main/java/com/vpn/fastestvpnservice/screens/BottomBarMainScreen.kt

@@ -35,12 +35,14 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.res.colorResource
 import androidx.compose.ui.res.painterResource
 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.NavDestination
 import androidx.navigation.NavDestination.Companion.hierarchy
 import androidx.navigation.NavGraph.Companion.findStartDestination
@@ -53,9 +55,13 @@ import com.vpn.fastestvpnservice.navigation.navigationAnimation
 import com.vpn.fastestvpnservice.sealedClass.BottomBarScreen
 import com.vpn.fastestvpnservice.ui.theme.customTypography2
 import com.vpn.fastestvpnservice.utils.isTablet
+import com.vpn.fastestvpnservice.viewmodels.SearchListViewModel
+import com.vpn.fastestvpnservice.viewmodels.ServerListViewModel
+import com.vpn.fastestvpnservice.viewmodels.SplashViewModel
 
 @Composable
 fun BottomBarMainScreen(navController: NavHostController, activity: ComponentActivity) {
+    Log.d("test_globalvar", "BottomBarMainScreen")
     val navController1 = rememberNavController()
     var isBottomBarVisible by remember { mutableStateOf(true) }
 

+ 90 - 85
app/src/main/java/com/vpn/fastestvpnservice/screens/ServerListScreen.kt

@@ -79,7 +79,6 @@ import androidx.compose.ui.res.painterResource
 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.stealthcopter.networktools.Ping
@@ -111,9 +110,10 @@ fun ServerList(
     val focusManager = LocalFocusManager.current
     val context = LocalContext.current
 
-    var serverListViewModel: ServerListViewModel = viewModel {
-        ServerListViewModel(context = context)
-    }
+//    var serverListViewModel: ServerListViewModel = viewModel {
+//        ServerListViewModel(context = context)
+//    }
+    val serverListViewModel = serverListViewModelSplash
     val basePreferenceHelper = BasePreferenceHelper(context)
     isAlphabetList.value = basePreferenceHelper.getFilterList() != filterList[0]
     Box(
@@ -285,60 +285,13 @@ fun ColumnScope.ShowRecommendedList(
         val recommendedList: MutableList<Server> = ArrayList<Server>()
         val smartLocationList: MutableList<Server> = ArrayList<Server>()
 
-        prefHelper.getServerData().get(0).servers?.let {
-            val serverDataLocation = it
-
-            val distinctdatanotnull =
-                serverDataLocation.filter {   // servers's lt and lt not be null
-                    it.lt != null && it.lg != null
-                }
-
-            val distinctdata =
-                distinctdatanotnull.distinctBy { // servers's lt filter, no same lt of a server
-                    it.lt
-                }
-
-            val result = FloatArray(1)
-            val ipinfo = prefHelper.getIpinfo()
-
-            distinctdata.forEachIndexed { index, server ->
-                val lat1 = ipinfo?.latitute
-                val lon1 = ipinfo?.longitude
-                val lat2 = server.lt
-                val lon2 = server.lg
-
-                if (lat1 != null && lat2 != null && lon1 != null && lon2 != null) {
-                    Location.distanceBetween(lat1, lon1, lat2, lon2, result)
-                }
+        val data = serverListViewModelSplash.liveDataTest.observeAsState().value
+        Log.d("test_live_data", "Num SLS = $data")
 
-                val distance: Float = result[0]
-                distinctdata.get(index).distance = distance
 
-            }
 
-            val sortedDistance = distinctdata.sortedBy {
-                it.distance
-            }
-
-            if (sortedDistance.isNotEmpty()) {
-                for (i in 0..2) {
-                    recommendedList.add(sortedDistance.get(i))
-                }
-            }
-
-            if (isAlphabetList.value) {
-                recommendedList.sortBy {
-                    it.server_name
-                }
-            }
 
-            if (sortedDistance.isNotEmpty()) {
-                for (i in 0..0) {
-                    smartLocationList.add(sortedDistance.get(i))
-                }
-            }
 
-        }
 
         var favList = serverListViewModel.liveDataGetFavList.observeAsState().value
         favList = serverListViewModel.getFavList(isAlphabetList.value)
@@ -351,6 +304,7 @@ fun ColumnScope.ShowRecommendedList(
 
 
 
+        var recommended = serverListViewModelSplash.liveDataGetRecommendedServers.value
 
         LazyColumn(
             modifier = Modifier
@@ -383,7 +337,6 @@ fun ColumnScope.ShowRecommendedList(
                     )
                 }
             }
-
             var favFilterList = ArrayList<Server>()
             favList.let {
                 if (isAlphabetList.value) {
@@ -397,8 +350,6 @@ fun ColumnScope.ShowRecommendedList(
                         favFilterList = favList2
                     }
                 }
-
-
                 items(items = favFilterList) { server ->
 
                     ServerItem(server, navHostController, server.ping)
@@ -432,8 +383,7 @@ fun ColumnScope.ShowRecommendedList(
                     )
                 }
             }
-
-            items(items = smartLocationList) { server ->
+            items(items = smartLocationListGlobal) { server ->
                 ServerItem(server, navHostController, server.ping)
             }
 
@@ -465,21 +415,12 @@ fun ColumnScope.ShowRecommendedList(
                     )
                 }
             }
-//            val recent = prefHelper.getServerData()
-//            val filterData3 = recent.get(1).servers?.let {
-//                serverListViewModel.filterServersByStreamingServers(
-//                    it
-//                )
+//            val recentLocation: ArrayList<Server> = ArrayList<Server>()
+//            prefHelper.getConnectedServer()?.let {
+//                recentLocation.add(it)
 //            }
 
-            val recentLocation: ArrayList<Server> = ArrayList<Server>()
-
             val recentList = prefHelper.getRecentlyList()
-
-            prefHelper.getConnectedServer()?.let {
-                recentLocation.add(it)
-            }
-
             recentList?.let {
                 items(items = it) { server ->
                     ServerItem(server, navHostController, server.ping)
@@ -515,15 +456,20 @@ fun ColumnScope.ShowRecommendedList(
                 }
             }
 
-//            val recommend = prefHelper.getServerData()
-//            val filterData4 = recommend.get(1).servers?.let {
-//                serverListViewModel.filterServersByStreamingServers(
-//                    it
-//                )
-//            }
 
-            items(items = recommendedList) { server ->
-                ServerItem(server, navHostController, server.ping)
+                if (isAlphabetList.value) {
+                    recommended?.sortBy {
+                        it.server_name
+                    }
+                } else {
+                    val recommended2 = serverListViewModelSplash.liveDataGetRecommendedServers.value
+                    recommended = recommended2
+                }
+
+            recommended?.let {
+                items(items = it) { server ->
+                    ServerItem(server, navHostController, server.ping)
+                }
             }
         }
     }
@@ -818,12 +764,15 @@ fun ColumnScope.ShowSearchBar(
     navHostController: NavHostController) {
 
     val context = LocalContext.current
-    val splashViewModel: SplashViewModel = viewModel{
-        SplashViewModel(context)
-    }
-    val searchListViewModel: SearchListViewModel = viewModel{
-        SearchListViewModel(context, serverListViewModel, splashViewModel)
-    }
+//    val splashViewModel: SplashViewModel = viewModel{
+//        SplashViewModel(context)
+//    }
+//    val splashViewModel = splashViewModelGlobal
+//    val searchListViewModel: SearchListViewModel = viewModel{
+//        SearchListViewModel(context, serverListViewModel, splashViewModel)
+//    }
+
+    val searchListViewModel = searchListViewModelSplash
     val scope = rememberCoroutineScope()
 
 //    var searchText by remember { mutableStateOf("") }
@@ -1119,4 +1068,60 @@ fun ServerListPreview() {
 //                        icon = if (isP2PExpanded) R.drawable.dragarrow3x
 //                        else R.drawable.downarrow3x
 //                    }
-//                }
+//                }
+
+
+//        prefHelper.getServerData().get(0).servers?.let {
+//            val serverDataLocation = it
+//
+//            val distinctdatanotnull =
+//                serverDataLocation.filter {   // servers's lt and lt not be null
+//                    it.lt != null && it.lg != null
+//                }
+//
+//            val distinctdata =
+//                distinctdatanotnull.distinctBy { // servers's lt filter, no same lt of a server
+//                    it.lt
+//                }
+//
+//            val result = FloatArray(1)
+//            val ipinfo = prefHelper.getIpinfo()
+//
+//            distinctdata.forEachIndexed { index, server ->
+//                val lat1 = ipinfo?.latitute
+//                val lon1 = ipinfo?.longitude
+//                val lat2 = server.lt
+//                val lon2 = server.lg
+//
+//                if (lat1 != null && lat2 != null && lon1 != null && lon2 != null) {
+//                    Location.distanceBetween(lat1, lon1, lat2, lon2, result)
+//                }
+//
+//                val distance: Float = result[0]
+//                distinctdata.get(index).distance = distance
+//
+//            }
+//
+//            val sortedDistance = distinctdata.sortedBy {
+//                it.distance
+//            }
+//
+//            if (sortedDistance.isNotEmpty()) {
+//                for (i in 0..2) {
+//                    recommendedList.add(sortedDistance.get(i))
+//                }
+//            }
+//
+//            if (isAlphabetList.value) {
+//                recommendedList.sortBy {
+//                    it.server_name
+//                }
+//            }
+//
+//            if (sortedDistance.isNotEmpty()) {
+//                for (i in 0..0) {
+//                    smartLocationList.add(sortedDistance.get(i))
+//                }
+//            }
+//
+//        }

+ 79 - 53
app/src/main/java/com/vpn/fastestvpnservice/screens/SplashScreen.kt

@@ -33,6 +33,7 @@ import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.livedata.observeAsState
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.paint
@@ -59,10 +60,17 @@ import com.vpn.fastestvpnservice.beans.Server
 import com.vpn.fastestvpnservice.beans.isDarkTheme
 import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
 import com.vpn.fastestvpnservice.sealedClass.Screen
+import com.vpn.fastestvpnservice.viewmodels.SearchListViewModel
 import com.vpn.fastestvpnservice.viewmodels.ServerListViewModel
 import com.vpn.fastestvpnservice.viewmodels.SplashViewModel
 import kotlinx.coroutines.delay
 
+val recommendedListGlobal: ArrayList<Server> = ArrayList<Server>()
+val smartLocationListGlobal: ArrayList<Server> = ArrayList<Server>()
+lateinit var splashViewModelSplash: SplashViewModel
+lateinit var serverListViewModelSplash: ServerListViewModel
+lateinit var searchListViewModelSplash: SearchListViewModel
+
 @Composable
 fun Splash(navHostController: NavHostController) {
     val context = LocalContext.current
@@ -71,7 +79,6 @@ fun Splash(navHostController: NavHostController) {
         SplashViewModel(context)
     }
 
-
     Box(modifier = Modifier
         .paint(
             painter = painterResource(id = if (isDarkTheme.value) R.drawable.bg_app else R.drawable.bg_img3),
@@ -122,61 +129,20 @@ fun Splash(navHostController: NavHostController) {
     val isLoggedIn = basePreferenceHelper.getLoggedInState()
 
     if (isLoggedIn) {
-        val serverListViewModel: ServerListViewModel = viewModel {
+        splashViewModelSplash = viewModel {
+            SplashViewModel(context)
+        }
+        serverListViewModelSplash = viewModel {
             ServerListViewModel(context = context)
         }
-
-        val smartLocationList: MutableList<Server> = ArrayList<Server>()
-
-        basePreferenceHelper.getServerData().get(0).servers?.let {
-            val serverDataLocation = it
-
-            val distinctdatanotnull =
-                serverDataLocation.filter {   // servers's lt and lt not be null
-                    it.lt != null && it.lg != null
-                }
-
-            val distinctdata =
-                distinctdatanotnull.distinctBy { // servers's lt filter, no same lt of a server
-                    it.lt
-                }
-
-            val result = FloatArray(1)
-            val ipinfo = basePreferenceHelper.getIpinfo()
-
-            distinctdata.forEachIndexed { index, server ->
-                val lat1 = ipinfo?.latitute
-                val lon1 = ipinfo?.longitude
-                val lat2 = server.lt
-                val lon2 = server.lg
-
-                if (lat1 != null && lat2 != null && lon1 != null && lon2 != null) {
-                    Location.distanceBetween(lat1, lon1, lat2, lon2, result)
-                }
-
-                val distance: Float = result[0]
-                distinctdata.get(index).distance = distance
-
-            }
-
-            val sortedDistance = distinctdata.sortedBy {
-                it.distance
-            }
-
-            if (sortedDistance.isNotEmpty()) {
-                for (i in 0..0) {
-                    smartLocationList.add(sortedDistance.get(i))
-                }
-            }
-
-            smartLocationList.forEach {
-//                basePreferenceHelper.setSmartServerObject(it)
-                basePreferenceHelper.setRecommendedServerObject(it)
-                Log.d("smartLocationList", "SS:: server = ${it.server_name}")
-            }
-
+        searchListViewModelSplash = viewModel {
+            SearchListViewModel(context, serverListViewModelSplash, splashViewModelSplash)
         }
 
+        val data = serverListViewModelSplash.liveDataTest.observeAsState().value
+        Log.d("test_live_data", "Num SS = $data")
+        serverListViewModelSplash._mutableLiveDataTest.value = 1
+
         val allServers: ArrayList<Server> = ArrayList<Server>()
         basePreferenceHelper.getServerData().let {
             it.forEachIndexed { index, serverData ->
@@ -197,6 +163,8 @@ fun Splash(navHostController: NavHostController) {
         delay(delay)
 
         if (isLoggedIn) {
+//
+            serverListViewModelSplash.setRecommendedSmartServers()
             splashViewModel.serverDataApi()
             navHostController.popBackStack()
             navHostController.navigate(Screen.BottomBarMainScreen.route)
@@ -219,4 +187,62 @@ fun SplashDarkThemePreview() {
 @Composable
 fun SplashDarkThemePreviewDark() {
     Splash(navHostController = rememberNavController())
-}
+}
+
+val smartLocationList: MutableList<Server> = ArrayList<Server>()
+//
+//            basePreferenceHelper.getServerData().get(0).servers?.let {
+//                val serverDataLocation = it
+//
+//                val distinctdatanotnull =
+//                    serverDataLocation.filter {   // servers's lt and lt not be null
+//                        it.lt != null && it.lg != null
+//                    }
+//
+//                val distinctdata =
+//                    distinctdatanotnull.distinctBy { // servers's lt filter, no same lt of a server
+//                        it.lt
+//                    }
+//
+//                val result = FloatArray(1)
+//                val ipinfo = basePreferenceHelper.getIpinfo()
+//
+//                distinctdata.forEachIndexed { index, server ->
+//                    val lat1 = ipinfo?.latitute
+//                    val lon1 = ipinfo?.longitude
+//                    val lat2 = server.lt
+//                    val lon2 = server.lg
+//
+//                    if (lat1 != null && lat2 != null && lon1 != null && lon2 != null) {
+//                        Location.distanceBetween(lat1, lon1, lat2, lon2, result)
+//                    }
+//
+//                    val distance: Float = result[0]
+//                    distinctdata.get(index).distance = distance
+//
+//                }
+//
+//                val sortedDistance = distinctdata.sortedBy {
+//                    it.distance
+//                }
+//
+//                if (sortedDistance.isNotEmpty()) {
+//                    for (i in 0..2) {
+//                        recommendedListGlobal.add(sortedDistance.get(i))
+//                        Log.d("recommendedListGlobal", "SS:: server = ${sortedDistance.get(i).server_name}")
+//                    }
+//                }
+//
+//                if (sortedDistance.isNotEmpty()) {
+//                    for (i in 0..0) {
+//                        smartLocationList.add(sortedDistance.get(i))
+//                    }
+//                }
+//
+//                smartLocationList.forEach {
+////                basePreferenceHelper.setSmartServerObject(it)
+//                    basePreferenceHelper.setRecommendedServerObject(it)
+//                    Log.d("smartLocationList", "SS:: server = ${it.server_name}")
+//                }
+//
+//            }

+ 17 - 12
app/src/main/java/com/vpn/fastestvpnservice/screens/bottomNavBarScreens/SettingsScreen.kt

@@ -86,6 +86,8 @@ import com.vpn.fastestvpnservice.constants.AppEnum
 import com.vpn.fastestvpnservice.constants.smartConnect
 import com.vpn.fastestvpnservice.customItems.ServerSpecificItem
 import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
+import com.vpn.fastestvpnservice.screens.searchListViewModelSplash
+import com.vpn.fastestvpnservice.screens.serverListViewModelSplash
 import com.vpn.fastestvpnservice.sealedClass.BottomBarScreen
 import com.vpn.fastestvpnservice.sealedClass.Screen
 import com.vpn.fastestvpnservice.viewmodels.HomeViewModel
@@ -253,6 +255,7 @@ fun ColumnScope.AddRowSwitch(icon: Int, text: String) {
             HomeViewModel(context, scope)
         }
         val isConnect: Int? = homeViewModel.isConnect.observeAsState().value
+
 //        val vpnConnectionsUtil = VPNConnectionsUtil(context, act, homeViewModel)
 
         Surface(
@@ -379,9 +382,10 @@ fun ColumnScope.AddRowSettingsColumn(
         "Auto", "WireGuard", "IKEv2", "OpenVPN TCP", "OpenVPN UDP"
     )
     var selectedProtocol by remember { mutableStateOf(basePreferenceHelper.getProtocol().full_name) }
-    val serverListViewModel: ServerListViewModel = viewModel{
-        ServerListViewModel(context)
-    }
+    val serverListViewModel = serverListViewModelSplash
+//    val serverListViewModel: ServerListViewModel = viewModel{
+//        ServerListViewModel(context)
+//    }
     val configuration = LocalConfiguration.current
     val isTablet = configuration.screenWidthDp > 840
 
@@ -952,15 +956,16 @@ fun ColumnScope.AddRowSettingsSmart(
 
     if (isAnySpecificSheetOpen) {
         val sheetStateAny = rememberModalBottomSheetState()
-        val splashViewModel: SplashViewModel = viewModel{
-            SplashViewModel(context)
-        }
-        val serverListViewModel: ServerListViewModel = viewModel {
-            ServerListViewModel(context = context)
-        }
-        val searchListViewModel: SearchListViewModel = viewModel{
-            SearchListViewModel(context, serverListViewModel, splashViewModel)
-        }
+//        val splashViewModel: SplashViewModel = viewModel{
+//            SplashViewModel(context)
+//        }
+//        val serverListViewModel: ServerListViewModel = viewModel {
+//            ServerListViewModel(context = context)
+//        }
+//        val searchListViewModel: SearchListViewModel = viewModel{
+//            SearchListViewModel(context, serverListViewModel, splashViewModel)
+//        }
+        val searchListViewModel = searchListViewModelSplash
         val searchText = searchListViewModel.searchText.observeAsState().value
         val isActive = searchListViewModel.isActive.observeAsState().value
         val scope = rememberCoroutineScope()

+ 79 - 0
app/src/main/java/com/vpn/fastestvpnservice/viewmodels/ServerListViewModel.kt

@@ -1,6 +1,7 @@
 package com.vpn.fastestvpnservice.viewmodels
 
 import android.content.Context
+import android.location.Location
 import android.os.Looper
 import android.util.Log
 import androidx.lifecycle.LiveData
@@ -20,6 +21,8 @@ import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
 import com.vpn.fastestvpnservice.retrofit.RetrofitNetworkHandling
 import com.vpn.fastestvpnservice.retrofit.WebServiceFactory
 import com.vpn.fastestvpnservice.screens.isAlphabetList
+import com.vpn.fastestvpnservice.screens.recommendedListGlobal
+import com.vpn.fastestvpnservice.screens.smartLocationListGlobal
 import retrofit2.Call
 
 class ServerListViewModel(context: Context): ViewModel() {
@@ -32,6 +35,10 @@ class ServerListViewModel(context: Context): ViewModel() {
 
     var mutableLiveDataGroupServers = MutableLiveData<ArrayList<Server>>()
 
+    var _mutableLiveDataTest = MutableLiveData<Int>(0)
+    var liveDataTest: LiveData<Int> = _mutableLiveDataTest
+
+
     var _mutableLiveDataPing = MutableLiveData<Int?>(0)
     var liveDataPing: LiveData<Int?> = _mutableLiveDataPing
 
@@ -44,6 +51,9 @@ class ServerListViewModel(context: Context): ViewModel() {
     var _mutableLiveDataGetServers = MutableLiveData<ArrayList<Server>>()
     var liveDataGetServers: LiveData<ArrayList<Server>> = _mutableLiveDataGetServers
 
+    var _mutableLiveDataGetRecommendedServers = MutableLiveData<ArrayList<Server>>()
+    var liveDataGetRecommendedServers: LiveData<ArrayList<Server>> = _mutableLiveDataGetRecommendedServers
+
     var _mutableLiveDataGetServerData = MutableLiveData<ArrayList<ServerData>>(getServerData())
     var liveDataGetServerData: LiveData<ArrayList<ServerData>> = _mutableLiveDataGetServerData
 
@@ -55,6 +65,75 @@ class ServerListViewModel(context: Context): ViewModel() {
         _mutableLiveDataPagerIndex.value = index
     }
 
+    fun setRecommendedSmartServers() {
+        val smartLocationList: MutableList<Server> = ArrayList<Server>()
+
+        preferencesHelper.getServerData().get(0).servers?.let {
+            val serverDataLocation = it
+
+            val distinctdatanotnull =
+                serverDataLocation.filter {   // servers's lt and lt not be null
+                    it.lt != null && it.lg != null
+                }
+
+            val distinctdata =
+                distinctdatanotnull.distinctBy { // servers's lt filter, no same lt of a server
+                    it.lt
+                }
+
+            val result = FloatArray(1)
+            val ipinfo = preferencesHelper.getIpinfo()
+
+            distinctdata.forEachIndexed { index, server ->
+                val lat1 = ipinfo?.latitute
+                val lon1 = ipinfo?.longitude
+                val lat2 = server.lt
+                val lon2 = server.lg
+
+                if (lat1 != null && lat2 != null && lon1 != null && lon2 != null) {
+                    Location.distanceBetween(lat1, lon1, lat2, lon2, result)
+                }
+
+                val distance: Float = result[0]
+                distinctdata.get(index).distance = distance
+
+            }
+
+            val sortedDistance = distinctdata.sortedBy {
+                it.distance
+            }
+
+            if (sortedDistance.isNotEmpty()) {
+                for (i in 0..2) {
+                    calculatePing(sortedDistance.get(i)) {
+                        sortedDistance.get(i).ping = it
+                    }
+                    recommendedListGlobal.add(sortedDistance.get(i))
+                    Log.d("recommendedListGlobal", "SS:: server = ${sortedDistance.get(i).server_name}")
+                }
+            }
+
+            _mutableLiveDataGetRecommendedServers.value = recommendedListGlobal
+
+            if (sortedDistance.isNotEmpty()) {
+                for (i in 0..0) {
+//                    smartLocationList.add(sortedDistance.get(i))
+                    calculatePing(sortedDistance.get(i)) {
+                        sortedDistance.get(i).ping = it
+                    }
+                    smartLocationListGlobal.add(sortedDistance.get(i))
+                }
+            }
+
+            smartLocationList.forEach {
+//                preferencesHelper.setSmartServerObject(it)
+                preferencesHelper.setRecommendedServerObject(it)
+                Log.d("smartLocationList", "SS:: server = ${it.server_name}")
+            }
+
+        }
+
+    }
     fun calculatePing(server: Server, onPingResult: (Int) -> Unit) {
         Ping.onAddress(server.ip as String).setTimeOutMillis(1000).doPing(
             object : Ping.PingListener{

+ 1 - 0
app/src/main/java/com/vpn/fastestvpnservice/viewmodels/SplashViewModel.kt

@@ -2,6 +2,7 @@ package com.vpn.fastestvpnservice.viewmodels
 
 import android.content.Context
 import android.util.Log
+import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import com.google.gson.Gson