working on user settings
This commit is contained in:
parent
a0d96da9e4
commit
2feb2c1b5e
|
@ -1,6 +1,5 @@
|
||||||
package org.foxarmy.barcodescannerforemployees
|
package org.foxarmy.barcodescannerforemployees
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
|
@ -124,4 +123,52 @@ class Net {
|
||||||
|
|
||||||
return responseText
|
return responseText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun changeUsername(server: String, token: String, newUsername: String): String {
|
||||||
|
|
||||||
|
lateinit var response: Response
|
||||||
|
|
||||||
|
thread {
|
||||||
|
val client = OkHttpClient()
|
||||||
|
|
||||||
|
val body = FormBody.Builder()
|
||||||
|
body.add("username", newUsername)
|
||||||
|
|
||||||
|
val requestBody = body.build()
|
||||||
|
|
||||||
|
val request = Request.Builder().url("https://$server/api/user/changeUsername")
|
||||||
|
.post(requestBody)
|
||||||
|
.addHeader("Authorization", "Bearer $token")
|
||||||
|
.build()
|
||||||
|
response = client.newCall(request).execute()
|
||||||
|
}.join()
|
||||||
|
|
||||||
|
val responseText = response.body!!.string()
|
||||||
|
|
||||||
|
return responseText
|
||||||
|
}
|
||||||
|
|
||||||
|
fun changePassword(server: String, token: String, newPassword: String): String {
|
||||||
|
|
||||||
|
lateinit var response: Response
|
||||||
|
|
||||||
|
thread {
|
||||||
|
val client = OkHttpClient()
|
||||||
|
|
||||||
|
val body = FormBody.Builder()
|
||||||
|
body.add("password", newPassword)
|
||||||
|
|
||||||
|
val requestBody = body.build()
|
||||||
|
|
||||||
|
val request = Request.Builder().url("https://$server/api/user/changePassword")
|
||||||
|
.post(requestBody)
|
||||||
|
.addHeader("Authorization", "Bearer $token")
|
||||||
|
.build()
|
||||||
|
response = client.newCall(request).execute()
|
||||||
|
}.join()
|
||||||
|
|
||||||
|
val responseText = response.body!!.string()
|
||||||
|
|
||||||
|
return responseText
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.foxarmy.barcodescannerforemployees.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.security.crypto.EncryptedSharedPreferences
|
||||||
|
import androidx.security.crypto.MasterKeys
|
||||||
|
import org.foxarmy.barcodescannerforemployees.Net
|
||||||
|
import org.foxarmy.barcodescannerforemployees.databinding.ActivityAccountSettingsBinding
|
||||||
|
|
||||||
|
class AccountSettingsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityAccountSettingsBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
binding = ActivityAccountSettingsBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||||
|
|
||||||
|
val sharedPreferences = EncryptedSharedPreferences.create(
|
||||||
|
"sensitive",
|
||||||
|
masterKeyAlias,
|
||||||
|
applicationContext,
|
||||||
|
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||||
|
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||||
|
)
|
||||||
|
|
||||||
|
val server = sharedPreferences.getString("server", "bsfe.foxarmy.org")
|
||||||
|
val token = sharedPreferences.getString("token", "")
|
||||||
|
val net = Net()
|
||||||
|
|
||||||
|
binding.saveUsernameButton.setOnClickListener {
|
||||||
|
Toast.makeText(this, net.changeUsername(server!!, token!!, binding.newUsernameTextEdit.text.toString()), Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.savePasswordButton.setOnClickListener {
|
||||||
|
Toast.makeText(this, net.changePassword(server!!, token!!, binding.newPasswordTextEdit.text.toString()), Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,14 +19,12 @@ import androidx.security.crypto.MasterKeys
|
||||||
import com.journeyapps.barcodescanner.ScanContract
|
import com.journeyapps.barcodescanner.ScanContract
|
||||||
import com.journeyapps.barcodescanner.ScanIntentResult
|
import com.journeyapps.barcodescanner.ScanIntentResult
|
||||||
import com.journeyapps.barcodescanner.ScanOptions
|
import com.journeyapps.barcodescanner.ScanOptions
|
||||||
import okhttp3.internal.http.hasBody
|
|
||||||
import org.foxarmy.barcodescannerforemployees.*
|
import org.foxarmy.barcodescannerforemployees.*
|
||||||
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import kotlin.math.abs
|
|
||||||
|
|
||||||
class AddAbstractProductActivity : AppCompatActivity() {
|
class AddAbstractProductActivity : AppCompatActivity() {
|
||||||
private lateinit var imageView: ImageView
|
private lateinit var imageView: ImageView
|
||||||
|
@ -157,7 +155,6 @@ class AddAbstractProductActivity : AppCompatActivity() {
|
||||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||||
|
|
||||||
val sharedPreferences = EncryptedSharedPreferences.create(
|
val sharedPreferences = EncryptedSharedPreferences.create(
|
||||||
// passing a file name to share a preferences
|
|
||||||
"sensitive",
|
"sensitive",
|
||||||
masterKeyAlias,
|
masterKeyAlias,
|
||||||
applicationContext,
|
applicationContext,
|
||||||
|
@ -166,6 +163,8 @@ class AddAbstractProductActivity : AppCompatActivity() {
|
||||||
)
|
)
|
||||||
val token = sharedPreferences.getString("token", "")
|
val token = sharedPreferences.getString("token", "")
|
||||||
val response = n.uploadAbstractProduct("bsfe.foxarmy.org", 1, abstractProduct, File(pictureFile.absolutePath), token!!);
|
val response = n.uploadAbstractProduct("bsfe.foxarmy.org", 1, abstractProduct, File(pictureFile.absolutePath), token!!);
|
||||||
|
|
||||||
|
Toast.makeText(this, response, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
finish()
|
finish()
|
||||||
|
|
|
@ -23,7 +23,6 @@ class LoginActivity : AppCompatActivity() {
|
||||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||||
|
|
||||||
val sharedPreferences = EncryptedSharedPreferences.create(
|
val sharedPreferences = EncryptedSharedPreferences.create(
|
||||||
// passing a file name to share a preferences
|
|
||||||
"sensitive",
|
"sensitive",
|
||||||
masterKeyAlias,
|
masterKeyAlias,
|
||||||
applicationContext,
|
applicationContext,
|
||||||
|
@ -39,7 +38,7 @@ class LoginActivity : AppCompatActivity() {
|
||||||
val n = Net()
|
val n = Net()
|
||||||
|
|
||||||
val response = n.login(server, username, password)
|
val response = n.login(server, username, password)
|
||||||
|
//TODO: handle it properly when server will support Accept-Language header
|
||||||
if (response == "Wrong password") {
|
if (response == "Wrong password") {
|
||||||
Toast.makeText(this, getString(R.string.wrong_password), Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.wrong_password), Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,11 +57,12 @@ class LoginActivity : AppCompatActivity() {
|
||||||
val n = Net()
|
val n = Net()
|
||||||
|
|
||||||
val response = n.registerAccount(server, username, password);
|
val response = n.registerAccount(server, username, password);
|
||||||
|
//TODO: handle it properly when server will support Accept-Language header
|
||||||
if (response == "Such username exists") {
|
if (response == "Such username exists") {
|
||||||
Toast.makeText(this, getString(R.string.username_already_exists), Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, getString(R.string.username_already_exists), Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
sharedPreferences.edit().putString("token", response).apply()
|
sharedPreferences.edit().putString("token", response).apply()
|
||||||
|
sharedPreferences.edit().putString("server", server).apply()
|
||||||
val intent = Intent(this, MainActivity::class.java)
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
finish()
|
finish()
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
package org.foxarmy.barcodescannerforemployees.activities
|
package org.foxarmy.barcodescannerforemployees.activities
|
||||||
|
|
||||||
|
//import android.R
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
|
import com.google.android.material.navigation.NavigationView
|
||||||
import org.foxarmy.barcodescannerforemployees.R
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
import org.foxarmy.barcodescannerforemployees.ViewPagerAdapter
|
import org.foxarmy.barcodescannerforemployees.ViewPagerAdapter
|
||||||
import org.foxarmy.barcodescannerforemployees.databinding.ActivityMainBinding
|
import org.foxarmy.barcodescannerforemployees.databinding.ActivityMainBinding
|
||||||
|
@ -17,10 +21,13 @@ import org.foxarmy.barcodescannerforemployees.fragments.CategoriesFragment
|
||||||
import org.foxarmy.barcodescannerforemployees.fragments.ShelfFragment
|
import org.foxarmy.barcodescannerforemployees.fragments.ShelfFragment
|
||||||
import org.foxarmy.barcodescannerforemployees.fragments.StorageFragment
|
import org.foxarmy.barcodescannerforemployees.fragments.StorageFragment
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
|
||||||
|
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
|
||||||
|
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
lateinit var adapter: ViewPagerAdapter
|
lateinit var adapter: ViewPagerAdapter
|
||||||
|
var drawerLayout: DrawerLayout? = null
|
||||||
|
var actionBarDrawerToggle: ActionBarDrawerToggle? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -32,6 +39,16 @@ class MainActivity : AppCompatActivity() {
|
||||||
setupViewPager(binding.tabViewpager)
|
setupViewPager(binding.tabViewpager)
|
||||||
binding.tabTablayout.setupWithViewPager(binding.tabViewpager)
|
binding.tabTablayout.setupWithViewPager(binding.tabViewpager)
|
||||||
|
|
||||||
|
drawerLayout = binding.drawerLayout
|
||||||
|
actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, R.string.nav_open, R.string.nav_close)
|
||||||
|
|
||||||
|
drawerLayout!!.addDrawerListener(actionBarDrawerToggle!!)
|
||||||
|
actionBarDrawerToggle!!.syncState()
|
||||||
|
binding.navView.setNavigationItemSelectedListener(this)
|
||||||
|
|
||||||
|
// to make the Navigation drawer icon always appear on the action bar
|
||||||
|
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
binding.expiryCalendarFab.setOnClickListener { _ ->
|
binding.expiryCalendarFab.setOnClickListener { _ ->
|
||||||
val expiryCalendarIntent = Intent(this, ExpiryCalendarActivity::class.java)
|
val expiryCalendarIntent = Intent(this, ExpiryCalendarActivity::class.java)
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
|
@ -82,7 +99,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
adapter.addFragment(ShelfFragment(), getString(R.string.shelf_title))
|
adapter.addFragment(ShelfFragment(), getString(R.string.shelf_title))
|
||||||
adapter.addFragment(CategoriesFragment(), getString(R.string.categories_title))
|
adapter.addFragment(CategoriesFragment(), getString(R.string.categories_title))
|
||||||
|
|
||||||
//TODO: settings fragments
|
//TODO: Settings
|
||||||
|
|
||||||
// setting adapter to view pager.
|
// setting adapter to view pager.
|
||||||
viewpager.adapter = adapter
|
viewpager.adapter = adapter
|
||||||
|
@ -90,16 +107,38 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
menuInflater.inflate(R.menu.menu_main, menu)
|
menuInflater.inflate(R.menu.menu_main, menu)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNavigationItemSelected(item: MenuItem): Boolean {
|
||||||
|
lateinit var intent: Intent
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.nav_account -> {
|
||||||
|
intent = Intent(this, AccountSettingsActivity::class.java)
|
||||||
|
}
|
||||||
|
R.id.nav_groups -> {
|
||||||
|
intent = Intent(this, AccountSettingsActivity::class.java)
|
||||||
|
}
|
||||||
|
R.id.nav_settings -> {
|
||||||
|
//TODO: Settings
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
if (actionBarDrawerToggle!!.onOptionsItemSelected(item)) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
|
||||||
val currentPosition = binding.tabTablayout.selectedTabPosition
|
val currentPosition = binding.tabTablayout.selectedTabPosition
|
||||||
val fragment = adapter.getItem(currentPosition)
|
val fragment = adapter.getItem(currentPosition)
|
||||||
|
|
||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
|
|
||||||
|
|
||||||
R.id.action_settings -> {
|
R.id.action_settings -> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -162,6 +201,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fun filterAbstractProductsByCategory(id: Int) {
|
fun filterAbstractProductsByCategory(id: Int) {
|
||||||
binding.tabViewpager.setCurrentItem(0, true)
|
binding.tabViewpager.setCurrentItem(0, true)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class NavigatorActivity : Activity() {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isAuthenticated(): Boolean {
|
private fun isAuthenticated(): Boolean {
|
||||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||||
|
|
||||||
val sharedPreferences = EncryptedSharedPreferences.create(
|
val sharedPreferences = EncryptedSharedPreferences.create(
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:ems="10"
|
||||||
|
android:id="@+id/newPasswordTextEdit"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.497" android:hint="@string/new_password"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/saveUsernameButton" android:layout_marginTop="64dp"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="text"
|
||||||
|
android:ems="10"
|
||||||
|
android:id="@+id/newUsernameTextEdit"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:hint="@string/new_name" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="48dp"/>
|
||||||
|
<Button
|
||||||
|
android:text="@string/saveButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" android:id="@+id/saveUsernameButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/newUsernameTextEdit" android:layout_marginTop="16dp"/>
|
||||||
|
<Button
|
||||||
|
android:text="@string/saveButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" android:id="@+id/savePasswordButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:layout_marginTop="16dp" app:layout_constraintTop_toBottomOf="@+id/newPasswordTextEdit"/>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -6,7 +6,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".activities.MainActivity"
|
tools:context=".activities.MainActivity"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true" android:id="@+id/drawer_layout">
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -69,6 +69,6 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
app:menu="@menu/drawer_menu" />
|
app:menu="@menu/drawer_menu" android:id="@+id/nav_view"/>
|
||||||
|
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
</androidx.drawerlayout.widget.DrawerLayout>
|
|
@ -6,11 +6,10 @@
|
||||||
android:id="@+id/nav_account"
|
android:id="@+id/nav_account"
|
||||||
android:title="@string/my_account" />
|
android:title="@string/my_account" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_groups"
|
||||||
|
android:title="@string/my_groups" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_settings"
|
android:id="@+id/nav_settings"
|
||||||
android:title="@string/settings"/>
|
android:title="@string/settings"/>
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_logout"
|
|
||||||
android:title="@string/my_groups" />
|
|
||||||
</menu>
|
</menu>
|
|
@ -99,4 +99,8 @@
|
||||||
<string name="server">Сервер</string>
|
<string name="server">Сервер</string>
|
||||||
<string name="my_account">Мой аккаунт</string>
|
<string name="my_account">Мой аккаунт</string>
|
||||||
<string name="my_groups">Мои группы</string>
|
<string name="my_groups">Мои группы</string>
|
||||||
|
<string name="nav_open">navigation open</string>
|
||||||
|
<string name="nav_close">Navigation close</string>
|
||||||
|
<string name="new_name">New name</string>
|
||||||
|
<string name="new_password">New password</string>
|
||||||
</resources>
|
</resources>
|
|
@ -97,4 +97,8 @@
|
||||||
<string name="server">Server</string>
|
<string name="server">Server</string>
|
||||||
<string name="my_account">My account</string>
|
<string name="my_account">My account</string>
|
||||||
<string name="my_groups">My groups</string>
|
<string name="my_groups">My groups</string>
|
||||||
|
<string name="nav_open">navigation open</string>
|
||||||
|
<string name="nav_close">Navigation close</string>
|
||||||
|
<string name="new_name">New name</string>
|
||||||
|
<string name="new_password">New password</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue