SplitTunnelingItem.kt 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package com.vpn.fastestvpnservice.customItems
  2. import android.content.Context
  3. import android.content.pm.PackageManager
  4. import android.graphics.Bitmap
  5. import android.graphics.drawable.BitmapDrawable
  6. import android.graphics.drawable.Drawable
  7. import android.util.Log
  8. import android.widget.Toast
  9. import androidx.compose.foundation.Image
  10. import androidx.compose.foundation.background
  11. import androidx.compose.foundation.clickable
  12. import androidx.compose.foundation.interaction.MutableInteractionSource
  13. import androidx.compose.foundation.layout.Arrangement
  14. import androidx.compose.foundation.layout.Box
  15. import androidx.compose.foundation.layout.Row
  16. import androidx.compose.foundation.layout.Spacer
  17. import androidx.compose.foundation.layout.fillMaxWidth
  18. import androidx.compose.foundation.layout.height
  19. import androidx.compose.foundation.layout.padding
  20. import androidx.compose.foundation.layout.size
  21. import androidx.compose.foundation.layout.width
  22. import androidx.compose.foundation.layout.wrapContentHeight
  23. import androidx.compose.foundation.layout.wrapContentWidth
  24. import androidx.compose.foundation.shape.RoundedCornerShape
  25. import androidx.compose.material.Checkbox
  26. import androidx.compose.material.CheckboxDefaults
  27. import androidx.compose.material.Surface
  28. import androidx.compose.material.Text
  29. import androidx.compose.material3.Icon
  30. import androidx.compose.material3.MaterialTheme
  31. import androidx.compose.material3.rememberDrawerState
  32. import androidx.compose.runtime.Composable
  33. import androidx.compose.runtime.getValue
  34. import androidx.compose.runtime.mutableStateOf
  35. import androidx.compose.runtime.remember
  36. import androidx.compose.runtime.saveable.rememberSaveable
  37. import androidx.compose.runtime.setValue
  38. import androidx.compose.ui.Alignment
  39. import androidx.compose.ui.Modifier
  40. import androidx.compose.ui.draw.alpha
  41. import androidx.compose.ui.focus.onFocusChanged
  42. import androidx.compose.ui.graphics.Color
  43. import androidx.compose.ui.graphics.ImageBitmap
  44. import androidx.compose.ui.graphics.asImageBitmap
  45. import androidx.compose.ui.platform.LocalContext
  46. import androidx.compose.ui.res.colorResource
  47. import androidx.compose.ui.res.painterResource
  48. import androidx.compose.ui.text.TextStyle
  49. import androidx.compose.ui.tooling.preview.Preview
  50. import androidx.compose.ui.unit.dp
  51. import androidx.compose.ui.unit.sp
  52. import androidx.core.graphics.drawable.DrawableCompat
  53. import androidx.core.graphics.drawable.toBitmap
  54. import com.vpn.fastestvpnservice.R
  55. import com.vpn.fastestvpnservice.beans.SelectApplicationEntry
  56. import com.vpn.fastestvpnservice.beans.SplitTunnelData
  57. import androidx.compose.ui.graphics.painter.BitmapPainter
  58. import androidx.compose.ui.text.style.TextOverflow
  59. import com.google.accompanist.drawablepainter.rememberDrawablePainter
  60. import com.vpn.fastestvpnservice.constants.splitList
  61. import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
  62. @Composable
  63. fun SplitTunnelingItem(
  64. app: SelectApplicationEntry,
  65. list: List<SelectApplicationEntry>,
  66. position: Int
  67. ) {
  68. var isSelected by rememberSaveable { mutableStateOf(app.isSelected().value) }
  69. var isItemFocused by remember { mutableStateOf(false) }
  70. val color = if (isSelected) colorResource(id = R.color.split_background)
  71. else if (isItemFocused) colorResource(id = R.color.grayDark)
  72. else colorResource(id = R.color.background_color_gray)
  73. Surface(
  74. modifier = Modifier
  75. .fillMaxWidth()
  76. .background(
  77. color = colorResource(id = R.color.background_color_gray)
  78. )
  79. .padding(bottom = 1.dp)
  80. .onFocusChanged {
  81. isItemFocused = it.isFocused
  82. },
  83. color = color
  84. ) {
  85. val context = LocalContext.current
  86. Row(
  87. verticalAlignment = Alignment.CenterVertically,
  88. horizontalArrangement = Arrangement.Start,
  89. modifier = Modifier
  90. .fillMaxWidth()
  91. .padding(start = 12.dp, end = 7.dp, top = 15.dp, bottom = 15.dp)
  92. .clickable(
  93. indication = null,
  94. interactionSource = remember {
  95. MutableInteractionSource()
  96. },
  97. ) {
  98. isSelected = !isSelected
  99. // Log.d("test_splittunnel_data", "$app ${list.get(position).isSelected().value}")
  100. list.get(position).setSelected(mutableStateOf(!list.get(position).isSelected().value))
  101. countSelectedApp(list, context)
  102. }
  103. .background(Color.Transparent)
  104. ) {
  105. Image(
  106. painter = rememberDrawablePainter(drawable = app.getIcon()),
  107. contentDescription = "Server Logo",
  108. // tint = Color.Unspecified,
  109. modifier = Modifier
  110. .padding(bottom = 0.dp)
  111. .align(Alignment.CenterVertically)
  112. .size(40.dp)
  113. )
  114. Text(text = "$app",
  115. style = MaterialTheme.typography.bodySmall,
  116. color = colorResource(id = R.color.dark_blue_gray_text),
  117. maxLines = 2,
  118. overflow = TextOverflow.Ellipsis,
  119. modifier = Modifier
  120. .padding(start = 12.dp, bottom = 0.dp, end = 20.dp)
  121. .align(Alignment.CenterVertically)
  122. .background(Color.Transparent)
  123. .weight(1f)
  124. )
  125. // Spacer(modifier = Modifier.weight(1F))
  126. // Image(
  127. // painter = rememberDrawablePainter(drawable = app.getIcon()),
  128. // contentDescription = "Server Logo",
  129. //// tint = Color.Unspecified,
  130. // modifier = Modifier
  131. // .padding(bottom = 18.dp, end = 8.dp)
  132. // .align(Alignment.CenterVertically)
  133. // .size(40.dp)
  134. // )
  135. Checkbox(
  136. checked = isSelected,
  137. onCheckedChange = {
  138. isSelected = !isSelected
  139. list.get(position).setSelected(mutableStateOf(!list.get(position).isSelected().value))
  140. countSelectedApp(list, context)
  141. },
  142. colors = CheckboxDefaults.colors(
  143. uncheckedColor = colorResource(id = R.color.switch_gray),
  144. checkedColor = colorResource(id = R.color.blue_text),
  145. ),
  146. modifier = Modifier
  147. .padding(start = 0.dp, bottom = 0.dp, end = 8.dp)
  148. .align(Alignment.CenterVertically)
  149. .background(
  150. color = if (isSelected) colorResource(id = R.color.blue_text)
  151. else colorResource(id = R.color.switch_gray),
  152. shape = RoundedCornerShape(5.dp)
  153. )
  154. .size(24.dp)
  155. )
  156. }
  157. }
  158. }
  159. fun countSelectedApp(list: List<SelectApplicationEntry>, context: Context) {
  160. val prefHelper: BasePreferenceHelper = BasePreferenceHelper(context = context)
  161. list.let { it ->
  162. Log.d("test_split_data", it.size.toString())
  163. prefHelper.getSplitPosition().let { pos ->
  164. when (pos) {
  165. splitList[1] -> {
  166. val temp = it.filter {
  167. it.isSelected().value
  168. }
  169. if (temp.size == 0) {
  170. prefHelper.setSplitTunneledApps(null)
  171. } else {
  172. val stringList = ArrayList<String>()
  173. temp.forEach {
  174. Log.d("test_split_data","apps allow " + it.getInfo()?.packageName.toString())
  175. stringList.add(it.getInfo()?.packageName!!)
  176. }
  177. prefHelper.setSplitTunneledApps(stringList.toString())
  178. }
  179. }
  180. splitList[2] -> {
  181. val tempNoVpn = it.filter {
  182. it.isSelected().value
  183. }
  184. val tempNotAllow = it.filter {
  185. !it.isSelected().value
  186. }
  187. if (tempNoVpn.size == 0) {
  188. prefHelper.setSplitTunneledAppsNoVpn(null)
  189. } else {
  190. val stringListNoVpn = ArrayList<String>()
  191. Log.d("test_split_data", "apps no vpn $tempNoVpn")
  192. tempNoVpn.forEach {
  193. stringListNoVpn.add(it.getInfo()?.packageName!!)
  194. }
  195. prefHelper.setSplitTunneledAppsNoVpn(stringListNoVpn.toString())
  196. }
  197. if (tempNotAllow.size == 0) {
  198. prefHelper.setSplitTunneledAppsNotAllow(null)
  199. } else {
  200. val stringListNotAllow = ArrayList<String>()
  201. Log.d("test_split_data", "apps not allow $tempNotAllow")
  202. tempNotAllow.forEach {
  203. stringListNotAllow.add(it.getInfo()?.packageName!!)
  204. }
  205. prefHelper.setSplitTunneledAppsNotAllow(stringListNotAllow.toString())
  206. }
  207. }
  208. }
  209. }
  210. }
  211. }
  212. @Preview
  213. @Composable
  214. fun SplitTunnelingItemPreview() {
  215. }