LoginScreen.kt 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. package com.vpn.fastestvpnservice.screens
  2. import android.content.res.Configuration
  3. import android.gesture.Gesture
  4. import android.util.Log
  5. import android.widget.Toast
  6. import androidx.activity.OnBackPressedCallback
  7. import androidx.compose.foundation.BorderStroke
  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.interaction.MutableInteractionSource
  14. import androidx.compose.foundation.isSystemInDarkTheme
  15. import androidx.compose.foundation.layout.Arrangement
  16. import androidx.compose.foundation.layout.Box
  17. import androidx.compose.foundation.layout.BoxScope
  18. import androidx.compose.foundation.layout.Column
  19. import androidx.compose.foundation.layout.ColumnScope
  20. import androidx.compose.foundation.layout.Row
  21. import androidx.compose.foundation.layout.RowScope
  22. import androidx.compose.foundation.layout.Spacer
  23. import androidx.compose.foundation.layout.fillMaxHeight
  24. import androidx.compose.foundation.layout.fillMaxSize
  25. import androidx.compose.foundation.layout.fillMaxWidth
  26. import androidx.compose.foundation.layout.height
  27. import androidx.compose.foundation.layout.padding
  28. import androidx.compose.foundation.layout.size
  29. import androidx.compose.foundation.layout.width
  30. import androidx.compose.foundation.shape.RoundedCornerShape
  31. import androidx.compose.foundation.text.ClickableText
  32. import androidx.compose.foundation.text.KeyboardActionScope
  33. import androidx.compose.foundation.text.KeyboardActions
  34. import androidx.compose.foundation.text.KeyboardOptions
  35. import androidx.compose.material.icons.Icons
  36. import androidx.compose.material.icons.filled.Email
  37. import androidx.compose.material.icons.filled.Home
  38. import androidx.compose.material.icons.filled.Lock
  39. import androidx.compose.material.icons.filled.Visibility
  40. import androidx.compose.material.icons.filled.VisibilityOff
  41. import androidx.compose.material.icons.outlined.Visibility
  42. import androidx.compose.material3.Button
  43. import androidx.compose.material3.ButtonColors
  44. import androidx.compose.material3.ButtonDefaults
  45. import androidx.compose.material3.ButtonElevation
  46. import androidx.compose.material3.CircularProgressIndicator
  47. import androidx.compose.material3.ElevatedButton
  48. import androidx.compose.material3.Icon
  49. import androidx.compose.material3.IconButton
  50. import androidx.compose.material3.Text
  51. import androidx.compose.material3.TextField
  52. import androidx.compose.material3.TextFieldColors
  53. import androidx.compose.material3.TextFieldDefaults
  54. import androidx.compose.runtime.Composable
  55. import androidx.compose.runtime.LaunchedEffect
  56. import androidx.compose.runtime.setValue
  57. import androidx.compose.runtime.getValue
  58. import androidx.compose.runtime.livedata.observeAsState
  59. import androidx.compose.runtime.mutableFloatStateOf
  60. import androidx.compose.runtime.mutableStateOf
  61. import androidx.compose.runtime.remember
  62. import androidx.compose.runtime.rememberCompositionContext
  63. import androidx.compose.ui.Alignment
  64. import androidx.compose.ui.ExperimentalComposeUiApi
  65. import androidx.compose.ui.Modifier
  66. import androidx.compose.ui.draw.alpha
  67. import androidx.compose.ui.draw.paint
  68. import androidx.compose.ui.graphics.Color
  69. import androidx.compose.ui.input.pointer.pointerInput
  70. import androidx.compose.ui.layout.ContentScale
  71. import androidx.compose.ui.platform.LocalContext
  72. import androidx.compose.ui.platform.LocalFocusManager
  73. import androidx.compose.ui.platform.LocalSoftwareKeyboardController
  74. import androidx.compose.ui.res.colorResource
  75. import androidx.compose.ui.res.painterResource
  76. import androidx.compose.ui.text.AnnotatedString
  77. import androidx.compose.ui.text.TextStyle
  78. import androidx.compose.ui.text.font.FontStyle
  79. import androidx.compose.ui.text.font.FontWeight
  80. import androidx.compose.ui.text.input.ImeAction
  81. import androidx.compose.ui.text.input.KeyboardType
  82. import androidx.compose.ui.text.input.PasswordVisualTransformation
  83. import androidx.compose.ui.text.input.VisualTransformation
  84. import androidx.compose.ui.text.style.TextAlign
  85. import androidx.compose.ui.tooling.preview.Preview
  86. import androidx.compose.ui.unit.TextUnit
  87. import androidx.compose.ui.unit.dp
  88. import androidx.compose.ui.unit.sp
  89. import androidx.lifecycle.viewmodel.compose.viewModel
  90. import androidx.navigation.NavController
  91. import androidx.navigation.NavHostController
  92. import androidx.navigation.compose.rememberNavController
  93. import com.vpn.fastestvpnservice.R
  94. import com.vpn.fastestvpnservice.beans.DataResponse
  95. import com.vpn.fastestvpnservice.beans.UserResponse
  96. import com.vpn.fastestvpnservice.beans.themesList
  97. import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
  98. import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.AddText
  99. import com.vpn.fastestvpnservice.sealedClass.Screen
  100. import com.vpn.fastestvpnservice.viewmodels.LoginViewModel
  101. import kotlinx.coroutines.delay
  102. import kotlin.coroutines.coroutineContext
  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. val context = LocalContext.current
  116. var basePreferenceHelper = BasePreferenceHelper(context)
  117. Box(
  118. modifier = Modifier
  119. .fillMaxSize()
  120. .paint(
  121. painter = painterResource(id = R.drawable.bg_img3),
  122. contentScale = ContentScale.FillBounds
  123. )
  124. .alpha(if (readOnly == true) 0.6F else 1F)
  125. // .background(
  126. // if (isSystemInDarkTheme()) Color.Black
  127. // else Color.Transparent
  128. // )
  129. .pointerInput(Unit) {
  130. detectTapGestures {
  131. focusManager.clearFocus()
  132. keyboardController?.hide()
  133. }
  134. }
  135. ,
  136. // contentAlignment = Alignment.Center
  137. ) {
  138. Column (
  139. modifier = Modifier
  140. .fillMaxHeight()
  141. .fillMaxWidth()
  142. ,
  143. verticalArrangement = Arrangement.Top,
  144. horizontalAlignment = Alignment.CenterHorizontally
  145. ) {
  146. Spacer(modifier = Modifier.height(132.dp))
  147. Image(
  148. painter = painterResource(
  149. id = R.drawable.fastestapp_logo3x),
  150. contentDescription = "FastestVPN",
  151. modifier = Modifier
  152. .size(width = 75.dp, height = 102.dp)
  153. .background(Color.Transparent)
  154. .padding(top = 0.dp)
  155. ,
  156. )
  157. Spacer(modifier = Modifier.height(50.dp))
  158. TextMsg(
  159. fontSize = 28.sp,
  160. text = "Welcome Back!",
  161. color = Color.White
  162. )
  163. TextMsg(
  164. fontSize = 14.sp,
  165. text = "Please login to your account.",
  166. color = colorResource(id = R.color.light_grey)
  167. )
  168. Spacer(modifier = Modifier.height(20.dp))
  169. TextField(
  170. value = textChanged,
  171. onValueChange = {
  172. textChanged = it
  173. },
  174. readOnly = readOnly!!,
  175. textStyle = TextStyle(
  176. fontSize = 20.sp,
  177. color = colorResource(id = R.color.white),
  178. ),
  179. modifier = Modifier
  180. .padding(start = 15.dp, end = 15.dp)
  181. .align(Alignment.Start)
  182. .fillMaxWidth()
  183. .height(60.dp)
  184. .border(
  185. 1.dp,
  186. color = colorResource(id = R.color.white),
  187. shape = RoundedCornerShape(16.dp)
  188. )
  189. .clickable() { },
  190. // placeholder = {
  191. // Text(text = "Enter email address",
  192. // color = colorResource(id = R.color.white))
  193. // },
  194. label = {
  195. Text(text = "Email",
  196. style = TextStyle(
  197. colorResource(id = R.color.white))
  198. )
  199. },
  200. leadingIcon = {
  201. Icon(
  202. painter = painterResource(id = R.drawable.sms3x),
  203. contentDescription = "Email Logo",
  204. tint = colorResource(id = R.color.white),
  205. modifier = Modifier
  206. .size(24.dp, 24.dp)
  207. )
  208. },
  209. maxLines = 1,
  210. colors = TextFieldDefaults.colors(
  211. focusedLabelColor = Color.Blue,
  212. unfocusedContainerColor = colorResource(id = R.color.transparent),
  213. focusedContainerColor = colorResource(id = R.color.transparent),
  214. focusedIndicatorColor = colorResource(id = R.color.transparent),
  215. disabledIndicatorColor = colorResource(id = R.color.transparent),
  216. unfocusedIndicatorColor = colorResource(id = R.color.transparent),
  217. cursorColor = colorResource(id = R.color.white)
  218. ),
  219. keyboardOptions = KeyboardOptions(
  220. keyboardType = KeyboardType.Email,
  221. imeAction = ImeAction.Done
  222. ),
  223. keyboardActions = KeyboardActions(
  224. onDone = {
  225. focusManager.clearFocus()
  226. keyboardController?.hide()
  227. }
  228. ),
  229. )
  230. Spacer(modifier = Modifier.height(20.dp))
  231. TextField(
  232. value = passwordChanged,
  233. onValueChange = {
  234. Log.d("onClick_test", "onValueChange -> ")
  235. passwordChanged = it
  236. },
  237. readOnly = readOnly,
  238. textStyle = TextStyle(
  239. fontSize = 20.sp,
  240. color = colorResource(id = R.color.white),
  241. ),
  242. modifier = Modifier
  243. .padding(start = 15.dp, end = 15.dp)
  244. .align(Alignment.Start)
  245. .fillMaxWidth()
  246. .height(60.dp)
  247. .border(
  248. 1.dp,
  249. color = colorResource(id = R.color.grey_password_field),
  250. shape = RoundedCornerShape(16.dp)
  251. )
  252. .background(color = colorResource(id = R.color.transparent))
  253. .clickable() { },
  254. shape = RoundedCornerShape(15.dp),
  255. // placeholder = {
  256. // Text(text = "Enter password",
  257. // color = colorResource(id = R.color.white))
  258. // },
  259. label = {
  260. Text(text = "Password",
  261. style = TextStyle(
  262. colorResource(id = R.color.white))
  263. )
  264. },
  265. leadingIcon = {
  266. Icon(
  267. painter = painterResource(id = R.drawable.lock3x),
  268. contentDescription = "Password Logo",
  269. tint = colorResource(id = R.color.white),
  270. modifier = Modifier
  271. .size(24.dp, 24.dp)
  272. )
  273. },
  274. maxLines = 1,
  275. colors = TextFieldDefaults.colors(
  276. focusedLabelColor = Color.Blue,
  277. unfocusedContainerColor = colorResource(id = R.color.grey_password_field),
  278. focusedContainerColor = colorResource(id = R.color.grey_password_field),
  279. focusedIndicatorColor = colorResource(id = R.color.transparent),
  280. disabledIndicatorColor = colorResource(id = R.color.transparent),
  281. unfocusedIndicatorColor = colorResource(id = R.color.transparent),
  282. cursorColor = colorResource(id = R.color.white)
  283. ),
  284. keyboardOptions = KeyboardOptions(
  285. keyboardType = KeyboardType.Password,
  286. imeAction = ImeAction.Done
  287. ),
  288. keyboardActions = KeyboardActions(
  289. onDone = {
  290. focusManager.clearFocus()
  291. keyboardController?.hide()
  292. }
  293. ),
  294. visualTransformation =
  295. if (passwordVisible) VisualTransformation.Companion.None
  296. else PasswordVisualTransformation(),
  297. trailingIcon = {
  298. // val image
  299. // = if (passwordVisible) Icons.Filled.Visibility
  300. // else Icons.Filled.VisibilityOff
  301. val description = if (passwordVisible) "Hide Password"
  302. else "Show Password"
  303. IconButton(onClick = {
  304. if (!readOnly) {
  305. passwordVisible = !passwordVisible
  306. }
  307. })
  308. {
  309. if (passwordVisible) {
  310. Icon(
  311. imageVector = Icons.Outlined.Visibility,
  312. contentDescription = description,
  313. tint = colorResource(id = R.color.white),
  314. modifier = Modifier.size(24.dp)
  315. )
  316. }
  317. else {
  318. Icon(
  319. painter = painterResource(id = R.drawable.eye_slash3x),
  320. contentDescription = description,
  321. tint = colorResource(id = R.color.white),
  322. modifier = Modifier.size(24.dp)
  323. )
  324. }
  325. }
  326. }
  327. )
  328. Spacer(modifier = Modifier.height(15.dp))
  329. ClickableText(
  330. onClick = {
  331. if (!readOnly) {
  332. Log.d("onClick_test", "Forgot Password Clicked")
  333. navHostController.navigate(Screen.ForgotPassword.route)
  334. }
  335. },
  336. modifier = Modifier
  337. .padding(end = 15.dp)
  338. .align(Alignment.End),
  339. style = TextStyle(
  340. fontSize = 16.sp,
  341. fontWeight = FontWeight.Normal,
  342. color = colorResource(id = R.color.yellow_text),
  343. ),
  344. text = AnnotatedString("Forgot Password"),
  345. )
  346. }
  347. SignInButton(
  348. navHostController = navHostController,
  349. textChanged,
  350. passwordChanged,
  351. loginViewModel = loginViewModel,
  352. basePreferenceHelper
  353. )
  354. Row (
  355. modifier = Modifier
  356. .align(Alignment.BottomCenter)
  357. .padding(57.dp),
  358. ){
  359. TextMsgSignUp(navHostController = navHostController, loginViewModel, readOnly!!)
  360. // Text(
  361. // modifier = Modifier
  362. // .padding(0.dp),
  363. // fontSize = 14.sp,
  364. // fontWeight = FontWeight.Normal,
  365. // fontStyle = FontStyle.Normal,
  366. // text = "Don't have an account? ",
  367. // color = Color.White,
  368. // )
  369. // ClickableText(
  370. // onClick = {
  371. // navHostController.navigate(Screen.SignUp.route)
  372. // },
  373. // modifier = Modifier
  374. // .padding(0.dp),
  375. // style = TextStyle(
  376. // fontSize = 14.sp,
  377. // fontStyle = FontStyle.Normal,
  378. // color = colorResource(id = R.color.yellow_text),
  379. // ),
  380. // text = AnnotatedString(" Sign Up"),
  381. // )
  382. }
  383. }
  384. }
  385. @Composable
  386. fun RowScope.TextMsgSignUp(
  387. navHostController: NavHostController,
  388. loginViewModel: LoginViewModel,
  389. isEnabled: Boolean
  390. ) {
  391. Text(
  392. modifier = Modifier
  393. .padding(0.dp),
  394. fontSize = 14.sp,
  395. fontWeight = FontWeight.Normal,
  396. fontStyle = FontStyle.Normal,
  397. text = "Don't have an account? ",
  398. color = Color.White,
  399. )
  400. ClickableText(
  401. onClick = {
  402. if (isEnabled == false) {
  403. navHostController.navigate(Screen.SignUp.route)
  404. }
  405. },
  406. modifier = Modifier
  407. .padding(0.dp),
  408. style = TextStyle(
  409. fontSize = 14.sp,
  410. fontStyle = FontStyle.Normal,
  411. color = colorResource(id = R.color.yellow_text),
  412. ),
  413. text = AnnotatedString(" Sign Up"),
  414. )
  415. }
  416. @Composable
  417. fun BoxScope.SignInButton(
  418. navHostController: NavHostController,
  419. email: String,
  420. password: String,
  421. loginViewModel: LoginViewModel,
  422. prefHelper: BasePreferenceHelper
  423. ) {
  424. // var showLoader by remember { mutableStateOf(false) }
  425. if (loginViewModel.liveDataLoginStatus.value == true) {
  426. var progress by remember { mutableFloatStateOf(0.1F) }
  427. LaunchedEffect(key1 = Unit) {
  428. while (true) {
  429. for (i in 1..100) {
  430. progress = i.toFloat()/100F
  431. delay(150)
  432. }
  433. progress = 0.1F
  434. }
  435. }
  436. CircularProgressIndicator(
  437. progress = { progress },
  438. modifier = Modifier
  439. .align(Alignment.Center)
  440. .size(50.dp),
  441. color = colorResource(id = R.color.yellow_text),
  442. strokeWidth = 5.dp,
  443. )
  444. }
  445. Button(
  446. modifier = Modifier
  447. .padding(
  448. start = 15.dp, end = 15.dp,
  449. bottom = 109.dp
  450. )
  451. .align(Alignment.BottomCenter)
  452. .background(colorResource(id = R.color.transparent))
  453. .fillMaxWidth()
  454. .height(60.dp)
  455. .clickable() { },
  456. onClick = {
  457. Log.d("test_api_response live", "Login Clicked:")
  458. // showLoader = true
  459. if (loginViewModel.liveDataLoginStatus.value == false) {
  460. Log.d("test_api_response live", "SignIn: $email $password")
  461. loginViewModel.setLoginStatus(true)
  462. loginViewModel.loginRequest(
  463. email,
  464. password,
  465. "android",
  466. "11",
  467. "3.2.4"
  468. )
  469. }
  470. },
  471. shape = RoundedCornerShape(15.dp),
  472. // border = BorderStroke(25.dp, colorResource(id = R.color.black)),
  473. colors = ButtonDefaults.buttonColors(
  474. contentColor = colorResource(id = R.color.blue_text),
  475. containerColor = colorResource(id = R.color.white),
  476. ),
  477. )
  478. {
  479. Text(text = "Sign In",
  480. fontSize = 18.sp,
  481. fontWeight = FontWeight.Medium,
  482. fontStyle = FontStyle.Normal
  483. )
  484. val loginData by loginViewModel.liveDataUserResponse.observeAsState()
  485. loginData?.let { response ->
  486. Log.d("test_api_response live", "live: ${loginData?.status} ${loginData?.message}")
  487. loginViewModel.setLoginStatus(false)
  488. // showLoader = false
  489. if (response.status) {
  490. response.data?.let {
  491. prefHelper.setLoggedInState(true)
  492. prefHelper.savePassword(password)
  493. prefHelper.saveUser(it)
  494. it.wireguard?.let { wg ->
  495. prefHelper.saveWireGuard(wg)
  496. Log.d("test_wg_data", "Login:: ${wg.ip} ${wg.key}")
  497. }
  498. it.product?.let { it1 -> prefHelper.saveProduct(it1) }
  499. prefHelper.saveEnabledProtocols(it.enabled_protocols)
  500. prefHelper.saveAvailableProtocols(it.available_protocols)
  501. prefHelper.saveXPlatformToken(it.userinfo?.email + "_" + System.currentTimeMillis())
  502. prefHelper.saveAdBlockState(false)
  503. prefHelper.saveTheme(themesList[0])
  504. it.servers?.let {
  505. prefHelper.saveServerData(it)
  506. }
  507. Log.d("bearer_token", it.token.toString())
  508. // upgradePriceViewModel.getProducts()
  509. // prefHelper.getFcmToken().let {
  510. // loginViewModel.sendFcmToken(it)
  511. // Log.d("fcm token get", prefHelper.getFcmToken())
  512. // }
  513. prefHelper.saveRadioBtnSplitPos(0)
  514. navHostController.popBackStack()
  515. navHostController.navigate(Screen.BottomBarMainScreen.route)
  516. }
  517. }
  518. loginViewModel.mutableLiveDataUserResponse.value = null
  519. }
  520. }
  521. }
  522. @Composable
  523. fun ColumnScope.TextMsg(fontSize: TextUnit, text: String, color: Color) {
  524. Text(
  525. modifier = Modifier
  526. .padding(start = 15.dp)
  527. .align(Alignment.Start),
  528. fontSize = fontSize,
  529. fontWeight = FontWeight.Normal,
  530. text = text,
  531. color = color,
  532. )
  533. }
  534. @Preview
  535. @Composable
  536. fun LoginPreview() {
  537. Login(rememberNavController())
  538. }
  539. @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
  540. @Composable
  541. fun LoginPreviewDark() {
  542. Login(rememberNavController())
  543. }