From a860e4d59f6f9aa316d3eb043aaa15ffa043a394 Mon Sep 17 00:00:00 2001 From: leca Date: Mon, 18 Nov 2024 14:20:34 +0300 Subject: [PATCH] added functionality to group rename & leave buttons, added ability to transfer ownership of a group --- .../foxarmy/barcodescannerforemployees/Net.kt | 65 +++++++++++ .../barcodescannerforemployees/Utils.kt | 12 +- .../activities/LoginActivity.kt | 9 +- .../activities/ManageGroupActivity.kt | 103 ++++++++++++++++-- .../activities/MyGroupsActivity.kt | 4 +- .../activities/NavigatorActivity.kt | 23 +++- .../views/GroupMemberView.kt | 2 +- app/src/main/res/menu/user_pop_menu.xml | 6 + app/src/main/res/values-ru/strings.xml | 6 + app/src/main/res/values/strings.xml | 6 + 10 files changed, 217 insertions(+), 19 deletions(-) create mode 100644 app/src/main/res/menu/user_pop_menu.xml diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/Net.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/Net.kt index fe2cf9e..a0f96e1 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/Net.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/Net.kt @@ -653,4 +653,69 @@ class Net { return response } + + fun renameGroup(groupId: Int, newName: String): Response { + lateinit var response: Response + + thread { + val client = OkHttpClient() + + val body = FormBody.Builder() + .add("name", newName) + .build() + + val request = Request.Builder() + .url("https://$server/api/group/rename/$groupId") + .post(body) + .addHeader("Authorization", "Bearer $token") + .addHeader("accept-language", language) + .build() + + response = client.newCall(request).execute() + }.join() + + return response + } + + fun transfer_ownership(groupId: Int, userId: Int): Response { + lateinit var response: Response + + thread { + val client = OkHttpClient() + + val body = FormBody.Builder() + .add("userId", userId.toString()) + .build() + + val request = Request.Builder() + .url("https://$server/api/group/transferOwnership/$groupId") + .post(body) + .addHeader("Authorization", "Bearer $token") + .addHeader("accept-language", language) + .build() + + response = client.newCall(request).execute() + }.join() + + return response + } + + fun leaveGroup(groupId: Int): Response { + lateinit var response: Response + + thread { + val client = OkHttpClient() + + val request = Request.Builder() + .url("https://$server/api/group/leave/$groupId") + .get() + .addHeader("Authorization", "Bearer $token") + .addHeader("accept-language", language) + .build() + + response = client.newCall(request).execute() + }.join() + + return response + } } \ No newline at end of file diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/Utils.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/Utils.kt index 83d07e8..8de2d95 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/Utils.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/Utils.kt @@ -3,6 +3,7 @@ package org.foxarmy.barcodescannerforemployees import android.app.Activity import android.content.Context import android.content.ContextWrapper +import android.content.Intent import android.content.SharedPreferences import android.graphics.Bitmap import android.graphics.BitmapFactory @@ -18,6 +19,7 @@ import androidx.core.content.FileProvider import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKeys import com.google.firebase.components.BuildConfig +import org.foxarmy.barcodescannerforemployees.activities.LoginActivity import java.io.File import java.io.FileInputStream import java.io.FileOutputStream @@ -141,10 +143,14 @@ fun getUnitNameById(context: Context, id: Int): String { } } -fun parseArray(input: String): IntArray { +fun parseIntArray(input: String): IntArray { return input.trim('[', ']').split(",").map { it.trim().toInt() }.toIntArray() } +fun parseStringList(input: String): List { + return input.trim('[', ']').split(",").map { it.trim() }.toList() +} + fun calculateMd5Hash(file: File): String { val digest = MessageDigest.getInstance("MD5") val fis = FileInputStream(file) @@ -204,7 +210,9 @@ fun noInternetConnectionAvailableNotification(context: Context) { sharedPreferences.edit().putString("server", "").apply() sharedPreferences.edit().putStringSet("groups", emptySet()).apply() sharedPreferences.edit().putString("currentGroup", "").apply() - exitProcess(0) + val intent = Intent(context, LoginActivity::class.java) + context.startActivity(intent) + context.finish() }.show() } } diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/LoginActivity.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/LoginActivity.kt index 1709e92..5ebe410 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/LoginActivity.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/LoginActivity.kt @@ -9,7 +9,7 @@ import org.foxarmy.barcodescannerforemployees.Net import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.databinding.ActivityLoginBinding import org.foxarmy.barcodescannerforemployees.noInternetConnectionAvailableNotification -import org.foxarmy.barcodescannerforemployees.parseArray +import org.foxarmy.barcodescannerforemployees.parseIntArray import org.json.JSONObject class LoginActivity : AppCompatActivity() { @@ -53,7 +53,12 @@ class LoginActivity : AppCompatActivity() { val r = net.getMyGroups().body!!.string() - val myGroups = parseArray(r).map { a -> a.toString()} + if (r == "" || r == "[]") { + val intent = Intent(this, GroupActivity::class.java) + startActivity(intent) + finish() + } + val myGroups = parseIntArray(r).map { a -> a.toString()} sharedPreferences.edit().putStringSet("groups", myGroups.toSet()).apply() sharedPreferences.edit().putString("currentGroup", myGroups[0]).apply() diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/ManageGroupActivity.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/ManageGroupActivity.kt index 9090d1b..6064902 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/ManageGroupActivity.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/ManageGroupActivity.kt @@ -1,19 +1,28 @@ package org.foxarmy.barcodescannerforemployees.activities import android.content.Context +import android.content.Intent import android.content.SharedPreferences import android.os.Bundle import android.view.View +import android.widget.EditText +import android.widget.PopupMenu +import android.widget.Toast +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import okhttp3.Response import org.foxarmy.barcodescannerforemployees.Net +import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.databinding.ActivityManageGroupBinding -import org.foxarmy.barcodescannerforemployees.parseArray +import org.foxarmy.barcodescannerforemployees.parseIntArray import org.foxarmy.barcodescannerforemployees.views.GroupMemberView class ManageGroupActivity : AppCompatActivity(){ private lateinit var binding: ActivityManageGroupBinding - private var isAdmin: Boolean = true + private var isAdmin: Boolean = false private lateinit var sharedPreferences: SharedPreferences + private lateinit var net: Net + private var groupId: Int = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -21,30 +30,94 @@ class ManageGroupActivity : AppCompatActivity(){ binding = ActivityManageGroupBinding.inflate(layoutInflater) setContentView(binding.root) - val groupId = intent.extras!!.getInt("groupId") + groupId = intent.extras!!.getInt("groupId") sharedPreferences = org.foxarmy.barcodescannerforemployees.getPreferences(this) - val net = Net() + net = Net() net.token = sharedPreferences.getString("token", "")!! net.server = sharedPreferences.getString("server", "")!! net.language = sharedPreferences.getString("language", "en-US")!! - val users = parseArray(net.getUsersInGroup(groupId).body!!.string()) + setUpMembers() + + binding.renameButton.setOnClickListener { + val input = EditText(this) + AlertDialog.Builder(this) + .setTitle(getString(R.string.new_group_name)) + .setView(input) + .setPositiveButton(getString(R.string.ok)) { _, _, -> + val newName = input.text.toString() + val response = net.renameGroup(groupId, newName) + Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show() + } + .setNegativeButton(getString(R.string.cancel)) {_, _, -> + + }.show() + } + + binding.leaveButton.setOnClickListener { + val response: Response = net.leaveGroup(groupId) + Toast.makeText(this, response.body!!.string(), Toast.LENGTH_SHORT).show() + if (response.code == 200) { + val groups = sharedPreferences.getStringSet("groups", emptySet())!! + groups.remove(groupId.toString()) + if (groups.isEmpty()) { + sharedPreferences.edit().putStringSet("groups", groups).apply() + val intent = Intent(this, GroupActivity::class.java) + startActivity(intent) + finish() + } + sharedPreferences.edit().putString("currentGroup", groups.toList()[0]).apply() + finish() + } + } + + setUpAdminRelatedButtons() + } + + private fun setUpMembers() { + val users = parseIntArray(net.getUsersInGroup(groupId).body!!.string()) for (user in users) { val groupMemberView = GroupMemberView(this, this as Context, net.getUsernameById(user).body!!.string(), user) + groupMemberView.setOnLongClickListener { view -> + if (!amIAnAdminIn(groupId)) return@setOnLongClickListener false + val popupMenu = PopupMenu(this, groupMemberView) + popupMenu.inflate(R.menu.user_pop_menu) + popupMenu.setOnMenuItemClickListener { item -> + when(item.itemId) { + R.id.kick -> { + + + + setUpMembers() + false + } + R.id.transfer_ownership -> { + AlertDialog.Builder(this) + .setMessage(getString(R.string.transfer_ownership_confirmation)) + .setPositiveButton(R.string.yes) { _, _, -> + val response: Response = net.transfer_ownership(groupId, (view as GroupMemberView).userId) + Toast.makeText(this, response.body!!.string(), Toast.LENGTH_SHORT).show() + setUpAdminRelatedButtons() + } + .setNegativeButton(R.string.no) { _, _, -> } + .show() + true + } + else -> false + } + } + popupMenu.show() + true + } + binding.groupsContent.addView(groupMemberView) } - - isAdmin = amIAnAdminIn(groupId) - - if (!isAdmin) { - binding.renameButton.visibility = View.GONE - } } fun amIAnAdminIn(groupId: Int): Boolean { @@ -57,4 +130,12 @@ class ManageGroupActivity : AppCompatActivity(){ val result = sharedPreferences.getInt("userId", 0) == net.getGroupAdminId(groupId).body!!.string().toInt() return result } + + fun setUpAdminRelatedButtons() { + isAdmin = amIAnAdminIn(groupId) + + if (!isAdmin) { + binding.renameButton.visibility = View.GONE + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MyGroupsActivity.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MyGroupsActivity.kt index 21449ac..1b2f27c 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MyGroupsActivity.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/MyGroupsActivity.kt @@ -8,7 +8,7 @@ import androidx.appcompat.app.AppCompatActivity import org.foxarmy.barcodescannerforemployees.Net import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.databinding.ActivityMyGroupsBinding -import org.foxarmy.barcodescannerforemployees.parseArray +import org.foxarmy.barcodescannerforemployees.parseIntArray import org.foxarmy.barcodescannerforemployees.views.GroupView class MyGroupsActivity : AppCompatActivity(){ @@ -28,7 +28,7 @@ class MyGroupsActivity : AppCompatActivity(){ net.server = sharedPreferences.getString("server", "")!! net.language = sharedPreferences.getString("language", "en-US")!! - val groups = parseArray(net.getMyGroups().body!!.string()) + val groups = parseIntArray(net.getMyGroups().body!!.string()) val container = findViewById(R.id.groupsLayout) diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/NavigatorActivity.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/NavigatorActivity.kt index cb1c3f4..85e9645 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/NavigatorActivity.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/activities/NavigatorActivity.kt @@ -4,6 +4,8 @@ import android.app.Activity import android.content.Intent import android.content.SharedPreferences import android.os.Bundle +import org.foxarmy.barcodescannerforemployees.Net +import org.foxarmy.barcodescannerforemployees.parseStringList class NavigatorActivity : Activity() { @@ -37,6 +39,25 @@ class NavigatorActivity : Activity() { } private fun isInGroup(): Boolean { - return sharedPreferences.getStringSet("groups", emptySet())!!.isNotEmpty() + val groups = sharedPreferences.getStringSet("groups", emptySet())!! + if (groups.isEmpty()) { + if(sharedPreferences.getString("token", "")!! == "") return false + val net = Net() + net.language = sharedPreferences.getString("language", "")!! + net.server = sharedPreferences.getString("server", "")!! + net.token = sharedPreferences.getString("token", "")!! + + val response = net.getMyGroups().body!!.string() + if (response == "" || response == "[]") return false + val groupsFromServer = parseStringList(response) + if (groupsFromServer.isNotEmpty()) { + sharedPreferences.edit().putStringSet("groups", groupsFromServer.toSet()).apply() + sharedPreferences.edit().putString("currentGroup", groupsFromServer[0]).apply() + return true + } else { + return false + } + } + return true } } \ No newline at end of file diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/views/GroupMemberView.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/views/GroupMemberView.kt index 42aed1f..3099d38 100644 --- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/views/GroupMemberView.kt +++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/views/GroupMemberView.kt @@ -10,7 +10,7 @@ import org.foxarmy.barcodescannerforemployees.R class GroupMemberView : LinearLayout { private var username: String - private var userId: Int + var userId: Int constructor(activity: Activity, context: Context, username: String, userId: Int) : super(context) { diff --git a/app/src/main/res/menu/user_pop_menu.xml b/app/src/main/res/menu/user_pop_menu.xml new file mode 100644 index 0000000..f234736 --- /dev/null +++ b/app/src/main/res/menu/user_pop_menu.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9d1a424..2dbce87 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -120,6 +120,12 @@ Эта возможность доступна только с онлайн аккаунтом Имя пользователя изменено. Пожалуйста, перезайдите Пароль изменён. Пожалуйста, перезайдите + Enter new group name + Kick + Transfer ownership + Are you sure you want to transfer ownership on current group to that + user? + en-US ru-RU diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f782e5e..5081544 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -118,6 +118,12 @@ This feature is online only Your username has been changed. Please, relogin You password was changed. Please, relogin + Enter new group name + Kick + Transfer ownership + Are you sure you want to transfer ownership on current group to that + user? + en-US ru-RU