LoginScreen.kt 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. package com.vpn.fastestvpnservice.screens
  2. import android.app.Activity
  3. import android.content.Context
  4. import android.content.Intent
  5. import android.content.res.Configuration
  6. import android.location.Location
  7. import android.util.Log
  8. import androidx.compose.foundation.Image
  9. import androidx.compose.foundation.background
  10. import androidx.compose.foundation.border
  11. import androidx.compose.foundation.clickable
  12. import androidx.compose.foundation.gestures.detectTapGestures
  13. import androidx.compose.foundation.layout.Arrangement
  14. import androidx.compose.foundation.layout.Box
  15. import androidx.compose.foundation.layout.Column
  16. import androidx.compose.foundation.layout.ColumnScope
  17. import androidx.compose.foundation.layout.Row
  18. import androidx.compose.foundation.layout.RowScope
  19. import androidx.compose.foundation.layout.Spacer
  20. import androidx.compose.foundation.layout.WindowInsets
  21. import androidx.compose.foundation.layout.fillMaxSize
  22. import androidx.compose.foundation.layout.fillMaxWidth
  23. import androidx.compose.foundation.layout.height
  24. import androidx.compose.foundation.layout.padding
  25. import androidx.compose.foundation.layout.size
  26. import androidx.compose.foundation.layout.systemBars
  27. import androidx.compose.foundation.layout.windowInsetsPadding
  28. import androidx.compose.foundation.shape.RoundedCornerShape
  29. import androidx.compose.foundation.text.ClickableText
  30. import androidx.compose.foundation.text.KeyboardActions
  31. import androidx.compose.foundation.text.KeyboardOptions
  32. import androidx.compose.material.icons.Icons
  33. import androidx.compose.material.icons.filled.Warning
  34. import androidx.compose.material.icons.outlined.Visibility
  35. import androidx.compose.material.rememberScaffoldState
  36. import androidx.compose.material3.Button
  37. import androidx.compose.material3.ButtonDefaults
  38. import androidx.compose.material3.CircularProgressIndicator
  39. import androidx.compose.material3.Icon
  40. import androidx.compose.material3.IconButton
  41. import androidx.compose.material3.MaterialTheme
  42. import androidx.compose.material3.Scaffold
  43. import androidx.compose.material3.SnackbarHostState
  44. import androidx.compose.material3.Text
  45. import androidx.compose.material3.TextField
  46. import androidx.compose.material3.TextFieldDefaults
  47. import androidx.compose.runtime.Composable
  48. import androidx.compose.runtime.LaunchedEffect
  49. import androidx.compose.runtime.getValue
  50. import androidx.compose.runtime.livedata.observeAsState
  51. import androidx.compose.runtime.mutableFloatStateOf
  52. import androidx.compose.runtime.mutableStateOf
  53. import androidx.compose.runtime.remember
  54. import androidx.compose.runtime.rememberCoroutineScope
  55. import androidx.compose.runtime.setValue
  56. import androidx.compose.ui.Alignment
  57. import androidx.compose.ui.ExperimentalComposeUiApi
  58. import androidx.compose.ui.Modifier
  59. import androidx.compose.ui.draw.alpha
  60. import androidx.compose.ui.draw.paint
  61. import androidx.compose.ui.graphics.Color
  62. import androidx.compose.ui.graphics.toArgb
  63. import androidx.compose.ui.input.pointer.pointerInput
  64. import androidx.compose.ui.layout.ContentScale
  65. import androidx.compose.ui.platform.LocalContext
  66. import androidx.compose.ui.platform.LocalFocusManager
  67. import androidx.compose.ui.platform.LocalSoftwareKeyboardController
  68. import androidx.compose.ui.platform.LocalView
  69. import androidx.compose.ui.res.colorResource
  70. import androidx.compose.ui.res.painterResource
  71. import androidx.compose.ui.text.AnnotatedString
  72. import androidx.compose.ui.text.TextStyle
  73. import androidx.compose.ui.text.font.FontWeight
  74. import androidx.compose.ui.text.input.ImeAction
  75. import androidx.compose.ui.text.input.KeyboardType
  76. import androidx.compose.ui.text.input.PasswordVisualTransformation
  77. import androidx.compose.ui.text.input.VisualTransformation
  78. import androidx.compose.ui.text.style.TextAlign
  79. import androidx.compose.ui.tooling.preview.Preview
  80. import androidx.compose.ui.unit.dp
  81. import androidx.compose.ui.unit.sp
  82. import androidx.lifecycle.viewmodel.compose.viewModel
  83. import androidx.navigation.NavHostController
  84. import androidx.navigation.compose.rememberNavController
  85. import com.vpn.fastestvpnservice.R
  86. import com.vpn.fastestvpnservice.beans.Server
  87. import com.vpn.fastestvpnservice.beans.filterList
  88. import com.vpn.fastestvpnservice.beans.isDarkTheme
  89. import com.vpn.fastestvpnservice.constants.smartConnect
  90. import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
  91. import com.vpn.fastestvpnservice.sealedClass.Screen
  92. import com.vpn.fastestvpnservice.ui.theme.customTypography
  93. import com.vpn.fastestvpnservice.ui.theme.outfitFontFamily
  94. import com.vpn.fastestvpnservice.viewmodels.LoginViewModel
  95. import com.vpn.fastestvpnservice.viewmodels.SearchListViewModel
  96. import com.vpn.fastestvpnservice.viewmodels.ServerListViewModel
  97. import com.vpn.fastestvpnservice.viewmodels.SplashViewModel
  98. import com.vpn.fastestvpnservice.views.CustomValidation
  99. import com.vpn.fastestvpnservice.views.ShowCustomSnackBar
  100. import com.vpn.fastestvpnservice.widgets.SimpleAppWidget
  101. import kotlinx.coroutines.delay
  102. import kotlinx.coroutines.launch
  103. import kotlin.random.Random
  104. @OptIn(ExperimentalComposeUiApi::class)
  105. @Composable
  106. fun Login(navHostController: NavHostController) {
  107. val keyboardController = LocalSoftwareKeyboardController.current
  108. val focusManager = LocalFocusManager.current
  109. val random = Random.nextInt(1,999)
  110. val loginViewModel: LoginViewModel = viewModel()
  111. val readOnly = loginViewModel.liveDataLoginStatus.observeAsState().value
  112. var textChanged by remember { mutableStateOf("") }
  113. var passwordChanged by remember { mutableStateOf("") }
  114. var passwordVisible by remember { mutableStateOf(false) }
  115. var showErrorEmail by remember { mutableStateOf(false) }
  116. var showErrorPass1 by remember { mutableStateOf(false) }
  117. var showErrorPass2 by remember { mutableStateOf(false) }
  118. val context = LocalContext.current
  119. val basePreferenceHelper = BasePreferenceHelper(context)
  120. val snackBarState = remember { SnackbarHostState() }
  121. val snackBarStateRed = remember { SnackbarHostState() }
  122. Scaffold(
  123. content = { padding ->
  124. Box(
  125. modifier = Modifier
  126. .fillMaxSize()
  127. .paint(
  128. painter = painterResource(id = if (isDarkTheme.value) R.drawable.bg_app else R.drawable.bg_img3),
  129. contentScale = ContentScale.FillBounds
  130. )
  131. .alpha(if (readOnly == true) 0.6F else 1F)
  132. .windowInsetsPadding(WindowInsets.systemBars)
  133. // .background(
  134. // if (isSystemInDarkTheme()) Color.Black
  135. // else Color.Transparent
  136. // )
  137. .pointerInput(Unit) {
  138. detectTapGestures {
  139. focusManager.clearFocus()
  140. keyboardController?.hide()
  141. }
  142. },
  143. ) {
  144. val view = LocalView.current
  145. val window = (view.context as Activity).window
  146. window.statusBarColor = Color.Transparent.toArgb()
  147. window.navigationBarColor = Color.Transparent.toArgb()
  148. ShowCustomSnackBar(snackBarState, R.color.switch_green, R.color.white)
  149. ShowCustomSnackBar(snackBarStateRed, R.color.Red, R.color.white)
  150. if (loginViewModel.liveDataLoginStatus.value == true) {
  151. var progress by remember { mutableFloatStateOf(0.1F) }
  152. LaunchedEffect(key1 = Unit) {
  153. while (true) {
  154. for (i in 1..100) {
  155. progress = i.toFloat()/100F
  156. delay(150)
  157. }
  158. progress = 0.1F
  159. }
  160. }
  161. CircularProgressIndicator(
  162. progress = { progress },
  163. modifier = Modifier
  164. .size(50.dp)
  165. .align(Alignment.Center),
  166. color = colorResource(id = R.color.yellow_text),
  167. strokeWidth = 5.dp,
  168. )
  169. }
  170. Image(
  171. painter = painterResource(
  172. id = R.drawable.fastestapp_logo3x),
  173. contentDescription = "FastestVPN",
  174. modifier = Modifier
  175. .padding(top = 50.dp)
  176. .size(width = 75.dp, height = 102.dp)
  177. .align(Alignment.TopCenter)
  178. ,
  179. )
  180. Column (
  181. modifier = Modifier.align(Alignment.Center),
  182. verticalArrangement = Arrangement.Center,
  183. horizontalAlignment = Alignment.CenterHorizontally
  184. ) {
  185. TextMsg(
  186. text = context.getString(R.string.welcome_back),
  187. color = Color.White,
  188. style = MaterialTheme.typography.displayLarge
  189. )
  190. Spacer(modifier = Modifier.height(8.dp))
  191. TextMsg(
  192. text = context.getString(R.string.please_login),
  193. color = colorResource(id = R.color.white),
  194. style = MaterialTheme.typography.customTypography.labelLarge,
  195. alpha = 0.6F
  196. )
  197. Spacer(modifier = Modifier.height(20.dp))
  198. TextField(
  199. value = textChanged,
  200. onValueChange = {
  201. textChanged = it
  202. },
  203. readOnly = readOnly!!,
  204. textStyle = MaterialTheme.typography.customTypography.bodyMedium,
  205. modifier = Modifier
  206. .padding(start = 15.dp, end = 15.dp)
  207. .align(Alignment.Start)
  208. .fillMaxWidth()
  209. .height(60.dp)
  210. .border(
  211. 1.dp,
  212. color = if (showErrorEmail) colorResource(id = R.color.red)
  213. else colorResource(id = R.color.white),
  214. shape = RoundedCornerShape(16.dp)
  215. )
  216. .background(color = colorResource(id = R.color.transparent))
  217. .clickable() { },
  218. shape = RoundedCornerShape(16.dp),
  219. // placeholder = {
  220. // Text(text = "Enter email address",
  221. // color = colorResource(id = R.color.white))
  222. // },
  223. label = {
  224. Text(text = context.getString(R.string.email),
  225. style = MaterialTheme.typography.customTypography.bodySmall
  226. )
  227. },
  228. leadingIcon = {
  229. Icon(
  230. painter = painterResource(id = R.drawable.sms3x),
  231. contentDescription = "Email Logo",
  232. tint = colorResource(id = R.color.white),
  233. modifier = Modifier
  234. .size(24.dp, 24.dp)
  235. )
  236. },
  237. maxLines = 1,
  238. colors = TextFieldDefaults.colors(
  239. focusedLabelColor = Color.Blue,
  240. unfocusedContainerColor = colorResource(id = R.color.transparent),
  241. focusedContainerColor = MaterialTheme.colorScheme.secondaryContainer,
  242. focusedIndicatorColor = colorResource(id = R.color.transparent),
  243. disabledIndicatorColor = colorResource(id = R.color.transparent),
  244. unfocusedIndicatorColor = colorResource(id = R.color.transparent),
  245. cursorColor = colorResource(id = R.color.white),
  246. ),
  247. keyboardOptions = KeyboardOptions(
  248. keyboardType = KeyboardType.Email,
  249. imeAction = ImeAction.Done
  250. ),
  251. keyboardActions = KeyboardActions(
  252. onDone = {
  253. focusManager.clearFocus()
  254. keyboardController?.hide()
  255. }
  256. ),
  257. )
  258. Spacer(modifier = Modifier.height(20.dp))
  259. val color = if (showErrorPass1) {
  260. colorResource(id = R.color.red)
  261. }
  262. else if (showErrorPass2) {
  263. colorResource(id = R.color.red)
  264. }
  265. else {
  266. colorResource(id = R.color.white)
  267. }
  268. TextField(
  269. value = passwordChanged,
  270. onValueChange = {
  271. // Log.d("onClick_test", "onValueChange -> ")
  272. passwordChanged = it
  273. },
  274. readOnly = readOnly,
  275. textStyle = MaterialTheme.typography.customTypography.bodyLarge,
  276. modifier = Modifier
  277. .padding(start = 15.dp, end = 15.dp)
  278. .align(Alignment.Start)
  279. .fillMaxWidth()
  280. .height(60.dp)
  281. .border(
  282. 1.dp,
  283. color = color,
  284. shape = RoundedCornerShape(16.dp)
  285. )
  286. .background(color = colorResource(id = R.color.transparent))
  287. .clickable() {},
  288. shape = RoundedCornerShape(16.dp),
  289. // placeholder = {
  290. // Text(text = "Enter password",
  291. // color = colorResource(id = R.color.white))
  292. // },
  293. label = {
  294. Text(text = context.getString(R.string.password),
  295. style = MaterialTheme.typography.customTypography.bodyLarge
  296. )
  297. },
  298. leadingIcon = {
  299. Icon(
  300. painter = painterResource(id = R.drawable.lock3x),
  301. contentDescription = "Password Logo",
  302. tint = colorResource(id = R.color.white),
  303. modifier = Modifier
  304. .size(24.dp, 24.dp)
  305. )
  306. },
  307. maxLines = 1,
  308. colors = TextFieldDefaults.colors(
  309. focusedLabelColor = Color.Blue,
  310. unfocusedContainerColor = colorResource(id = R.color.transparent),
  311. focusedContainerColor = MaterialTheme.colorScheme.secondaryContainer,
  312. focusedIndicatorColor = colorResource(id = R.color.transparent),
  313. disabledIndicatorColor = colorResource(id = R.color.transparent),
  314. unfocusedIndicatorColor = colorResource(id = R.color.transparent),
  315. cursorColor = colorResource(id = R.color.white)
  316. ),
  317. keyboardOptions = KeyboardOptions(
  318. keyboardType = KeyboardType.Password,
  319. imeAction = ImeAction.Done
  320. ),
  321. keyboardActions = KeyboardActions(
  322. onDone = {
  323. focusManager.clearFocus()
  324. keyboardController?.hide()
  325. }
  326. ),
  327. visualTransformation =
  328. if (passwordVisible) VisualTransformation.Companion.None
  329. else PasswordVisualTransformation(),
  330. trailingIcon = {
  331. // val image
  332. // = if (passwordVisible) Icons.Filled.Visibility
  333. // else Icons.Filled.VisibilityOff
  334. val description = if (passwordVisible) "Hide Password"
  335. else "Show Password"
  336. IconButton(onClick = {
  337. if (!readOnly) {
  338. passwordVisible = !passwordVisible
  339. }
  340. })
  341. {
  342. if (passwordVisible) {
  343. Icon(
  344. imageVector = Icons.Outlined.Visibility,
  345. contentDescription = description,
  346. tint = colorResource(id = R.color.white),
  347. modifier = Modifier.size(24.dp)
  348. )
  349. }
  350. else {
  351. Icon(
  352. painter = painterResource(id = R.drawable.eye_slash3x),
  353. contentDescription = description,
  354. tint = colorResource(id = R.color.white),
  355. modifier = Modifier.size(24.dp)
  356. )
  357. }
  358. }
  359. }
  360. )
  361. Spacer(modifier = Modifier.height(20.dp))
  362. ClickableText(
  363. onClick = {
  364. if (!readOnly) {
  365. // Log.d("onClick_test", "Forgot Password Clicked")
  366. navHostController.navigate(Screen.ForgotPassword.route)
  367. }
  368. },
  369. modifier = Modifier
  370. .padding(end = 15.dp)
  371. .align(Alignment.End),
  372. style = MaterialTheme.typography.customTypography.titleSmall,
  373. text = AnnotatedString(context.getString(R.string.forgot_pass)),
  374. )
  375. }
  376. Column(
  377. modifier = Modifier.align(Alignment.BottomCenter)
  378. ) {
  379. SignInButton(
  380. navHostController = navHostController,
  381. textChanged,
  382. passwordChanged,
  383. loginViewModel = loginViewModel,
  384. basePreferenceHelper,
  385. showErrorEmail = {
  386. showErrorEmail = it
  387. },
  388. showErrorEmail,
  389. showErrorPass = {
  390. showErrorPass1 = it
  391. },
  392. showErrorPass1,
  393. showErrorPass2 = {
  394. showErrorPass2 = it
  395. },
  396. showErrorPass2,
  397. snackBarState,
  398. snackBarStateRed,
  399. context
  400. )
  401. Row (
  402. modifier = Modifier
  403. .padding(bottom = 25.dp)
  404. .align(Alignment.CenterHorizontally),
  405. ){
  406. TextMsgSignUp(navHostController = navHostController, loginViewModel, readOnly!!, context)
  407. }
  408. }
  409. }
  410. }
  411. )
  412. }
  413. @Composable
  414. fun ColumnScope.ShowErrorRow(
  415. errorText: String
  416. ) {
  417. Row(
  418. verticalAlignment = Alignment.CenterVertically,
  419. modifier = Modifier
  420. .align(Alignment.Start)
  421. .padding(start = 16.dp, top = 3.dp)
  422. ) {
  423. Icon(imageVector = Icons.Default.Warning,
  424. contentDescription = "Error",
  425. tint = colorResource(id = R.color.red),
  426. modifier = Modifier.size(14.dp)
  427. )
  428. Text(text = errorText,
  429. style = TextStyle(
  430. fontFamily = outfitFontFamily,
  431. fontWeight = FontWeight.Normal,
  432. fontSize = 14.sp,
  433. color = colorResource(id = R.color.red)
  434. ),
  435. modifier = Modifier.padding(start = 5.dp)
  436. )
  437. }
  438. }
  439. @Composable
  440. fun RowScope.TextMsgSignUp(
  441. navHostController: NavHostController,
  442. loginViewModel: LoginViewModel,
  443. isEnabled: Boolean,
  444. context: Context
  445. ) {
  446. Text(
  447. modifier = Modifier
  448. .padding(0.dp),
  449. text = context.getString(R.string.dont_have_acc),
  450. style = MaterialTheme.typography.customTypography.labelLarge,
  451. )
  452. ClickableText(
  453. onClick = {
  454. if (!isEnabled) {
  455. navHostController.navigate(Screen.SignUp.route)
  456. }
  457. },
  458. modifier = Modifier
  459. .padding(0.dp),
  460. style = MaterialTheme.typography.customTypography.titleMedium,
  461. text = AnnotatedString(" ${context.getString(R.string.signup)}"),
  462. )
  463. }
  464. @Composable
  465. fun ColumnScope.SignInButton(
  466. navHostController: NavHostController,
  467. email: String,
  468. password: String,
  469. loginViewModel: LoginViewModel,
  470. prefHelper: BasePreferenceHelper,
  471. showErrorEmail: (Boolean) -> Unit,
  472. isError: Boolean,
  473. showErrorPass: (Boolean) -> Unit,
  474. isErrorPass: Boolean,
  475. showErrorPass2: (Boolean) -> Unit,
  476. isErrorPass2: Boolean,
  477. snackBarState: SnackbarHostState,
  478. snackBarStateRed: SnackbarHostState,
  479. context: Context
  480. ) {
  481. val scaffoldState = rememberScaffoldState()
  482. val coroutineScope = rememberCoroutineScope()
  483. val customValidation = CustomValidation()
  484. if (isError) {
  485. if (email.isNotEmpty()) {
  486. showErrorEmail(false)
  487. }
  488. }
  489. if (isErrorPass) {
  490. if (password.isNotEmpty()) {
  491. showErrorPass(false)
  492. }
  493. }
  494. if (isErrorPass2) {
  495. if (password.isNotEmpty()) {
  496. val isErrorPassSize = customValidation.isValidPassword(password)
  497. if (isErrorPassSize) {
  498. showErrorPass2(false)
  499. }
  500. }
  501. }
  502. Button(
  503. modifier = Modifier
  504. .padding(
  505. start = 15.dp, end = 15.dp,
  506. bottom = 25.dp
  507. )
  508. .background(colorResource(id = R.color.transparent))
  509. .fillMaxWidth()
  510. .height(60.dp)
  511. .clickable() { },
  512. onClick = {
  513. // Log.d("test_api_response live", "Login Clicked:")
  514. val isErrors = customValidation.isValidText(email, "Email")
  515. showErrorEmail(!isErrors)
  516. val isError1 = customValidation.isValidText(password, "Password")
  517. showErrorPass(!isError1)
  518. val isError2 = customValidation.isValidPassword(password)
  519. if (password.isNotEmpty()) {
  520. showErrorPass2(!isError2)
  521. }
  522. Log.d("test_snackbar", "sb in = $isErrors")
  523. if (!isErrors) {
  524. // ShowErrorRow(errorText = "Email is Empty")
  525. coroutineScope.launch {
  526. snackBarStateRed.showSnackbar("Email is Empty")
  527. }
  528. }
  529. else if (!isError1) {
  530. // ShowErrorRow(errorText = "Password is Empty")
  531. coroutineScope.launch {
  532. snackBarStateRed.showSnackbar("Password is Empty")
  533. }
  534. }
  535. else if (!isError2) {
  536. // ShowErrorRow(errorText = "Should be 3 or more!")
  537. coroutineScope.launch {
  538. snackBarStateRed.showSnackbar("Password should be 3 or more!")
  539. }
  540. }
  541. // showLoader = true
  542. if (loginViewModel.liveDataLoginStatus.value == false) {
  543. // Log.d("test_api_response live", "SignIn: $email $password")
  544. if (customValidation.isValidText(email, "Email") &&
  545. customValidation.isValidText(password, "Password") &&
  546. customValidation.isValidPassword(password)) {
  547. // Log.d("test_login_text", "true")
  548. if (email.isNotEmpty() && password.isNotEmpty()) {
  549. loginViewModel.setLoginStatus(true)
  550. loginViewModel.loginRequest(
  551. email,
  552. password,
  553. "android",
  554. "11",
  555. "3.2.4"
  556. )
  557. }
  558. }
  559. }
  560. },
  561. shape = RoundedCornerShape(15.dp),
  562. // border = BorderStroke(25.dp, colorResource(id = R.color.black)),
  563. colors = ButtonDefaults.buttonColors(
  564. contentColor = MaterialTheme.colorScheme.primaryContainer,
  565. containerColor = MaterialTheme.colorScheme.onSecondaryContainer,
  566. ),
  567. )
  568. {
  569. Text(text = context.getString(R.string.signin),
  570. style = MaterialTheme.typography.titleMedium,
  571. textAlign = TextAlign.Center
  572. )
  573. val context = LocalContext.current
  574. val loginData by loginViewModel.liveDataUserResponse.observeAsState()
  575. loginData?.let { response ->
  576. // Log.d("test_api_response live", "live: ${loginData?.status} ${loginData?.message}")
  577. loginViewModel.setLoginStatus(false)
  578. // showLoader = false
  579. if (response.status) {
  580. response.data?.let {
  581. prefHelper.setLoggedInState(true)
  582. prefHelper.savePassword(password)
  583. prefHelper.saveUser(it)
  584. it.wireguard?.let { wg ->
  585. prefHelper.saveWireGuard(wg)
  586. // Log.d("test_wg_data", "Login:: ${wg.ip} ${wg.key}")
  587. }
  588. it.product?.let { it1 -> prefHelper.saveProduct(it1) }
  589. prefHelper.saveEnabledProtocols(it.enabled_protocols)
  590. prefHelper.saveAvailableProtocols(it.available_protocols)
  591. prefHelper.saveXPlatformToken(it.userinfo?.email + "_" + System.currentTimeMillis())
  592. prefHelper.saveAdBlockState(false)
  593. // prefHelper.saveTheme(themesList[0])
  594. prefHelper.saveFilterList(filterList[0])
  595. prefHelper.saveSmartList(smartConnect[0])
  596. it.servers?.let {
  597. prefHelper.saveServerData(it)
  598. }
  599. // Log.d("bearer_token", it.token.toString())
  600. // upgradePriceViewModel.getProducts()
  601. prefHelper.getFcmToken().let {
  602. loginViewModel.sendFcmToken(it)
  603. // Log.d("Refreshed token: ", "Login: $it")
  604. }
  605. val smartLocationList: MutableList<Server> = ArrayList<Server>()
  606. prefHelper.getServerData().get(0).servers?.let {
  607. val serverDataLocation = it
  608. val distinctdatanotnull =
  609. serverDataLocation.filter { // servers's lt and lt not be null
  610. it.lt != null && it.lg != null
  611. }
  612. val distinctdata =
  613. distinctdatanotnull.distinctBy { // servers's lt filter, no same lt of a server
  614. it.lt
  615. }
  616. val result = FloatArray(1)
  617. val ipinfo = prefHelper.getIpinfo()
  618. distinctdata.forEachIndexed { index, server ->
  619. val lat1 = ipinfo?.latitute
  620. val lon1 = ipinfo?.longitude
  621. val lat2 = server.lt
  622. val lon2 = server.lg
  623. if (lat1 != null && lat2 != null && lon1 != null && lon2 != null) {
  624. Location.distanceBetween(lat1, lon1, lat2, lon2, result)
  625. }
  626. val distance: Float = result[0]
  627. distinctdata.get(index).distance = distance
  628. }
  629. val sortedDistance = distinctdata.sortedBy {
  630. it.distance
  631. }
  632. if (sortedDistance.isNotEmpty()) {
  633. for (i in 0..0) {
  634. smartLocationList.add(sortedDistance.get(i))
  635. }
  636. }
  637. smartLocationList.forEach {
  638. // prefHelper.setSmartServerObject(it)
  639. prefHelper.setRecommendedServerObject(it)
  640. Log.d("smartLocationList", "L:: server = ${it.server_name}")
  641. }
  642. }
  643. // setCustomLocale(context)
  644. splashViewModelSplash = viewModel {
  645. SplashViewModel(context)
  646. }
  647. serverListViewModelSplash = viewModel {
  648. ServerListViewModel(context = context)
  649. }
  650. searchListViewModelSplash = viewModel {
  651. SearchListViewModel(context, serverListViewModelSplash, splashViewModelSplash)
  652. }
  653. serverListViewModelSplash.setRecommendedSmartServers()
  654. serverListViewModelSplash.setCountryData()
  655. val widgetIntent = Intent(context, SimpleAppWidget::class.java)
  656. widgetIntent.action = SimpleAppWidget.ACTION_LOGIN
  657. context.sendBroadcast(widgetIntent)
  658. navHostController.popBackStack()
  659. navHostController.navigate(Screen.BottomBarMainScreen.route)
  660. }
  661. }
  662. else {
  663. response.message?.let {
  664. // Log.d("test_login_msg", "${response.message}")
  665. coroutineScope.launch {
  666. snackBarStateRed.showSnackbar(it)
  667. }
  668. }
  669. }
  670. loginViewModel.mutableLiveDataUserResponse.value = null
  671. }
  672. }
  673. }
  674. @Composable
  675. fun ColumnScope.TextMsg(
  676. text: String,
  677. color: Color,
  678. style: TextStyle,
  679. alpha: Float = 1F
  680. ) {
  681. Text(
  682. modifier = Modifier
  683. .padding(start = 15.dp)
  684. .align(Alignment.Start)
  685. .alpha(alpha),
  686. style = style,
  687. text = text,
  688. color = color,
  689. )
  690. }
  691. @Preview
  692. @Composable
  693. fun LoginPreview() {
  694. Login(rememberNavController())
  695. }
  696. @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
  697. @Composable
  698. fun LoginPreviewDark() {
  699. Login(rememberNavController())
  700. }