瀏覽代碼

Added string resources for diffrent locales, Created a bottom sheet modal for languages and translation is working on android 13+ and also below these versions

Khubaib 8 月之前
父節點
當前提交
de22a89147

+ 2 - 2
.idea/deploymentTargetSelector.xml

@@ -4,10 +4,10 @@
     <selectionStates>
       <SelectionState runConfigName="app">
         <option name="selectionMode" value="DROPDOWN" />
-        <DropdownSelection timestamp="2024-08-22T14:55:11.504615460Z">
+        <DropdownSelection timestamp="2024-08-26T15:18:56.962088920Z">
           <Target type="DEFAULT_BOOT">
             <handle>
-              <DeviceId pluginId="LocalEmulator" identifier="path=/home/ubuntu/.android/avd/Television_1080p_API_31.avd" />
+              <DeviceId pluginId="LocalEmulator" identifier="path=/home/ubuntu/.android/avd/Small_Phone_API_27.avd" />
             </handle>
           </Target>
         </DropdownSelection>

+ 44 - 0
.idea/other.xml

@@ -73,6 +73,28 @@
           <option name="screenY" value="2400" />
         </PersistentDeviceSelectionData>
         <PersistentDeviceSelectionData>
+          <option name="api" value="34" />
+          <option name="brand" value="google" />
+          <option name="codename" value="caiman" />
+          <option name="id" value="caiman" />
+          <option name="manufacturer" value="Google" />
+          <option name="name" value="Pixel 9 Pro" />
+          <option name="screenDensity" value="360" />
+          <option name="screenX" value="960" />
+          <option name="screenY" value="2142" />
+        </PersistentDeviceSelectionData>
+        <PersistentDeviceSelectionData>
+          <option name="api" value="34" />
+          <option name="brand" value="google" />
+          <option name="codename" value="comet" />
+          <option name="id" value="comet" />
+          <option name="manufacturer" value="Google" />
+          <option name="name" value="Pixel 9 Pro Fold" />
+          <option name="screenDensity" value="390" />
+          <option name="screenX" value="2076" />
+          <option name="screenY" value="2152" />
+        </PersistentDeviceSelectionData>
+        <PersistentDeviceSelectionData>
           <option name="api" value="29" />
           <option name="brand" value="samsung" />
           <option name="codename" value="crownqlteue" />
@@ -150,6 +172,17 @@
           <option name="screenY" value="1600" />
         </PersistentDeviceSelectionData>
         <PersistentDeviceSelectionData>
+          <option name="api" value="34" />
+          <option name="brand" value="google" />
+          <option name="codename" value="komodo" />
+          <option name="id" value="komodo" />
+          <option name="manufacturer" value="Google" />
+          <option name="name" value="Pixel 9 Pro XL" />
+          <option name="screenDensity" value="360" />
+          <option name="screenX" value="1008" />
+          <option name="screenY" value="2244" />
+        </PersistentDeviceSelectionData>
+        <PersistentDeviceSelectionData>
           <option name="api" value="33" />
           <option name="brand" value="google" />
           <option name="codename" value="lynx" />
@@ -239,6 +272,17 @@
           <option name="screenY" value="2560" />
         </PersistentDeviceSelectionData>
         <PersistentDeviceSelectionData>
+          <option name="api" value="34" />
+          <option name="brand" value="google" />
+          <option name="codename" value="tokay" />
+          <option name="id" value="tokay" />
+          <option name="manufacturer" value="Google" />
+          <option name="name" value="Pixel 9" />
+          <option name="screenDensity" value="420" />
+          <option name="screenX" value="1080" />
+          <option name="screenY" value="2424" />
+        </PersistentDeviceSelectionData>
+        <PersistentDeviceSelectionData>
           <option name="api" value="29" />
           <option name="brand" value="samsung" />
           <option name="codename" value="x1q" />

+ 1 - 0
app/build.gradle.kts

@@ -28,6 +28,7 @@ android {
         vectorDrawables {
             useSupportLibrary = true
         }
+//        resConfigs("en","de","fr","es")
 //        multiDexEnabled = true
     }
 

二進制
app/release/app-release.aab


二進制
app/release/fvpn_release_v-3.0.1(beta).apk


+ 2 - 2
app/release/output-metadata.json

@@ -11,8 +11,8 @@
       "type": "SINGLE",
       "filters": [],
       "attributes": [],
-      "versionCode": 329,
-      "versionName": "3.2.9",
+      "versionCode": 330,
+      "versionName": "3.3.0",
       "outputFile": "app-release.apk"
     }
   ],

+ 1 - 0
app/src/main/AndroidManifest.xml

@@ -46,6 +46,7 @@
         android:supportsRtl="true"
         android:theme="@style/Theme.AppCompat.Light.NoActionBar.App"
         android:usesCleartextTraffic="true"
+        android:localeConfig="@xml/locales_config"
         tools:targetApi="31">
         <activity
             android:name=".activities.HomeActivityTV"

+ 8 - 1
app/src/main/java/com/vpn/fastestvpnservice/MainActivity.kt

@@ -4,6 +4,7 @@ import android.content.Context
 import android.content.Intent
 import android.content.pm.ActivityInfo
 import android.content.pm.PackageManager
+import android.content.res.Configuration
 import android.net.Uri
 import android.os.Build
 import android.os.Bundle
@@ -12,6 +13,7 @@ import android.util.Log
 import android.view.WindowInsets
 import android.view.WindowInsetsController
 import android.view.WindowManager
+import android.widget.Toast
 import androidx.activity.compose.setContent
 import androidx.activity.viewModels
 import androidx.compose.foundation.isSystemInDarkTheme
@@ -40,6 +42,7 @@ import com.vpn.fastestvpnservice.interfaces.UpdateServersOnProtocol
 import com.vpn.fastestvpnservice.interfaces.VPNConnectionCallBacks
 import com.vpn.fastestvpnservice.navigation.SetUpNavGraph
 import com.vpn.fastestvpnservice.navigation.SetUpNavGraphTV
+import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.Settings
 import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.isSwitch
 import com.vpn.fastestvpnservice.screens.helpScreensAll.fileChooserCallback
 import com.vpn.fastestvpnservice.ui.theme.FastestVPNTheme
@@ -49,7 +52,6 @@ import de.blinkt.openvpn.core.App
 
 
 open class MainActivity : DockActivity(), ConnectivityReceiver.ConnectivityReceiverListener {
-    val loginViewModel: LoginViewModel by viewModels()
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -195,6 +197,11 @@ open class MainActivity : DockActivity(), ConnectivityReceiver.ConnectivityRecei
         return R.id.mainFrameLayout
     }
 
+//    override fun onConfigurationChanged(newConfig: Configuration) {
+//        super.onConfigurationChanged(newConfig)
+//        Toast.makeText(baseContext, "onConfigurationChanged", Toast.LENGTH_SHORT).show()
+//    }
+
 //    override fun getContainerId(): Int {
 //        return 0
 //    }

+ 4 - 2
app/src/main/java/com/vpn/fastestvpnservice/beans/Dark_Light_Theme.kt

@@ -8,8 +8,10 @@ val themesList = listOf<String>(
 )
 
 val languages = listOf<Language>(
-    Language("English","en"), Language("French","fr"),
-    Language("German","de"), Language("Turkish","tr")
+    Language("English","en"),
+    Language("French","fr"),
+//    Language("German","de"),
+//    Language("Spanish", "es")
 )
 
 var isDarkTheme: MutableState<Boolean> = mutableStateOf(false)

+ 1 - 1
app/src/main/java/com/vpn/fastestvpnservice/screens/bottomNavBarScreens/HomeScreen.kt

@@ -744,7 +744,7 @@ fun Home(
                             ),
                         ) {
                             Text(
-                                text = "Smart Connect",
+                                text = context.resources.getString(R.string.smart_connect),
                                 style = MaterialTheme.typography.customTypography.labelLarge.copy(
                                     fontSize = if (isTablet()) 21.sp else 18.sp
                                 ),

+ 45 - 26
app/src/main/java/com/vpn/fastestvpnservice/screens/bottomNavBarScreens/SettingsScreen.kt

@@ -12,6 +12,7 @@ import android.os.LocaleList
 import android.provider.Settings
 import android.util.Log
 import androidx.activity.ComponentActivity
+import androidx.appcompat.app.AppCompatDelegate
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.LocalOverscrollConfiguration
@@ -37,6 +38,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.DarkMode
+import androidx.compose.material.icons.filled.Language
 import androidx.compose.material.icons.filled.RocketLaunch
 import androidx.compose.material3.AlertDialog
 import androidx.compose.material3.BottomSheetDefaults
@@ -82,6 +84,7 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
 import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.res.colorResource
 import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
@@ -89,7 +92,9 @@ import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.compose.ui.window.DialogProperties
+import androidx.core.content.ContextCompat
 import androidx.core.content.ContextCompat.startActivity
+import androidx.core.os.LocaleListCompat
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
 import com.vpn.fastestvpnservice.MainActivity
@@ -116,15 +121,20 @@ import com.vpn.fastestvpnservice.viewmodels.SplashViewModel
 import de.blinkt.openvpn.core.App
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
+import java.util.Locale
 
 var isSwitch: MutableState<Boolean> = mutableStateOf(false)
 
 @OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
 @Composable
 fun Settings(navHostController: NavHostController, activity: ComponentActivity) {
+//    Log.d("test_settings_screen", "Settings")
+//    Log.d("test_settings_screen", AppCompatDelegate.getApplicationLocales().toString())
+
     val context = LocalContext.current
     val basePreferenceHelper = BasePreferenceHelper(context)
     var isLaunched by remember { mutableStateOf(false) }
+    var settingsString by remember { mutableStateOf(context.getString(R.string.settings)) }
 
     isSwitch.value = basePreferenceHelper.getLaunchState()
 
@@ -161,16 +171,21 @@ fun Settings(navHostController: NavHostController, activity: ComponentActivity)
 //                    )
 //                }
 
+                val settingsStr = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+                    context.getString(R.string.settings)
+                } else {
+                    settingsString
+                }
                 Spacer(modifier = Modifier.height(50.dp))
                 AddTextSettings(
-                    text = context.resources.getString(R.string.settings),
+                    text = settingsStr,
                     size = 28.sp,
                     color = MaterialTheme.colorScheme.primary,
                     style = MaterialTheme.typography.headlineLarge
                 )
                 AddRowSettingsColumn(
                     icon = R.drawable.vpn_protocols3x,
-                    text = "VPN Protocols"
+                    text = context.getString(R.string.vpn_protocols)
                 )
                 /* Commenting so far ...*/
 
@@ -188,7 +203,7 @@ fun Settings(navHostController: NavHostController, activity: ComponentActivity)
 
                 AddRowSettingsSmart(
                     icon = R.drawable.smart_connect3x,
-                    text = "Smart Connect",
+                    text = stringResource(id = R.string.smart_connect),
                     isRowShown = true,
                     isSheetShown = false,
                     navHostController
@@ -221,8 +236,6 @@ fun Settings(navHostController: NavHostController, activity: ComponentActivity)
                     icon = Icons.Default.DarkMode,
                     text = "Appearance")
 
-//                SelectLanguage(icon = Icons.Default.Language, text = "Language")
-                
                 AddRowLaunchSwitch(
                     icon = Icons.Filled.RocketLaunch,
                     text = "Launch On Startup",
@@ -232,6 +245,10 @@ fun Settings(navHostController: NavHostController, activity: ComponentActivity)
                     }
                 )
 
+                SelectLanguage(icon = Icons.Default.Language, text = "Language") {
+                    settingsString = it
+                }
+
                 if (isLaunched) {
                     AlertDialog(
                         onDismissRequest = { isLaunched = false },
@@ -1046,6 +1063,7 @@ fun AddRowDarkLightTheme(
 fun SelectLanguage(
     icon: ImageVector,
     text: String,
+    changeLanguage: (String) -> Unit
 ) {
     var isLanguageSheetOpen by remember { mutableStateOf(false) }
     val sheetState = rememberModalBottomSheetState()
@@ -1162,27 +1180,28 @@ fun SelectLanguage(
                                     selected = language == languages[0],
                                     onClick = {
                                         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
-                                            when (language.name) {
-                                                languages[0].name -> {
-                                                    context.getSystemService(LocaleManager::class.java).applicationLocales =
-                                                        LocaleList.forLanguageTags(language.code)
-                                                }
-
-                                                languages[1].name -> {
-                                                    context.getSystemService(LocaleManager::class.java).applicationLocales =
-                                                        LocaleList.forLanguageTags(language.code)
-                                                }
-
-                                                languages[2].name -> {
-                                                    context.getSystemService(LocaleManager::class.java).applicationLocales =
-                                                        LocaleList.forLanguageTags(language.code)
-                                                }
-
-                                                languages[3].name -> {
-                                                    context.getSystemService(LocaleManager::class.java).applicationLocales =
-                                                        LocaleList.forLanguageTags(language.code)
-                                                }
-                                            }
+                                            context.getSystemService(LocaleManager::class.java).applicationLocales =
+                                                LocaleList.forLanguageTags(language.code)
+                                        } else {
+                                            AppCompatDelegate.setApplicationLocales(
+                                                LocaleListCompat.forLanguageTags(
+                                                    language.code
+                                                )
+                                            )
+                                            context.resources.updateConfiguration(
+                                                context.resources.configuration.apply {
+                                                    setLocale(Locale.forLanguageTag(language.code))
+                                                },
+                                                context.resources.displayMetrics
+                                            )
+//                                            Log.d(
+//                                                "test_settings_screen",
+//                                                "Click = " + AppCompatDelegate
+//                                                    .getApplicationLocales()
+//                                                    .toString()
+//                                            )
+                                            changeLanguage(context.getString(R.string.settings))
+
                                         }
                                         isLanguageSheetOpen = false
                                     },

+ 4 - 2
app/src/main/res/values-de/strings.xml

@@ -1,5 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
 <resources>
+    <!-- Multi Lingual - (German-de) -->
     <string name="app_name">FastestVPN</string>
-    <string name="settings">Einstellungen</string>
+    <string name="settings">Settings</string>
+    <string name="smart_connect">Smart Connect</string>
+    <string name="vpn_protocols">VPN Protocols</string>
 </resources>

+ 5 - 0
app/src/main/res/values-es/strings.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">FastestVPN</string>
+    <string name="settings">Ajustes</string>
+</resources>

+ 3 - 0
app/src/main/res/values-fr/strings.xml

@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
+    <!-- Multi Lingual - (French-fr) -->
     <string name="app_name">FastestVPN</string>
     <string name="settings">Paramètres</string>
+    <string name="smart_connect">Connexion Intelligente</string>
+    <string name="vpn_protocols">Protocoles VPN</string>
 </resources>

+ 3 - 2
app/src/main/res/values/strings.xml

@@ -1,5 +1,4 @@
 <resources>
-    <string name="app_name">FastestVPN</string>
     <string name="chk_internet_connectivity">Please check your internet connection</string>
     <!-- TODO: Remove or change this placeholder text -->
     <string name="hello_blank_fragment">Hello blank fragment</string>
@@ -415,7 +414,6 @@
     <string name="policy">Privacy Policy</string>
     <string name="logout">Logout</string>
     <string name="select_protocol">Select Protocol</string>
-    <string name="smart_connect">Smart Connect</string>
     <string name="kill_switch">Kill Switch</string>
     <string name="about">About</string>
 
@@ -532,6 +530,9 @@
     <string name="app_widget_description">This is an app widget description</string>
 
     <!-- Multi Lingual - (English-en) -->
+    <string name="app_name">FastestVPN</string>
     <string name="settings">Settings</string>
+    <string name="smart_connect">Smart Connect</string>
+    <string name="vpn_protocols">VPN Protocols</string>
 
 </resources>