working on user settings

This commit is contained in:
leca 2024-10-31 04:03:33 +03:00
parent a0d96da9e4
commit 2feb2c1b5e
11 changed files with 246 additions and 73 deletions

View File

@ -1,6 +1,5 @@
package org.foxarmy.barcodescannerforemployees
import android.util.Log
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
@ -124,4 +123,52 @@ class Net {
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
}
}

View File

@ -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()
}
}
}

View File

@ -19,14 +19,12 @@ import androidx.security.crypto.MasterKeys
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions
import okhttp3.internal.http.hasBody
import org.foxarmy.barcodescannerforemployees.*
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
import java.io.File
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import kotlin.concurrent.thread
import kotlin.math.abs
class AddAbstractProductActivity : AppCompatActivity() {
private lateinit var imageView: ImageView
@ -157,7 +155,6 @@ class AddAbstractProductActivity : AppCompatActivity() {
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val sharedPreferences = EncryptedSharedPreferences.create(
// passing a file name to share a preferences
"sensitive",
masterKeyAlias,
applicationContext,
@ -166,6 +163,8 @@ class AddAbstractProductActivity : AppCompatActivity() {
)
val token = sharedPreferences.getString("token", "")
val response = n.uploadAbstractProduct("bsfe.foxarmy.org", 1, abstractProduct, File(pictureFile.absolutePath), token!!);
Toast.makeText(this, response, Toast.LENGTH_LONG).show()
}
finish()

View File

@ -23,7 +23,6 @@ class LoginActivity : AppCompatActivity() {
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val sharedPreferences = EncryptedSharedPreferences.create(
// passing a file name to share a preferences
"sensitive",
masterKeyAlias,
applicationContext,
@ -39,7 +38,7 @@ class LoginActivity : AppCompatActivity() {
val n = Net()
val response = n.login(server, username, password)
//TODO: handle it properly when server will support Accept-Language header
if (response == "Wrong password") {
Toast.makeText(this, getString(R.string.wrong_password), Toast.LENGTH_SHORT).show()
} else {
@ -58,11 +57,12 @@ class LoginActivity : AppCompatActivity() {
val n = Net()
val response = n.registerAccount(server, username, password);
//TODO: handle it properly when server will support Accept-Language header
if (response == "Such username exists") {
Toast.makeText(this, getString(R.string.username_already_exists), Toast.LENGTH_SHORT).show();
} else {
sharedPreferences.edit().putString("token", response).apply()
sharedPreferences.edit().putString("server", server).apply()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()

View File

@ -1,14 +1,18 @@
package org.foxarmy.barcodescannerforemployees.activities
//import android.R
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.viewpager.widget.ViewPager
import com.google.android.material.navigation.NavigationView
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.ViewPagerAdapter
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.StorageFragment
class MainActivity : AppCompatActivity() {
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var binding: ActivityMainBinding
lateinit var adapter: ViewPagerAdapter
var drawerLayout: DrawerLayout? = null
var actionBarDrawerToggle: ActionBarDrawerToggle? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -32,6 +39,16 @@ class MainActivity : AppCompatActivity() {
setupViewPager(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 { _ ->
val expiryCalendarIntent = Intent(this, ExpiryCalendarActivity::class.java)
val extras = Bundle()
@ -82,7 +99,7 @@ class MainActivity : AppCompatActivity() {
adapter.addFragment(ShelfFragment(), getString(R.string.shelf_title))
adapter.addFragment(CategoriesFragment(), getString(R.string.categories_title))
//TODO: settings fragments
//TODO: Settings
// setting adapter to view pager.
viewpager.adapter = adapter
@ -90,76 +107,100 @@ class MainActivity : AppCompatActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
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
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val currentPosition = binding.tabTablayout.selectedTabPosition
val fragment = adapter.getItem(currentPosition)
if (actionBarDrawerToggle!!.onOptionsItemSelected(item)) {
return true
} else {
return when (item.itemId) {
val currentPosition = binding.tabTablayout.selectedTabPosition
val fragment = adapter.getItem(currentPosition)
R.id.action_settings -> {
true
}
R.id.action_delete -> {
when (fragment::class.simpleName.toString()) {
"StorageFragment" -> {
AlertDialog.Builder(this)
.setMessage(getString(R.string.deleting_abstract_product_warning))
.setPositiveButton(getString(R.string.yes)) { _: DialogInterface, _: Int ->
val storageFragment = fragment as StorageFragment
storageFragment.removeSelected()
}
.setNegativeButton(getString(R.string.no)) { _: DialogInterface, _: Int ->
}.show()
}
"CategoriesFragment" -> {
AlertDialog.Builder(this)
.setMessage(getString(R.string.deleting_category_warning))
.setPositiveButton(getString(R.string.yes)) { _: DialogInterface, _: Int ->
val categoriesFragment = fragment as CategoriesFragment
categoriesFragment.removeSelected()
}
.setNegativeButton(getString(R.string.no)) { _: DialogInterface, _: Int ->
}.show()
}
"ShelfFragment" -> {
val shelfFragment = fragment as ShelfFragment
shelfFragment.removeSelected()
}
return when (item.itemId) {
R.id.action_settings -> {
true
}
true
}
R.id.action_update -> {
when (fragment::class.simpleName.toString()) {
"StorageFragment" -> {
val storageFragment = fragment as StorageFragment
storageFragment.updateSelected()
}
R.id.action_delete -> {
"CategoriesFragment" -> {
val categoriesFragment = fragment as CategoriesFragment
categoriesFragment.updateSelected()
}
when (fragment::class.simpleName.toString()) {
"StorageFragment" -> {
AlertDialog.Builder(this)
.setMessage(getString(R.string.deleting_abstract_product_warning))
.setPositiveButton(getString(R.string.yes)) { _: DialogInterface, _: Int ->
val storageFragment = fragment as StorageFragment
storageFragment.removeSelected()
}
.setNegativeButton(getString(R.string.no)) { _: DialogInterface, _: Int ->
"ShelfFragment" -> {
val shelfFragment = fragment as ShelfFragment
shelfFragment.updateSelected()
}.show()
}
"CategoriesFragment" -> {
AlertDialog.Builder(this)
.setMessage(getString(R.string.deleting_category_warning))
.setPositiveButton(getString(R.string.yes)) { _: DialogInterface, _: Int ->
val categoriesFragment = fragment as CategoriesFragment
categoriesFragment.removeSelected()
}
.setNegativeButton(getString(R.string.no)) { _: DialogInterface, _: Int ->
}.show()
}
"ShelfFragment" -> {
val shelfFragment = fragment as ShelfFragment
shelfFragment.removeSelected()
}
}
true
}
true
}
else -> super.onOptionsItemSelected(item)
R.id.action_update -> {
when (fragment::class.simpleName.toString()) {
"StorageFragment" -> {
val storageFragment = fragment as StorageFragment
storageFragment.updateSelected()
}
"CategoriesFragment" -> {
val categoriesFragment = fragment as CategoriesFragment
categoriesFragment.updateSelected()
}
"ShelfFragment" -> {
val shelfFragment = fragment as ShelfFragment
shelfFragment.updateSelected()
}
}
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
fun filterAbstractProductsByCategory(id: Int) {

View File

@ -20,7 +20,7 @@ class NavigatorActivity : Activity() {
finish();
}
fun isAuthenticated(): Boolean {
private fun isAuthenticated(): Boolean {
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val sharedPreferences = EncryptedSharedPreferences.create(

View File

@ -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>

View File

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.MainActivity"
android:fitsSystemWindows="true">
android:fitsSystemWindows="true" android:id="@+id/drawer_layout">
<FrameLayout
android:layout_width="match_parent"
@ -69,6 +69,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/drawer_menu" />
app:menu="@menu/drawer_menu" android:id="@+id/nav_view"/>
</androidx.drawerlayout.widget.DrawerLayout>

View File

@ -7,10 +7,9 @@
android:title="@string/my_account" />
<item
android:id="@+id/nav_settings"
android:title="@string/settings" />
<item
android:id="@+id/nav_logout"
android:id="@+id/nav_groups"
android:title="@string/my_groups" />
<item
android:id="@+id/nav_settings"
android:title="@string/settings"/>
</menu>

View File

@ -99,4 +99,8 @@
<string name="server">Сервер</string>
<string name="my_account">Мой аккаунт</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>

View File

@ -97,4 +97,8 @@
<string name="server">Server</string>
<string name="my_account">My account</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>