Bläddra i källkod

Implemented searching on any specific screen on TV, design UI etc

Khubaib 9 månader sedan
förälder
incheckning
83034b109f

+ 2 - 2
.idea/deploymentTargetSelector.xml

@@ -4,10 +4,10 @@
     <selectionStates>
       <SelectionState runConfigName="app">
         <option name="selectionMode" value="DROPDOWN" />
-        <DropdownSelection timestamp="2024-08-08T13:38:22.898215760Z">
+        <DropdownSelection timestamp="2024-08-08T15:11:14.519629907Z">
           <Target type="DEFAULT_BOOT">
             <handle>
-              <DeviceId pluginId="LocalEmulator" identifier="path=/home/ubuntu/.android/avd/Television_1080p_API_31.avd" />
+              <DeviceId pluginId="Default" identifier="serial=192.168.109.7:5555;connection=544c5340" />
             </handle>
           </Target>
         </DropdownSelection>

+ 3 - 3
app/src/main/java/com/vpn/fastestvpnservice/constants/AppConstant.kt

@@ -10,9 +10,9 @@ class AppConstant {
 //        const val FAQ_WEBVIEW_URL = "https://fastestvpn.com/faq?device=ios"
         const val FAQ_WEBVIEW_URL = "https://fastestvpn.com/faq?device=tv"
         const val CHANGE_PASSWORD_URL = "https://fastestvpn.com/password/reset"
-        const val POLICY_WEBVIEW_URL = "https://fastestvpn.com/privacy-policy?device=ios"
-        const val TERMS_WEBVIEW_URL = "https://fastestvpn.com/terms-of-service?device=ios"
-        const val ABOUT_WEBVIEW_URL = "https://fastestvpn.com/about?device=ios"
+        const val POLICY_WEBVIEW_URL = "https://fastestvpn.com/privacy-policy?device=tv"
+        const val TERMS_WEBVIEW_URL = "https://fastestvpn.com/terms-of-service?device=tv"
+        const val ABOUT_WEBVIEW_URL = "https://fastestvpn.com/about?device=tv"
         const val CHAT_WEBVIEW_URL = "https://api.fastestvpn.com/v2/chat?device=ios&email="
 
         //Api Base Url

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

@@ -166,6 +166,7 @@ fun HelpTV(navHostController: NavHostController) {
                             ScreenTV.AboutTV.route
                         )
                     },
+                    isLastRow = true
                 )
 //                AddRowTV(
 //                    icon = R.drawable.faq3x,

+ 151 - 13
app/src/main/java/com/vpn/fastestvpnservice/screensTV/settingsScreenAll/AnySpecificScreenTV.kt

@@ -3,10 +3,12 @@ package com.vpn.fastestvpnservice.screensTV.settingsScreenAll
 import android.util.Log
 import android.widget.Toast
 import androidx.compose.foundation.background
+import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
@@ -14,8 +16,12 @@ import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.lazy.itemsIndexed
 import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.KeyboardActions
+import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.DockedSearchBar
 import androidx.compose.material3.ExperimentalMaterial3Api
@@ -23,28 +29,40 @@ import androidx.compose.material3.Icon
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.SearchBarDefaults
 import androidx.compose.material3.Text
+import androidx.compose.material3.TextField
 import androidx.compose.material3.TextFieldDefaults
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.livedata.observeAsState
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.platform.LocalSoftwareKeyboardController
 import androidx.compose.ui.res.colorResource
 import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.input.ImeAction
+import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
 import androidx.navigation.NavHostController
 import com.vpn.fastestvpnservice.R
 import com.vpn.fastestvpnservice.customItems.SearchServerItemTV
 import com.vpn.fastestvpnservice.customItems.ServerItemTV
+import com.vpn.fastestvpnservice.customItems.ServerSearchItem
 import com.vpn.fastestvpnservice.screens.searchListViewModelSplash
 import com.vpn.fastestvpnservice.screens.serverListViewModelSplash
 import com.vpn.fastestvpnservice.screensTV.HeaderRowSL
 import com.vpn.fastestvpnservice.screensTV.locations
+import com.vpn.fastestvpnservice.ui.theme.customTypography
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 
 @OptIn(ExperimentalMaterial3Api::class)
@@ -55,6 +73,9 @@ fun AnySpecificScreenTV(navHostController: NavHostController) {
     var searchText1 by remember { mutableStateOf("Test") }
     val isActive = searchListViewModel.isActive.observeAsState().value
     val scope = rememberCoroutineScope()
+    var textChanged by remember { mutableStateOf("") }
+    val keyboardController = LocalSoftwareKeyboardController.current
+    val focusManager = LocalFocusManager.current
 
     Box(
         modifier = Modifier
@@ -119,25 +140,142 @@ fun AnySpecificScreenTV(navHostController: NavHostController) {
 //                .background(Color.Black)
 //        ) {}
 
-        val listAll = serverListViewModelSplash.liveDataAllServers.observeAsState().value
-        Column(
+        TextField(
+            value = textChanged,
+            onValueChange = {
+                textChanged = it
+            },
+            textStyle = MaterialTheme.typography.customTypography.bodyMedium.copy(
+                color = colorResource(id = R.color.dark_blue_gray_text)
+            ),
             modifier = Modifier
-                .fillMaxSize()
-                .padding(top = 80.dp, start = 24.dp, end = 24.dp, bottom = 24.dp)
-//                .verticalScroll(rememberScrollState())
-                .background(Color.Transparent)
-        ) {
-            LazyColumn(
+                .padding(top = 60.dp, end = 0.dp)
+                .padding(horizontal = 0.dp)
+                .fillMaxWidth(fraction = 0.5f)
+                .align(Alignment.TopCenter)
+                .height(50.dp)
+                .border(
+                    1.dp,
+                    colorResource(id = R.color.white),
+                    shape = RoundedCornerShape(24.dp)
+                )
+                .background(color = colorResource(id = R.color.transparent)),
+//                .focusRequester(focusRequester1)
+//                            .onFocusChanged {
+////                                isTextFieldFocused = it.isFocused
+//                                focusRequester2.requestFocus()
+//                            }
+//                            .focusable()
+            shape = RoundedCornerShape(24.dp),
+            placeholder = {
+                Text(
+                    text = "Search Location",
+                    style = MaterialTheme.typography.customTypography.titleSmall.copy(
+                        color = colorResource(id = R.color.dark_blue_gray_text),
+                        fontSize = 14.sp
+                    )
+                )
+            },
+//            label = {
+//                Text(
+//                    text = "Search Location",
+//                    style = MaterialTheme.typography.customTypography.bodyLarge.copy(
+//                        color = colorResource(id = R.color.dark_blue_gray_text),
+//                        fontSize = 14.sp
+//                    )
+//                )
+//            },
+            leadingIcon = {
+                Icon(
+                    painter = painterResource(id = R.drawable.search3x),
+                    contentDescription = "Email Logo",
+                    tint = colorResource(id = R.color.dark_blue_gray_text),
+                    modifier = Modifier
+                        .size(20.dp, 20.dp)
+                )
+            },
+            maxLines = 1,
+            colors = TextFieldDefaults.colors(
+                focusedLabelColor = colorResource(id = R.color.dark_blue_gray_text),
+                unfocusedTextColor = colorResource(id = R.color.dark_blue_gray_text),
+                focusedTextColor = colorResource(id = R.color.dark_blue_gray_text),
+                disabledTextColor = colorResource(id = R.color.dark_blue_gray_text),
+                unfocusedContainerColor = colorResource(id = R.color.white),
+                focusedContainerColor = colorResource(id = R.color.white),
+                focusedIndicatorColor = colorResource(id = R.color.transparent),
+                disabledIndicatorColor = colorResource(id = R.color.transparent),
+                unfocusedIndicatorColor = colorResource(id = R.color.transparent),
+                cursorColor = colorResource(id = R.color.dark_blue_gray_text),
+                ),
+            keyboardOptions = KeyboardOptions(
+                keyboardType = KeyboardType.Email,
+                imeAction = ImeAction.Done
+            ),
+            keyboardActions = KeyboardActions(
+                onDone = {
+                    focusManager.clearFocus()
+                    keyboardController?.hide()
+                }
+            ),
+        )
+
+        if (textChanged == "") {
+            val listAll = serverListViewModelSplash.liveDataAllServers.observeAsState().value
+            Column(
                 modifier = Modifier
-                    .padding(top = 10.dp, start = 0.dp, end = 0.dp)
+                    .fillMaxSize()
+                    .padding(top = 130.dp, start = 24.dp, end = 24.dp, bottom = 24.dp)
+//                .verticalScroll(rememberScrollState())
                     .background(Color.Transparent)
             ) {
-                listAll?.let {
-                    itemsIndexed(items = listAll, itemContent = { index, server ->
-                        SearchServerItemTV(server = server, navHostController = navHostController, serverPing = server.ping)
-                    })
+                LazyColumn(
+                    modifier = Modifier
+                        .padding(top = 10.dp, start = 0.dp, end = 0.dp)
+                        .background(Color.Transparent)
+                ) {
+                    listAll?.let {
+                        itemsIndexed(items = listAll, itemContent = { index, server ->
+                            SearchServerItemTV(server = server, navHostController = navHostController, serverPing = server.ping)
+                        })
+                    }
                 }
             }
+        } else {
+            LaunchedEffect(key1 = textChanged) {
+                Log.d("test_search_logic", "LaunchedEffect $textChanged")
+                val delay = if (textChanged.isEmpty()) 0L else 300L
+                delay(delay)
+                searchListViewModel.getCountries(textChanged, true)
+            }
+
+            val searchServersList = searchListViewModel.countriesList.observeAsState().value
+            searchServersList?.forEachIndexed { index, server ->
+                Log.d("test_search", "SLS_ ${server.server_name} ${server.ping}")
+            }
+            if (searchServersList != null) {
+                val fraction = if (searchServersList.size > 0) 1f else if (textChanged.isNotEmpty()) 1f else 0f
+                Column(
+                    modifier = Modifier
+                        .fillMaxSize()
+                        .padding(top = 130.dp, start = 24.dp, end = 24.dp, bottom = 24.dp)
+//                .verticalScroll(rememberScrollState())
+                        .background(Color.Transparent)
+                ) {
+                    LazyColumn(
+                        modifier = Modifier
+                            .fillMaxWidth()
+                            .fillMaxHeight(fraction = fraction)
+                            .padding(top = 10.dp, bottom = 0.dp),
+                    ) {
+                        searchServersList.let {
+                            items(items = it) { server ->
+                                SearchServerItemTV(server, navHostController = navHostController, serverPing = server.ping)
+                            }
+                        }
+                    }
+                }
+            }
+
         }
     }
 }