Browse Source

Worked on favorite server screen on TV, Comment delete account, change password and email us screens on TV, changed some UI

Khubaib 10 tháng trước cách đây
mục cha
commit
d712011155

+ 2 - 2
.idea/deploymentTargetSelector.xml

@@ -4,10 +4,10 @@
     <selectionStates>
       <SelectionState runConfigName="app">
         <option name="selectionMode" value="DROPDOWN" />
-        <DropdownSelection timestamp="2024-07-18T15:20:53.451269375Z">
+        <DropdownSelection timestamp="2024-08-08T08:19:24.701447605Z">
           <Target type="DEFAULT_BOOT">
             <handle>
-              <DeviceId pluginId="Default" identifier="serial=192.168.108.28:5555;connection=909aac42" />
+              <DeviceId pluginId="LocalEmulator" identifier="path=/home/ubuntu/.android/avd/Television_1080p_API_31.avd" />
             </handle>
           </Target>
         </DropdownSelection>

+ 0 - 11
.idea/other.xml

@@ -183,17 +183,6 @@
           <option name="screenY" value="2400" />
         </PersistentDeviceSelectionData>
         <PersistentDeviceSelectionData>
-          <option name="api" value="31" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="q2q" />
-          <option name="id" value="q2q" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy Z Fold3" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1768" />
-          <option name="screenY" value="2208" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
           <option name="api" value="34" />
           <option name="brand" value="samsung" />
           <option name="codename" value="q5q" />

+ 169 - 2
app/src/main/java/com/vpn/fastestvpnservice/customItems/ServerItemTV.kt

@@ -114,7 +114,10 @@ fun ServerItemTV(
                     .size(150.dp)
                     .padding(start = 0.dp, end = 0.dp, top = 0.dp)
                     .border(
-                        border = BorderStroke(0.dp, if (isItemFocused) Color.LightGray else Color.White),
+                        border = BorderStroke(
+                            0.dp,
+                            if (isItemFocused) Color.LightGray else Color.White
+                        ),
                         shape = RoundedCornerShape(4.dp)
                     )
                     .background(
@@ -297,7 +300,7 @@ fun SearchServerItemTV(
                     )
             )
             Text(text = server.server_name!!,
-                color = MaterialTheme.colorScheme.primary,
+                color = colorResource(id = R.color.dark_blue_gray_text),
                 style = MaterialTheme.typography.labelMedium,
                 modifier = Modifier
                     .padding(start = 16.dp, bottom = 18.dp)
@@ -342,6 +345,170 @@ fun SearchServerItemTV(
     }
 }
 
+@Composable
+fun FavoriteServerItemTV(
+    server: Server,
+    navHostController: NavHostController,
+    serverPing: Int
+) {
+    val context = LocalContext.current
+    var isItemFocused by remember { mutableStateOf(false) }
+    val basePreferenceHelper = BasePreferenceHelper(context)
+//    val serverListViewModel: ServerListViewModel = viewModel {
+//        ServerListViewModel(context = context)
+//    }
+//    val splashViewModel: SplashViewModel = viewModel{
+//        SplashViewModel(context)
+//    }
+
+    val scope = rememberCoroutineScope()
+    val homeViewModel: HomeViewModel = viewModel {
+        HomeViewModel(context, scope)
+    }
+
+    var isFavorite by remember { mutableStateOf(server.isFavourited) }
+    val isServerFavourited: Boolean = server.isFavourited == true
+    Log.d("test-server_fav_d", "$isFavorite")
+
+    var isFavServerClicked by remember { mutableStateOf(false) }
+
+    if (isFavServerClicked) {
+        Log.d("ServerCallbacks", "isServerClicked $isFavServerClicked")
+//        onServer.onServerSelected(
+//            context,
+//            homeViewModel,
+//            onClick = { isFavServerClicked = false },
+//            true,
+//            server
+//        )
+
+        navHostController.popBackStack(BottomBarScreen.Home.route, false)
+    }
+
+    Box(
+        modifier = Modifier
+            .fillMaxWidth()
+            .background(if (isItemFocused) Color.LightGray else Color.Transparent)
+            .padding(bottom = 1.dp)
+    ) {
+        Row(
+            verticalAlignment = Alignment.Top,
+            horizontalArrangement = Arrangement.Start,
+            modifier = Modifier
+                .fillMaxWidth()
+                .padding(start = 12.dp, end = 7.dp, top = 12.dp)
+                .onFocusChanged {
+                    isItemFocused = it.isFocused
+                }
+                .focusable()
+                .clickable(
+                    indication = null,
+                    interactionSource = remember { MutableInteractionSource() }
+                ) {
+                    if (server.enable == 1) {
+                        isFavServerClicked = true
+                    } else {
+//                        basePreferenceHelper.setSubscriptionServerObject(server)
+//                        Screen.Subscription.isTrue = true
+//                        navHostController.navigate(
+//                            Screen.Subscription.route
+//                        )
+                    }
+                }
+        ) {
+//            var ping by rememberSaveable { mutableIntStateOf(0) }
+//            fun updatePing(newPing: Int) {
+//                ping = newPing
+//            }
+//            LaunchedEffect(key1 = Unit) {
+//                Ping.onAddress(server.ip as String).setTimeOutMillis(1000).doPing(
+//                    object : Ping.PingListener{
+//                        override fun onResult(pingResult: PingResult?) {
+//                            android.os.Handler(Looper.getMainLooper()).post {
+//                                pingResult?.let {
+//                                    if (ping == 0) updatePing(it.timeTaken.toInt())
+//                                }
+//                            }
+//                        }
+//
+//                        override fun onError(e: Exception?) {}
+//                        override fun onFinished(pingStats: PingStats?) {}
+//                    }
+//                )
+//            }
+            val icon = if (server.enable == 1) Utils.getDrawable(context, server.iso)
+            else Utils.getDrawableGray(context, server.iso)
+
+            Icon(
+                painter = painterResource(id = icon),
+                contentDescription = "Server Logo",
+                tint = Color.Unspecified,
+                modifier = Modifier
+                    .padding(bottom = 16.dp)
+                    .size(24.dp)
+                    .clip(CircleShape)
+                    .border(1.dp, colorResource(id = R.color.gray_opac_04), CircleShape)
+                    .paint(
+                        painter = painterResource(id = icon),
+                        contentScale = ContentScale.FillBounds
+                    )
+            )
+
+            Text(text = server.server_name!!,
+                color = colorResource(id = R.color.dark_blue_gray_text),
+                style = MaterialTheme.typography.labelMedium,
+                modifier = Modifier
+                    .padding(start = 16.dp, bottom = 18.dp)
+                    .align(Alignment.CenterVertically)
+            )
+            Spacer(modifier = Modifier.weight(1F))
+            Text(text = "$serverPing ms",
+                color = colorResource(id = R.color.blue_text),
+                style = MaterialTheme.typography.displayMedium,
+                modifier = Modifier
+                    .padding(end = 30.dp, bottom = 18.dp)
+                    .align(Alignment.CenterVertically)
+            )
+//            Spacer(modifier = Modifier.weight(1F))
+
+            IconButton(
+                onClick = {
+                    isFavorite = !isFavorite!!
+                    serverListViewModelSplash.favAndUnFav(server)
+                },
+                modifier = Modifier
+                    .padding(bottom = 18.dp, end = 0.dp)
+                    .size(25.dp)
+//                    .clickable(
+//                        indication = null,
+//                        interactionSource = remember { MutableInteractionSource() }
+//                    ) {  },
+            ) {
+                Icon(
+                    painter = if (isServerFavourited) painterResource(
+                        id = R.drawable.fav_server3x) else painterResource(
+                        id = R.drawable.unfav_server3x),
+                    contentDescription = "Server Logo",
+                    tint = Color.Unspecified,
+                    modifier = Modifier.size(22.dp, 21.dp)
+                )
+            }
+
+        }
+
+        Surface(
+            modifier = Modifier
+                .padding(start = 0.dp, end = 0.dp)
+                .height(1.dp)
+                .fillMaxWidth()
+                .alpha(0.6F)
+                .align(Alignment.BottomCenter)
+            ,
+            color = colorResource(id = R.color.gray_icon)
+        ) {}
+    }
+}
+
 @Preview
 @Composable
 fun ServerListTVPreview() {

+ 9 - 0
app/src/main/java/com/vpn/fastestvpnservice/navigation/BottomBarNavGraphTV.kt

@@ -12,6 +12,7 @@ import androidx.navigation.NavBackStackEntry
 import androidx.navigation.NavHostController
 import androidx.navigation.compose.NavHost
 import androidx.navigation.compose.composable
+import com.vpn.fastestvpnservice.customItems.FavoriteServerItemTV
 import com.vpn.fastestvpnservice.screensTV.AccountTV
 import com.vpn.fastestvpnservice.screensTV.HelpTV
 import com.vpn.fastestvpnservice.screensTV.HomeTV
@@ -19,7 +20,9 @@ import com.vpn.fastestvpnservice.screensTV.NotificationsTV
 import com.vpn.fastestvpnservice.screensTV.ServerListTV
 import com.vpn.fastestvpnservice.screensTV.SettingsTV
 import com.vpn.fastestvpnservice.screensTV.SplitTunnelingTV
+import com.vpn.fastestvpnservice.screensTV.accountScreensAll.FavoriteServersTV
 import com.vpn.fastestvpnservice.screensTV.helpScreensAll.AboutTV
+import com.vpn.fastestvpnservice.screensTV.helpScreensAll.EmailUsScreenTV
 import com.vpn.fastestvpnservice.screensTV.helpScreensAll.FaqTV
 import com.vpn.fastestvpnservice.screensTV.helpScreensAll.PrivacyPolicyTV
 import com.vpn.fastestvpnservice.screensTV.helpScreensAll.TermsAndConditionsTV
@@ -88,6 +91,12 @@ fun BottomBarNavGraphTV(navHostController: NavHostController,
         composable(route = ScreenTV.AnySpecificScreenTV.route) {
             AnySpecificScreenTV(navHostController = navHostController)
         }
+        composable(route = ScreenTV.EmailUs.route) {
+            EmailUsScreenTV(navHostController = navHostController)
+        }
+        composable(route = ScreenTV.FavoriteTV.route) {
+            FavoriteServersTV(navHostController = navHostController,)
+        }
 
         /* Again declare for login because of different -> navHostController */
 //        composable(route = Screen.Login.route) {

+ 18 - 18
app/src/main/java/com/vpn/fastestvpnservice/screensTV/AccountScreenTV.kt

@@ -184,28 +184,28 @@ fun AccountTV(navHostController: NavHostController,
                     text = "Favorite Servers",
                     onClick = {
                         navHostController.navigate(
-                            Screen.FavoriteServers.route
+                            ScreenTV.FavoriteTV.route
                         )
                     },
                     focusRequester1
                 )
-                AddRowAccountIconTV(
-                    icon = painterResource(id = R.drawable.lock3x),
-                    text = "Change Password",
-                    onClick = {
-                        navHostController.navigate(
-                            Screen.ChangePassword.route
-                        )
-                    }
-                )
-                AddRowAccountIconTV(
-                    icon = painterResource(id = R.drawable.delete3x),
-                    text = "Delete Account",
-                    onClick = {
-                        isDelete = true
-                        Log.d("islogoutClicked?", "isDelete Yes")
-                    }
-                )
+//                AddRowAccountIconTV(
+//                    icon = painterResource(id = R.drawable.lock3x),
+//                    text = "Change Password",
+//                    onClick = {
+//                        navHostController.navigate(
+//                            Screen.ChangePassword.route
+//                        )
+//                    }
+//                )
+//                AddRowAccountIconTV(
+//                    icon = painterResource(id = R.drawable.delete3x),
+//                    text = "Delete Account",
+//                    onClick = {
+//                        isDelete = true
+//                        Log.d("islogoutClicked?", "isDelete Yes")
+//                    }
+//                )
                 AddRowAccountIconTV(
                     icon = painterResource(id = R.drawable.logout3x),
                     text = "Logout",

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

@@ -178,17 +178,17 @@ fun HelpTV(navHostController: NavHostController) {
 //                    },
 //                    isIconTV = false
 //                )
-                AddRowTV(
-                    icon = R.drawable.customer_support3x,
-                    text = "Email Us",
-                    navHostController = navHostController,
-                    onClick = {
-                        navHostController.navigate(
-                            Screen.EmailUs.route
-                        )
-                    },
-                    isLastRow = true
-                )
+//                AddRowTV(
+//                    icon = R.drawable.customer_support3x,
+//                    text = "Email Us",
+//                    navHostController = navHostController,
+//                    onClick = {
+//                        navHostController.navigate(
+//                            ScreenTV.EmailUs.route
+//                        )
+//                    },
+//                    isLastRow = true
+//                )
             }
         }
     }

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

@@ -98,7 +98,7 @@ fun BoxScope.HeaderRowNSTV(navHostController: NavHostController) {
         color = colorResource(id = R.color.transparent)
     ) {
         Text(text = "Notifications",
-            color = MaterialTheme.colorScheme.primary,
+            color = colorResource(id = R.color.dark_blue_gray_text),
             style = MaterialTheme.typography.bodyMedium,
             modifier = Modifier.fillMaxHeight()
 

+ 7 - 6
app/src/main/java/com/vpn/fastestvpnservice/screensTV/SettingsScreenTV.kt

@@ -932,13 +932,14 @@ fun ColumnScope.AddRowSettingsSmartTV(
                                         basePreferenceHelper.saveSmartList(smart)
                                         isSmartSheetOpen = false
 
-                                        navHostController.navigate(
-                                            ScreenTV.AnySpecificScreenTV.route
-                                        )
-//                                        if (smart == smartConnect[2]) {
-//                                            Log.d("smartLocationList Row", smart)
+
+                                        if (smart == smartConnect[2]) {
+                                            Log.d("smartLocationList Row", smart)
 //                                            isAnySpecificSheetOpen = true
-//                                        }
+                                            navHostController.navigate(
+                                                ScreenTV.AnySpecificScreenTV.route
+                                            )
+                                        }
                                     },
                                 )
 //                                    .indication(

+ 145 - 0
app/src/main/java/com/vpn/fastestvpnservice/screensTV/accountScreensAll/FavoriteScreenTV.kt

@@ -0,0 +1,145 @@
+package com.vpn.fastestvpnservice.screensTV.accountScreensAll
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.LocalOverscrollConfiguration
+import androidx.compose.foundation.background
+import androidx.compose.foundation.focusable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+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.focus.focusRequester
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import androidx.navigation.NavHostController
+import com.vpn.fastestvpnservice.R
+import com.vpn.fastestvpnservice.customItems.FavoriteServerItemTV
+import com.vpn.fastestvpnservice.screens.serverListViewModelSplash
+
+@OptIn(ExperimentalFoundationApi::class)
+@Composable
+fun FavoriteServersTV(navHostController: NavHostController) {
+//    val context = LocalContext.current
+//    val basePreferenceHelper = BasePreferenceHelper(context)
+//    val serverListViewModel: ServerListViewModel = viewModel{
+//        ServerListViewModel(context)
+//    }
+
+    Box(
+        modifier = Modifier
+            .fillMaxSize()
+            .background(colorResource(id = R.color.background_color_gray))
+    )
+    {
+        HeaderRowFSTV(navHostController = navHostController)
+
+        Column(
+            verticalArrangement = Arrangement.Top,
+            horizontalAlignment = Alignment.Start,
+            modifier = Modifier
+                .padding(
+                    top = 60.dp,
+                    start = 16.dp, end = 16.dp
+                )
+                .fillMaxSize()
+                .background(Color.Transparent)
+        ) {
+            val favoriteServers = serverListViewModelSplash.liveDataGetFavList.observeAsState().value
+            var ping by rememberSaveable { mutableIntStateOf(0) }
+
+            CompositionLocalProvider(
+                LocalOverscrollConfiguration provides null
+            ) {
+                LazyColumn {
+//                    val favoriteServers = basePreferenceHelper.getServerData().get(0)
+//                    val filterFavoriteServers = favoriteServers.servers?.let {
+//                        serverListViewModel.filterServersByISO(
+//                            it
+//                        )
+//                    }
+
+
+//                    favoriteServers?.forEachIndexed { index, server ->
+//                        Log.d("filterFavoriteServers", "${server.country} ${server.server_name}")
+//                    }
+
+                    favoriteServers?.let {
+                        items(items = favoriteServers) {server ->
+//                            calPing(server) {
+//                                server.ping = it
+////                                if (server.ping != 0) ping = it
+//                            }
+                            FavoriteServerItemTV(server = server, navHostController, server.ping)
+                        }
+                    }
+
+                }
+            }
+        }
+    }
+}
+
+@Composable
+fun BoxScope.HeaderRowFSTV(
+    navHostController: NavHostController) {
+//    IconButton(
+//        onClick = {
+//            navHostController.popBackStack()
+//
+////            navHostController.popBackStack(BottomBarScreen.Home.route, false)
+////            navHostController.navigate(BottomBarScreen.Home.route)
+//        },
+//        modifier = Modifier
+//            .align(Alignment.TopStart)
+//            .padding(top = 50.dp)
+//            .padding(start = 16.dp)
+//            .size(30.dp, 32.dp)
+//    ) {
+//        Icon(
+//            painter = painterResource(id = R.drawable.backarrow3x),
+//            contentDescription = "Arrow-Back",
+//            tint = colorResource(id = R.color.dark_blue_gray_text),
+//            modifier = Modifier.size(18.dp, 12.dp)
+//        )
+//    }
+    Surface(
+        modifier = Modifier
+            .padding(start = 14.dp, top = 16.dp)
+            .height(32.dp)
+            .align(Alignment.TopStart)
+            .padding(5.dp),
+        color = colorResource(id = R.color.transparent)
+    ) {
+        Text(text = "Favorite Servers",
+            color = colorResource(id = R.color.dark_blue_gray_text),
+            style = MaterialTheme.typography.bodyMedium,
+            modifier = Modifier.fillMaxHeight()
+
+        )
+    }
+}

+ 264 - 0
app/src/main/java/com/vpn/fastestvpnservice/screensTV/helpScreensAll/EmailUsScreenTV.kt

@@ -0,0 +1,264 @@
+package com.vpn.fastestvpnservice.screensTV.helpScreensAll
+
+import android.util.Log
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.text.KeyboardActions
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SnackbarHostState
+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.mutableFloatStateOf
+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.graphics.Color
+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.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import com.vpn.fastestvpnservice.R
+import com.vpn.fastestvpnservice.ui.theme.customTypography
+import com.vpn.fastestvpnservice.viewmodels.HelpViewModel
+import com.vpn.fastestvpnservice.views.CustomValidation
+import com.vpn.fastestvpnservice.views.ShowCustomSnackBar
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+@Composable
+fun EmailUsScreenTV(navHostController: NavHostController) {
+    var textChanged by remember { mutableStateOf("") }
+    val keyboardController = LocalSoftwareKeyboardController.current
+    val focusManager = LocalFocusManager.current
+    val snackBarState = remember { SnackbarHostState() }
+    val snackBarStateRed = remember { SnackbarHostState() }
+    var isShowLoader by remember { mutableStateOf(false) }
+
+    Box(
+        modifier = Modifier
+            .background(colorResource(id = R.color.background_color_gray))
+            .fillMaxSize()
+    ) {
+        ShowCustomSnackBar(snackBarState, R.color.switch_green, R.color.white)
+        ShowCustomSnackBar(snackBarStateRed, R.color.Red, R.color.white)
+
+        if (isShowLoader) {
+            var progress by remember { mutableFloatStateOf(0.1F) }
+
+            LaunchedEffect(key1 = Unit) {
+                while (true) {
+                    for (i in 1..100) {
+                        progress = i.toFloat()/100F
+                        delay(150)
+                    }
+                    progress = 0.1F
+                }
+            }
+
+            CircularProgressIndicator(
+                progress = { progress },
+                modifier = Modifier
+                    .size(50.dp)
+                    .align(Alignment.Center),
+                color = colorResource(id = R.color.yellow_text),
+                strokeWidth = 5.dp,
+            )
+        }
+
+        Column(
+            modifier = Modifier
+                .fillMaxSize()
+                .background(Color.Transparent),
+            verticalArrangement = Arrangement.Top,
+            horizontalAlignment = Alignment.Start
+        ) {
+            Spacer(modifier = Modifier.height(50.dp))
+
+            ShowHeaderEUTV(
+                navHostController = navHostController,
+                textChanged,
+                snackBarState,
+                snackBarStateRed,
+                isShowLoader = {
+                    isShowLoader = it
+                }
+            ) {
+                textChanged = it
+            }
+
+            Text(text = "Your message:",
+                color = colorResource(id = R.color.dark_blue_gray_text),
+                style = MaterialTheme.typography.bodyMedium,
+                modifier = Modifier
+                    .padding(start = 20.dp, top = 25.dp)
+                    .align(Alignment.Start)
+            )
+
+            TextField(
+                value = textChanged,
+                onValueChange = {
+                    textChanged = it
+                },
+
+                textStyle = MaterialTheme.typography.customTypography.bodyMedium.copy(
+                    MaterialTheme.colorScheme.primary
+                ),
+                modifier = Modifier
+                    .padding(top = 2.dp, start = 5.dp, end = 5.dp, bottom = 10.dp)
+                    .fillMaxWidth()
+                    .align(Alignment.Start)
+                    .fillMaxHeight()
+//                    .border(
+//                        1.dp,
+//                        color = colorResource(id = R.color.Black),
+//                    ),
+                ,
+                colors = TextFieldDefaults.colors(
+                    focusedLabelColor = Color.Blue,
+                    unfocusedContainerColor = colorResource(id = R.color.transparent),
+                    focusedContainerColor = colorResource(id = R.color.transparent),
+                    focusedIndicatorColor = colorResource(id = R.color.transparent),
+                    disabledIndicatorColor = colorResource(id = R.color.transparent),
+                    unfocusedIndicatorColor = colorResource(id = R.color.transparent),
+                    cursorColor = MaterialTheme.colorScheme.primary
+                ),
+                keyboardOptions = KeyboardOptions(
+                    keyboardType = KeyboardType.Email,
+                    imeAction = ImeAction.Done
+                ),
+                keyboardActions = KeyboardActions(
+                    onDone = {
+                        focusManager.clearFocus()
+                        keyboardController?.hide()
+                    }
+                ),
+            )
+        }
+    }
+}
+
+@Composable
+fun ColumnScope.ShowHeaderEUTV(
+    navHostController: NavHostController,
+    message: String,
+    snackBarState: SnackbarHostState,
+    snackBarStateRed: SnackbarHostState,
+    isShowLoader: (Boolean) -> Unit,
+    textChanged: (String) -> Unit,
+) {
+    Log.d("emailUs: ","EU :: message = $message")
+    val helpViewModel: HelpViewModel = viewModel()
+    val coroutineScope = rememberCoroutineScope()
+
+    Row(
+        modifier = Modifier.fillMaxWidth(),
+        horizontalArrangement = Arrangement.SpaceBetween
+    ) {
+        IconButton(
+            onClick = {
+                navHostController.popBackStack()
+                navHostController.popBackStack()
+//                    navHostController.navigate(BottomBarScreen.Help.route)
+            },
+            modifier = Modifier
+                .padding(top = 10.dp)
+                .padding(start = 16.dp)
+                .size(30.dp, 32.dp)
+        ) {
+            Icon(
+                painter = painterResource(id = R.drawable.backarrow3x),
+                contentDescription = "Arrow-Back",
+                tint = colorResource(id = R.color.dark_blue_gray_text),
+                modifier = Modifier.size(18.dp, 12.dp)
+            )
+        }
+        Surface(
+            modifier = Modifier
+                .padding(top = 10.dp)
+                .height(32.dp)
+                .padding(5.dp),
+            color = colorResource(id = R.color.transparent)
+        ) {
+            Text(text = "Email Us",
+                color = colorResource(id = R.color.dark_blue_gray_text),
+                style = MaterialTheme.typography.bodyMedium,
+                modifier = Modifier.fillMaxHeight()
+            )
+        }
+        val customValidation = CustomValidation()
+        val isMessageValid = customValidation.isValidText(message, "Message")
+
+        IconButton(
+            onClick = {
+                if (isMessageValid) {
+                    isShowLoader(true)
+                    helpViewModel.emailUs(message)
+                } else {
+                    coroutineScope.launch {
+                        snackBarStateRed.showSnackbar("The message field is required.")
+                    }
+                }
+            },
+            modifier = Modifier
+                .padding(top = 10.dp)
+                .padding(end = 16.dp)
+                .size(30.dp, 32.dp)
+        ) {
+            Icon(
+                painter = painterResource(id = R.drawable.customer_support3x),
+                contentDescription = "Email-Us",
+                tint = colorResource(id = R.color.dark_blue_gray_text),
+                modifier = Modifier.size(24.dp)
+            )
+
+            val emailUsResponse = helpViewModel.liveDataEmailUs.observeAsState()
+            emailUsResponse.value?.let { data ->
+                Log.d("emailUs: ","emailUs Screen: ${data.status} ${data.message}")
+                isShowLoader(false)
+                if (data.status) {
+                    coroutineScope.launch {
+                        data.message?.let { snackBarState.showSnackbar(it) }
+                        navHostController.popBackStack()
+                        navHostController.popBackStack()
+                    }
+//                    textChanged("")
+
+                } else {
+                    coroutineScope.launch {
+                        data.message?.let { snackBarStateRed.showSnackbar(it) }
+                    }
+                }
+                helpViewModel.mutableLiveDataEmailUs.value = null
+            }
+        }
+    }
+}

+ 2 - 0
app/src/main/java/com/vpn/fastestvpnservice/sealedClass/ScreenTV.kt

@@ -13,4 +13,6 @@ sealed class ScreenTV(val route: String) {
     data object TermsAndConditionsTV : ScreenTV("terms_and_conditions_tv")
     data object AboutTV : ScreenTV("about_tv")
     data object AnySpecificScreenTV : ScreenTV("any_specific_screen_tv")
+    data object EmailUs : ScreenTV("email_us")
+    data object FavoriteTV : ScreenTV("favorite_tv")
 }