浏览代码

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

Khubaib 11 月之前
父节点
当前提交
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