Мимо собственного кода

Я без шуток не хожу -
То комменты не коммичу,
То весь класс перепишу

Кволити - не кволити,
Хуй меня уволите
This commit is contained in:
leca 2024-11-20 15:42:40 +03:00
parent a860e4d59f
commit 6bbf436f45
21 changed files with 716 additions and 560 deletions

View File

@ -0,0 +1,14 @@
package org.foxarmy.barcodescannerforemployees
import android.app.Dialog
import android.os.Bundle
import androidx.fragment.app.DialogFragment
class LoadingDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState)
}
}

View File

@ -1,6 +1,9 @@
package org.foxarmy.barcodescannerforemployees
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
@ -11,19 +14,18 @@ import org.foxarmy.barcodescannerforemployees.dataclasses.Product
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import kotlin.concurrent.thread
class Net {
var language = "en-US"
var server = "bsfe.foxarmy.org"
var token = ""
fun serverIsAvailable(context: Context): Boolean {
fun serverIsAvailable(context: Context, callback: (Boolean) -> Unit) {
if (!isInternetConnectionAvailable(context)) {
return false
callback(false)
}
var flag = false
thread {
CoroutineScope(Dispatchers.IO).launch {
var flag = false
val client = OkHttpClient();
val request = Request.Builder()
.url("https://$server/status")
@ -32,17 +34,17 @@ class Net {
try {
val response = client.newCall(request).execute();
flag = response.code == 200;
flag = response.code == 200;
} catch (e: Exception) {
flag = false;
}
}.join()
return flag
callback(flag)
}
}
fun requestProductFromOnlineDB(barcode: String): String {
var response = ""
thread {
fun requestProductFromOnlineDB(barcode: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
val url = "https://ean-online.ru/match.php"
val client = OkHttpClient()
@ -58,19 +60,15 @@ class Net {
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute().body!!.string()
}.join()
return if (response == "") {
"Not found 404"
} else {
response
response = client.newCall(request).execute()
callback(response)
}
}
fun registerAccount(username: String, password: String): Response {
lateinit var response: Response
thread {
fun registerAccount(username: String, password: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
val client = OkHttpClient()
val body = FormBody.Builder()
@ -86,14 +84,13 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun login(username: String, password: String): Response {
lateinit var response: Response
thread {
fun login(username: String, password: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
val client = OkHttpClient()
val body = FormBody.Builder()
@ -107,15 +104,19 @@ class Net {
.addHeader("accept-language", language)
.build()
response = client.newCall(requestLogin).execute()
}.join()
return response
callback(response)
}
}
fun uploadAbstractProduct(groupId: Int, abstractProduct: AbstractProduct, imageFile: File): Response {
lateinit var response: Response
fun uploadAbstractProduct(
groupId: Int,
abstractProduct: AbstractProduct,
imageFile: File,
callback: (Response) -> Unit,
) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = MultipartBody.Builder()
@ -138,16 +139,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun changeUsername(newUsername: String): Response {
fun changeUsername(newUsername: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -162,16 +161,14 @@ class Net {
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun changePassword(newPassword: String): Response {
fun changePassword(newPassword: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -186,15 +183,12 @@ class Net {
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun createGroup(name: String, password: String): Response {
lateinit var response: Response
thread {
fun createGroup(name: String, password: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -207,19 +201,19 @@ class Net {
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
val response = client.newCall(request).execute()
changeGroupPassword(name, password, { responseFromPassword ->
callback(response)
})
changeGroupPassword(name, password)
return response
}
}
fun joinGroup(id: Int, password: String): Response {
lateinit var response: Response
fun joinGroup(id: Int, password: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -233,41 +227,38 @@ class Net {
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun changeGroupPassword(name: String, password: String): Response {
lateinit var response: Response
fun changeGroupPassword(name: String, password: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
getGroupId(name, { groupId ->
val client = OkHttpClient()
val groupId = getGroupId(name);
val body = FormBody.Builder()
body.add("password", password)
val client = OkHttpClient()
val requestBody = body.build()
val body = FormBody.Builder()
body.add("password", password)
val requestBody = body.build()
val request = Request.Builder()
.url("https://$server/api/group/password/$groupId")
.post(requestBody)
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
val request = Request.Builder()
.url("https://$server/api/group/password/$groupId")
.post(requestBody)
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
callback(response)
});
}
}
fun getGroupId(name: String): String {
lateinit var response: Response
fun getGroupId(name: String, callback: (String) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -277,17 +268,14 @@ class Net {
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
val responseText = response.body!!.string()
return responseText
callback(response.body!!.string())
}
}
fun getGroupName(id: Int): String {
lateinit var response: Response
fun getGroupName(id: Int, callback: (String) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -297,17 +285,14 @@ class Net {
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
val responseText = response.body!!.string()
return responseText
callback(response.body!!.string())
}
}
fun getUsersInGroup(groupId: Int): Response {
lateinit var response: Response
fun getUsersInGroup(groupId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -318,15 +303,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun getMyGroups(): Response {
lateinit var response: Response
fun getMyGroups(callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -337,15 +321,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun getUsernameById(userId: Int): Response {
lateinit var response: Response
fun getUsernameById(userId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -356,15 +339,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun getGroupAdminId(groupId: Int): Response {
lateinit var response: Response
fun getGroupAdminId(groupId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -375,15 +357,19 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun updateAbstractProduct(groupId: Int, abstractProduct: AbstractProduct, imageFile: File): Response {
lateinit var response: Response
fun updateAbstractProduct(
groupId: Int,
abstractProduct: AbstractProduct,
imageFile: File,
callback: (Response) -> Unit,
) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = MultipartBody.Builder()
@ -406,15 +392,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun uploadCategory(groupId: Int, category: Category): Response {
lateinit var response: Response
fun uploadCategory(groupId: Int, category: Category, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -431,15 +416,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun updateCategory(groupId: Int, category: Category): Response {
lateinit var response: Response
fun updateCategory(groupId: Int, category: Category, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -456,15 +440,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun uploadProduct(groupId: Int, product: Product): Response {
lateinit var response: Response
fun uploadProduct(groupId: Int, product: Product, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -484,15 +467,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun updateProduct(groupId: Int, product: Product): Response {
lateinit var response: Response
fun updateProduct(groupId: Int, product: Product, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -512,15 +494,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun synchronize(groupId: Int): Response {
lateinit var response: Response
fun synchronize(groupId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -531,51 +512,12 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun getProduct(groupId: Int, localId: Int): Response {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://$server/api/product/$groupId/$localId")
.get()
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
}
fun getAbstractProduct(groupId: Int, localId: Int): Response {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://$server/api/abstractproduct/$groupId/$localId")
.get()
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
}
fun downloadImage(url: String, file: File) {
thread {
fun downloadImage(url: String, file: File, callback: () -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
val client = OkHttpClient()
val request = Request.Builder()
.url(url)
@ -583,24 +525,24 @@ class Net {
.addHeader("accept-language", language)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
val response = client.newCall(request).execute()
if (!response.isSuccessful) throw IOException("Unexpected code $response")
val fos = FileOutputStream(file)
val fos = FileOutputStream(file)
response.body?.byteStream()?.use { inputStream ->
fos.use {
inputStream.copyTo(fos)
}
response.body?.byteStream()?.use { inputStream ->
fos.use {
inputStream.copyTo(fos)
}
}
}.join()
callback()
}
}
fun deleteCategory(groupId: Int, localId: Int): Response {
lateinit var response: Response
fun deleteCategory(groupId: Int, localId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -611,15 +553,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun deleteAbstractProduct(groupId: Int, localId: Int): Response {
lateinit var response: Response
fun deleteAbstractProduct(groupId: Int, localId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -630,15 +571,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun deleteProduct(groupId: Int, localId: Int): Response {
lateinit var response: Response
fun deleteProduct(groupId: Int, localId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -649,15 +589,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun renameGroup(groupId: Int, newName: String): Response {
lateinit var response: Response
fun renameGroup(groupId: Int, newName: String, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -672,15 +611,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun transfer_ownership(groupId: Int, userId: Int): Response {
lateinit var response: Response
fun transfer_ownership(groupId: Int, userId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
@ -695,15 +633,14 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
fun leaveGroup(groupId: Int): Response {
lateinit var response: Response
fun leaveGroup(groupId: Int, callback: (Response) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
@ -714,8 +651,7 @@ class Net {
.build()
response = client.newCall(request).execute()
}.join()
return response
callback(response)
}
}
}

View File

@ -117,29 +117,17 @@ fun calculateProductFreshness(dateOfProduction: Long, dateOfExpiry: Long): Doubl
fun getUnitNameById(context: Context, id: Int): String {
return when (id) {
0 -> {
context.getString(R.string.kilogram)
}
0 -> { context.getString(R.string.kilogram) }
1 -> {
context.getString(R.string.gram)
}
1 -> { context.getString(R.string.gram) }
2 -> {
context.getString(R.string.liter)
}
2 -> { context.getString(R.string.liter) }
3 -> {
context.getString(R.string.milliliter)
}
3 -> { context.getString(R.string.milliliter) }
4 -> {
context.getString(R.string.pieces)
}
4 -> { context.getString(R.string.pieces) }
else -> {
""
}
else -> { "" }
}
}
@ -200,6 +188,7 @@ fun noInternetConnectionAvailableNotification(context: Context) {
(context as Activity).runOnUiThread {
AlertDialog.Builder(context)
.setMessage(context.getString(R.string.no_internet_connection))
.setCancelable(false)
.setPositiveButton(R.string.quit) { _, _ ->
exitProcess(0)
}

View File

@ -20,8 +20,13 @@ import java.util.concurrent.TimeUnit
class WebSocketClient(private val context: Context, private val server: String) {
private lateinit var webSocket: WebSocket
private lateinit var token: String
private lateinit var currentGroup: String
fun connect(token: String, currentGroup: String) {
this.token = token
this.currentGroup = currentGroup
val client = OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.SECONDS)
.readTimeout(1, TimeUnit.MINUTES)
@ -70,9 +75,10 @@ class WebSocketClient(private val context: Context, private val server: String)
val pictureFile =
File(picturesDir, "${data["image_filename"]}.png")
val url = "https://${net.server}/api/abstractproduct/getImage/${currentGroup}/${data["local_id"]}"
net.downloadImage(url, pictureFile)
net.downloadImage(url, pictureFile, {
abstractProductDAO.addAbstractProduct(newAbstractProduct)
})
abstractProductDAO.addAbstractProduct(newAbstractProduct)
}
"product" -> {
@ -102,9 +108,10 @@ class WebSocketClient(private val context: Context, private val server: String)
val pictureFile =
File(picturesDir, "${data["image_filename"]}.png")
val url = "https://${net.server}/api/abstractproduct/getImage/${currentGroup}/${data["local_id"]}"
net.downloadImage(url, pictureFile)
net.downloadImage(url, pictureFile, {
abstractProductDAO.updateAbstractProduct(updatedAbstractProduct)
})
abstractProductDAO.updateAbstractProduct(updatedAbstractProduct)
}
"product" -> {
val updatedProduct = Product.createFromJSON(data)
@ -139,7 +146,8 @@ class WebSocketClient(private val context: Context, private val server: String)
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
Log.d("QWERTYUIOP", "Closing ws. Reason: $reason")
noInternetConnectionAvailableNotification(context)
// noInternetConnectionAvailableNotification(context)
this@WebSocketClient.connect(token, currentGroup)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {

View File

@ -28,27 +28,39 @@ class AccountSettingsActivity : AppCompatActivity() {
net.token = sharedPreferences.getString("token", "")!!
binding.saveUsernameButton.setOnClickListener {
val response = net.changeUsername(binding.newUsernameTextEdit.text.toString())
if (response.code == 200) {
Toast.makeText(this, getString(R.string.username_changed), Toast.LENGTH_LONG).show()
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
finish()
} else {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
}
net.changeUsername(binding.newUsernameTextEdit.text.toString(), { response ->
if (response.code == 200) {
runOnUiThread {
Toast.makeText(this, getString(R.string.username_changed), Toast.LENGTH_LONG).show()
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
finish()
}
} else {
runOnUiThread {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
}
}
})
}
binding.savePasswordButton.setOnClickListener {
val response = net.changePassword(binding.newPasswordTextEdit.text.toString())
if (response.code == 200) {
Toast.makeText(this, getString(R.string.password_changed), Toast.LENGTH_LONG).show()
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
finish()
} else {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
}
net.changePassword(binding.newPasswordTextEdit.text.toString(), { response ->
if (response.code == 200) {
runOnUiThread {
Toast.makeText(this, getString(R.string.password_changed), Toast.LENGTH_LONG).show()
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
finish()
}
} else {
runOnUiThread {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
}
}
})
}
}
}

View File

@ -1,5 +1,6 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.app.ProgressDialog
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
@ -30,7 +31,6 @@ import java.io.File
import java.io.FileOutputStream
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import kotlin.concurrent.thread
class AddAbstractProductActivity : AppCompatActivity() {
private lateinit var imageView: ImageView
@ -58,11 +58,18 @@ class AddAbstractProductActivity : AppCompatActivity() {
private lateinit var DAO: AbstractProductDAO
private lateinit var sharedPreferences: SharedPreferences
private lateinit var loadingDialog: ProgressDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_add_abstract_product)
loadingDialog = ProgressDialog(this)
loadingDialog.setMessage(getString(R.string.loading_please_wait))
loadingDialog.setCancelable(false)
loadingDialog.setTitle(getString(R.string.loading))
sharedPreferences = getPreferences(this)
val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "offline")!!)
@ -146,10 +153,12 @@ class AddAbstractProductActivity : AppCompatActivity() {
Toast.makeText(this, getString(R.string.product_net_weight_request), Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
loadingDialog.show()
val currentGroup: Int
val currentGroupString = sharedPreferences.getString("currentGroup", "offline")!!
lateinit var response: Response
val net = Net()
if (currentGroupString != "offline") {
@ -177,15 +186,12 @@ class AddAbstractProductActivity : AppCompatActivity() {
if (action == "update") {
DAO.updateAbstractProduct(abstractProduct!!)
if (currentGroup > 0) response = net.updateAbstractProduct(currentGroup, abstractProduct!!, pictureFile)
if (currentGroup > 0) net.updateAbstractProduct(currentGroup, abstractProduct!!, pictureFile, this::notifyUserAndExit)
} else if (action == "new" || action == "new_from_barcode") {
abstractProduct!!.id = DAO.addAbstractProduct(abstractProduct!!).toInt()
if (currentGroup > 0) response =
net.uploadAbstractProduct(currentGroup, abstractProduct!!, pictureFile)
if (currentGroup > 0)
net.uploadAbstractProduct(currentGroup, abstractProduct!!, pictureFile, this::notifyUserAndExit)
}
if (currentGroup > 0) Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
finish()
}
takePictureButton.setOnClickListener {
@ -198,10 +204,16 @@ class AddAbstractProductActivity : AppCompatActivity() {
}
}
fun notifyUserAndExit(response: Response) {
runOnUiThread {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
loadingDialog.dismiss()
finish()
}
}
fun performRequest(barcode: String) {
barcodeText.setText(this.barcode)
val net = Net();
val result = net.requestProductFromOnlineDB(barcode)
var abstractProduct: AbstractProduct
@ -223,24 +235,25 @@ class AddAbstractProductActivity : AppCompatActivity() {
}.show()
}
thread {
if (result == "Not found 404") {
val net = Net();
net.requestProductFromOnlineDB(barcode, {response ->
if (response.code == 404) {
runOnUiThread {
Toast.makeText(this, getString(R.string.no_product_in_online_database), Toast.LENGTH_LONG)
.show()
productNameText.setText("")
netWeightText.setText("")
}
return@thread
return@requestProductFromOnlineDB
}
abstractProduct = Parser().parse(result)
abstractProduct = Parser().parse(response.body!!.string())
runOnUiThread {
productNameText.text = abstractProduct.name
netWeightText.text = abstractProduct.netWeight.toString()
unitTypeSpinner.setSelection(abstractProduct.unit)
}
}
})
}
private fun fillupUnitsSpinner() {

View File

@ -1,11 +1,13 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.app.Activity
import android.app.ProgressDialog
import android.content.SharedPreferences
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import okhttp3.Response
import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.database.CategoryDAO
@ -16,12 +18,18 @@ class AddCategoryActivity : Activity() {
private lateinit var DAO: CategoryDAO
private lateinit var sharedPreferences: SharedPreferences
private lateinit var loadingDialog: ProgressDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_category)
loadingDialog = ProgressDialog(this)
loadingDialog.setMessage(getString(R.string.loading_please_wait))
loadingDialog.setCancelable(false)
loadingDialog.setTitle(getString(R.string.loading))
sharedPreferences = org.foxarmy.barcodescannerforemployees.getPreferences(this)
val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "offline")!!)
@ -40,25 +48,35 @@ class AddCategoryActivity : Activity() {
net.server = sharedPreferences.getString("server", "")!!
net.language = sharedPreferences.getString("language", "")!!
val currentGroup: Int = if (sharedPreferences.getString("currentGroup", "offline")!! == "offline") 0 else sharedPreferences.getString("currentGroup", "")!!.toInt()
val currentGroup: Int = if (sharedPreferences.getString(
"currentGroup",
"offline"
)!! == "offline"
) 0 else sharedPreferences.getString("currentGroup", "")!!.toInt()
findViewById<Button>(R.id.saveButton).setOnClickListener {
if (categoryNameTextEdit.text.toString() == "") {
Toast.makeText(this, getString(R.string.category_name_required), Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
loadingDialog.show()
if (category.id == 0) { // Inserting new category
val newCategory = Category(0, categoryNameTextEdit.text.toString())
newCategory.id = DAO.addCategory(newCategory).toInt()
if (currentGroup > 0) net.uploadCategory(currentGroup, newCategory)
if (currentGroup > 0) net.uploadCategory(currentGroup, newCategory, this::notifyUserAndExit)
} else { // Updating existing category
category.name = categoryNameTextEdit.text.toString()
DAO.updateCategory(category)
if (currentGroup > 0) net.updateCategory(currentGroup, category)
if (currentGroup > 0) net.updateCategory(currentGroup, category, this::notifyUserAndExit)
}
finish()
}
}
fun notifyUserAndExit(response: Response) {
runOnUiThread {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
loadingDialog.dismiss()
finish()
}
}

View File

@ -1,6 +1,7 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.app.Activity
import android.app.ProgressDialog
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
@ -54,11 +55,18 @@ class AddProductActivity : AppCompatActivity() {
private lateinit var abstractProductDAO: AbstractProductDAO
private lateinit var sharedPreferences: SharedPreferences
private lateinit var loadingDialog: ProgressDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_add_product)
loadingDialog = ProgressDialog(this)
loadingDialog.setMessage(getString(R.string.loading_please_wait))
loadingDialog.setCancelable(false)
loadingDialog.setTitle(getString(R.string.loading))
sharedPreferences = org.foxarmy.barcodescannerforemployees.getPreferences(this)
val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "offline")!!)
@ -169,23 +177,17 @@ class AddProductActivity : AppCompatActivity() {
return@setOnClickListener
}
val currentGroup: Int = if (sharedPreferences.getString("currentGroup", "offline")!! == "offline") 0 else sharedPreferences.getString("currentGroup", "")!!.toInt()
loadingDialog.show()
var response: Response? = null
val currentGroup: Int = if (sharedPreferences.getString("currentGroup", "offline")!! == "offline") 0 else sharedPreferences.getString("currentGroup", "")!!.toInt()
if (updatingExistentProduct) {
productDAO.updateProduct(product!!)
if (currentGroup > 0) response = net.updateProduct(currentGroup, product!!)
if (currentGroup > 0) net.updateProduct(currentGroup, product!!, this::notifyUserAndExit)
} else {
product!!.id = productDAO.insertNewProduct(product!!).toInt()
if (currentGroup > 0) response = net.uploadProduct(currentGroup, product!!)
if (currentGroup > 0) net.uploadProduct(currentGroup, product!!, this::notifyUserAndExit)
}
if (response != null) {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
}
finish()
}
update()
@ -199,6 +201,14 @@ class AddProductActivity : AppCompatActivity() {
}
fun notifyUserAndExit(response: Response) {
runOnUiThread {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
loadingDialog.dismiss()
finish()
}
}
private val intentLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {

View File

@ -1,10 +1,12 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.app.ProgressDialog
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.ActivityGroupBinding
import org.foxarmy.barcodescannerforemployees.noInternetConnectionAvailableNotification
@ -18,6 +20,11 @@ class GroupActivity : AppCompatActivity() {
binding = ActivityGroupBinding.inflate(layoutInflater)
setContentView(binding.root)
val loadingDialog = ProgressDialog(this)
loadingDialog.setMessage(getString(R.string.loading_please_wait))
loadingDialog.setCancelable(false)
loadingDialog.setTitle(getString(R.string.loading))
val sharedPreferences = org.foxarmy.barcodescannerforemployees.getPreferences(this)
binding.createGroupButton.setOnClickListener {
@ -28,24 +35,36 @@ class GroupActivity : AppCompatActivity() {
net.server = sharedPreferences.getString("server", "")!!
net.token = sharedPreferences.getString("token", "")!!
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val response = net.createGroup(groupName, groupPassword)
val responseText = response.body!!.string()
if (response.code == 200) {
val currentGroups = sharedPreferences.getStringSet("groups", mutableSetOf())
currentGroups!!.add(responseText)
sharedPreferences.edit().putStringSet("groups", currentGroups).apply()
sharedPreferences.edit().putString("currentGroup", responseText).apply()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
net.serverIsAvailable(this, { isServerAvailable ->
if (!isServerAvailable) {
noInternetConnectionAvailableNotification(this)
} else {
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
runOnUiThread {
loadingDialog.show()
}
net.createGroup(groupName, groupPassword, { response ->
val responseText = response.body!!.string()
if (response.code == 200) {
val currentGroups = sharedPreferences.getStringSet("groups", mutableSetOf())
currentGroups!!.add(responseText)
sharedPreferences.edit().putStringSet("groups", currentGroups).apply()
sharedPreferences.edit().putString("currentGroup", responseText).apply()
runOnUiThread {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
loadingDialog.dismiss()
finish()
}
} else {
runOnUiThread {
loadingDialog.dismiss()
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
}
}
})
}
}
})
}
binding.joinGroupButton.setOnClickListener {
@ -57,30 +76,46 @@ class GroupActivity : AppCompatActivity() {
net.server = sharedPreferences.getString("server", "")!!
net.token = sharedPreferences.getString("token", "")!!
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val requestGroupIdResponse = net.getGroupId(groupName)
var groupId: Int
try {
groupId = requestGroupIdResponse.toInt()
} catch (e: Exception) {
Toast.makeText(this, requestGroupIdResponse, Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val response = net.joinGroup(groupId, groupPassword)
val responseText = response.body!!.string()
if (response.code == 200) {
val currentGroups = sharedPreferences.getStringSet("groups", mutableSetOf())
currentGroups!!.add(groupId.toString())
sharedPreferences.edit().putStringSet("groups", currentGroups).apply()
sharedPreferences.edit().putString("currentGroup", groupId.toString()).apply()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
net.serverIsAvailable(this) { isServerAvailable ->
if (!isServerAvailable) {
noInternetConnectionAvailableNotification(this)
} else {
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
runOnUiThread {
loadingDialog.show()
}
net.getGroupId(groupName, { requestGroupIdResponse ->
var groupId: Int
try {
groupId = requestGroupIdResponse.toInt()
} catch (e: Exception) {
runOnUiThread {
loadingDialog.dismiss()
Toast.makeText(this, requestGroupIdResponse, Toast.LENGTH_SHORT).show()
}
return@getGroupId
}
net.joinGroup(groupId, groupPassword, { response ->
val responseText = response.body!!.string()
if (response.code == 200) {
val currentGroups = sharedPreferences.getStringSet("groups", mutableSetOf())
currentGroups!!.add(groupId.toString())
sharedPreferences.edit().putStringSet("groups", currentGroups).apply()
sharedPreferences.edit().putString("currentGroup", groupId.toString()).apply()
runOnUiThread {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
loadingDialog.dismiss()
finish()
}
} else {
runOnUiThread {
loadingDialog.dismiss()
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
}
}
})
})
}
}
}

View File

@ -1,5 +1,6 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.app.ProgressDialog
import android.content.Intent
import android.os.Bundle
import android.widget.ArrayAdapter
@ -22,6 +23,11 @@ class LoginActivity : AppCompatActivity() {
binding = ActivityLoginBinding.inflate(layoutInflater);
setContentView(binding.root)
val loadingDialog = ProgressDialog(this)
loadingDialog.setMessage(getString(R.string.loading_please_wait))
loadingDialog.setCancelable(false)
loadingDialog.setTitle(getString(R.string.loading))
fillUpLanguagesSpinner()
val sharedPreferences = org.foxarmy.barcodescannerforemployees.getPreferences(this)
@ -37,37 +43,45 @@ class LoginActivity : AppCompatActivity() {
net.language = sharedPreferences.getString("language", "en-US")!!
net.server = server
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val response = net.login(username, password)
val responseText = response.body!!.string()
if (response.code != 200) {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show()
net.serverIsAvailable(this, { isServerAvailable ->
if (!isServerAvailable) {
noInternetConnectionAvailableNotification(this)
} else {
val json = JSONObject(responseText)
sharedPreferences.edit().putString("token", json["token"].toString()).apply()
net.token = json["token"].toString()
sharedPreferences.edit().putInt("userId", json["id"].toString().toInt()).apply()
sharedPreferences.edit().putString("server", server).apply()
val r = net.getMyGroups().body!!.string()
if (r == "" || r == "[]") {
val intent = Intent(this, GroupActivity::class.java)
startActivity(intent)
finish()
runOnUiThread {
loadingDialog.show()
}
val myGroups = parseIntArray(r).map { a -> a.toString()}
net.login(username, password, { response ->
val responseText = response.body!!.string()
if (response.code != 200) {
runOnUiThread {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show()
}
} else {
val json = JSONObject(responseText)
sharedPreferences.edit().putString("token", json["token"].toString()).apply()
net.token = json["token"].toString()
sharedPreferences.edit().putInt("userId", json["id"].toString().toInt()).apply()
sharedPreferences.edit().putString("server", server).apply()
sharedPreferences.edit().putStringSet("groups", myGroups.toSet()).apply()
sharedPreferences.edit().putString("currentGroup", myGroups[0]).apply()
net.getMyGroups({ response ->
runOnUiThread {
loadingDialog.dismiss()
}
val r = response.body!!.string()
if (r == "" || r == "[]") {
goToActivity("GroupActivity")
}
val myGroups = parseIntArray(r).map { a -> a.toString() }
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
sharedPreferences.edit().putStringSet("groups", myGroups.toSet()).apply()
sharedPreferences.edit().putString("currentGroup", myGroups[0]).apply()
goToActivity("MainActivity")
})
}
})
}
}
})
}
binding.registerButton.setOnClickListener {
@ -82,24 +96,30 @@ class LoginActivity : AppCompatActivity() {
net.language = language
net.server = server
if (!net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else {
val response = net.registerAccount(username, password);
val responseText = response.body!!.string()
if (response.code != 200) {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show();
net.serverIsAvailable(this, {isServerAvailable ->
if (!isServerAvailable) {
noInternetConnectionAvailableNotification(this)
} else {
sharedPreferences.edit().putInt("userId", responseText.toInt()).apply()
val token = JSONObject(net.login(username, password).body!!.string())["token"].toString()
sharedPreferences.edit().putString("token", token).apply()
net.registerAccount(username, password, {response ->
val responseText = response.body!!.string()
if (response.code != 200) {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show();
} else {
sharedPreferences.edit().putInt("userId", responseText.toInt()).apply()
net.login(username, password, {response ->
val token = JSONObject(response.body!!.string())["token"].toString()
sharedPreferences.edit().putString("token", token).apply()
sharedPreferences.edit().putString("server", server).apply()
val intent = Intent(this, GroupActivity::class.java)
startActivity(intent)
finish()
sharedPreferences.edit().putString("server", server).apply()
runOnUiThread {
loadingDialog.dismiss()
}
goToActivity("GroupActivity")
})
}
})
}
}
})
}
binding.offlineButton.setOnClickListener {
@ -114,9 +134,22 @@ class LoginActivity : AppCompatActivity() {
private fun fillUpLanguagesSpinner() {
val languages = resources.getStringArray(R.array.languages)
val arrayAdapter = ArrayAdapter(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, languages)
val arrayAdapter =
ArrayAdapter(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, languages)
arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
binding.languageSpinner.adapter = arrayAdapter
}
private fun goToActivity(activityName: String) {
runOnUiThread {
val intent = Intent(this, when(activityName) {
"MainActivity" -> MainActivity::class.java
"GroupActivity" -> GroupActivity::class.java
"LoginActivity" -> LoginActivity::class.java
else -> LoginActivity::class.java
})
startActivity(intent)
finish()
}
}
}

View File

@ -1,6 +1,7 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.app.Activity
import android.app.ProgressDialog
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
@ -47,12 +48,19 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
private lateinit var sharedPreferences: SharedPreferences
private lateinit var loadingDialog: ProgressDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
loadingDialog = ProgressDialog(this)
loadingDialog.setMessage(getString(R.string.loading_please_wait))
loadingDialog.setCancelable(false)
loadingDialog.setTitle(getString(R.string.loading))
sharedPreferences = getPreferences(this)
setSupportActionBar(binding.toolbar)
@ -116,14 +124,18 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
val net = Net()
net.server = sharedPreferences.getString("server", "")!!
val currentGroup = sharedPreferences.getString("currentGroup", "offline")!!
if ( currentGroup != "offline" && !net.serverIsAvailable(this)) {
noInternetConnectionAvailableNotification(this)
} else if (currentGroup != "offline" && net.serverIsAvailable(this)) {
synchronize()
ws = WebSocketClient(this, sharedPreferences.getString("server", "")!!)
val token = sharedPreferences.getString("token", "")!!
ws.connect(token, currentGroup)
}
net.serverIsAvailable(this, {isServerAvailable ->
if ( currentGroup != "offline" && !isServerAvailable) {
runOnUiThread {
noInternetConnectionAvailableNotification(this)
}
} else if (currentGroup != "offline" && isServerAvailable) {
synchronize()
ws = WebSocketClient(this, sharedPreferences.getString("server", "")!!)
val token = sharedPreferences.getString("token", "")!!
ws.connect(token, currentGroup)
}
})
}
private fun synchronize() {
@ -137,26 +149,27 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
val currentGroup = sharedPreferences.getString("currentGroup", "")!!.toInt()
val data = JSONObject(net.synchronize(currentGroup).body!!.string())
net.synchronize(currentGroup, {response ->
val data = JSONObject(response.body!!.string())
val remoteAbstractProducts = data["abstract_products"] as JSONArray
val remoteProducts = data["products"] as JSONArray
val remoteCategories = data["categories"] as JSONArray
val remoteAbstractProducts = data["abstract_products"] as JSONArray
val remoteProducts = data["products"] as JSONArray
val remoteCategories = data["categories"] as JSONArray
val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "")!!)
val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "")!!)
val abstractProductDAO = AbstractProductDAO(dbHelper)
val productDAO = ProductDAO(dbHelper)
val categoryDAO = CategoryDAO(dbHelper)
val abstractProductDAO = AbstractProductDAO(dbHelper)
val productDAO = ProductDAO(dbHelper)
val categoryDAO = CategoryDAO(dbHelper)
val localAbstractProducts = abstractProductDAO.getSortedListOfAbstractProducts(0, "", arrayOf(""))
val localProducts = productDAO.getSortedListOfProducts(0, "", "")
val localCategories = categoryDAO.getAllCategories()
syncAbstractProducts(net, currentGroup, abstractProductDAO, remoteAbstractProducts, localAbstractProducts)
syncProducts(productDAO, remoteProducts, localProducts)
syncCategories(categoryDAO, remoteCategories, localCategories)
val localAbstractProducts = abstractProductDAO.getSortedListOfAbstractProducts(0, "", arrayOf(""))
val localProducts = productDAO.getSortedListOfProducts(0, "", "")
val localCategories = categoryDAO.getAllCategories()
syncAbstractProducts(net, currentGroup, abstractProductDAO, remoteAbstractProducts, localAbstractProducts)
syncProducts(productDAO, remoteProducts, localProducts)
syncCategories(categoryDAO, remoteCategories, localCategories)
})
}
private fun syncCategories(
@ -299,12 +312,11 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
val pictureFile =
File(picturesDir, "${remoteAbstractProduct["image_filename"]}.png")
val url = "https://${net.server}/api/abstractproduct/getImage/${currentGroup}/${localId}"
net.downloadImage(url, pictureFile)
val newAbstractProduct = AbstractProduct.createFromJSON(remoteAbstractProduct)
abstractProductDAO.addAbstractProduct(newAbstractProduct)
net.downloadImage(url, pictureFile, {
val newAbstractProduct = AbstractProduct.createFromJSON(remoteAbstractProduct)
abstractProductDAO.addAbstractProduct(newAbstractProduct)
})
}
if (abstractProductInRemoteDB != null && abstractProductInLocalDB != null) {
@ -314,11 +326,11 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
val pictureFile =
File(File(filesDir, "pictures"), "${abstractProductInRemoteDB["image_filename"]}.png")
val url = "https://${net.server}/api/abstractproduct/getImage/${currentGroup}/${localId}"
net.downloadImage(url, pictureFile)
net.downloadImage(url, pictureFile, {
val updatedData = AbstractProduct.createFromJSON(abstractProductInRemoteDB)
val updatedData = AbstractProduct.createFromJSON(abstractProductInRemoteDB)
abstractProductDAO.updateAbstractProduct(updatedData)
abstractProductDAO.updateAbstractProduct(updatedData)
})
}
}
}

View File

@ -10,14 +10,13 @@ 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.parseIntArray
import org.foxarmy.barcodescannerforemployees.views.GroupMemberView
class ManageGroupActivity : AppCompatActivity(){
class ManageGroupActivity : AppCompatActivity() {
private lateinit var binding: ActivityManageGroupBinding
private var isAdmin: Boolean = false
private lateinit var sharedPreferences: SharedPreferences
@ -48,94 +47,128 @@ class ManageGroupActivity : AppCompatActivity(){
AlertDialog.Builder(this)
.setTitle(getString(R.string.new_group_name))
.setView(input)
.setPositiveButton(getString(R.string.ok)) { _, _, ->
.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()
net.renameGroup(groupId, newName, { response ->
runOnUiThread {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
}
})
}
.setNegativeButton(getString(R.string.cancel)) {_, _, ->
.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()
net.leaveGroup(groupId, { response ->
runOnUiThread {
Toast.makeText(this, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
sharedPreferences.edit().putString("currentGroup", groups.toList()[0]).apply()
finish()
}
if (response.code == 200) {
val groups = sharedPreferences.getStringSet("groups", emptySet())!!
groups.remove(groupId.toString())
if (groups.isEmpty()) {
sharedPreferences.edit().putStringSet("groups", groups).apply()
runOnUiThread {
val intent = Intent(this, GroupActivity::class.java)
startActivity(intent)
finish()
}
}
sharedPreferences.edit().putString("currentGroup", groups.toList()[0]).apply()
runOnUiThread {
finish()
}
}
})
}
setUpAdminRelatedButtons()
}
private fun setUpMembers() {
val users = parseIntArray(net.getUsersInGroup(groupId).body!!.string())
net.getUsersInGroup(groupId, { response ->
val users = parseIntArray(response.body!!.string())
for (user in users) {
net.getUsernameById(user, { response ->
val groupMemberView = GroupMemberView(this, this as Context, response.body!!.string(), user)
for (user in users) {
val groupMemberView = GroupMemberView(this, this as Context, net.getUsernameById(user).body!!.string(), user)
groupMemberView.setOnLongClickListener { view ->
amIAnAdminIn(groupId, {amIAnAdmin ->
if (!amIAnAdmin) return@amIAnAdminIn
runOnUiThread {
val popupMenu = PopupMenu(this, groupMemberView)
popupMenu.inflate(R.menu.user_pop_menu)
popupMenu.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.kick -> {
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) { _, _ ->
net.transfer_ownership(
groupId,
(view as GroupMemberView).userId,
{ response ->
runOnUiThread {
Toast.makeText(
this,
response.body!!.string(),
Toast.LENGTH_SHORT
).show()
setUpAdminRelatedButtons()
}
})
}
.setNegativeButton(R.string.no) { _, _ -> }
.show()
true
}
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()
else -> false
}
}
.setNegativeButton(R.string.no) { _, _, -> }
.show()
true
}
else -> false
runOnUiThread {
popupMenu.show()
}
}
})
true
}
}
popupMenu.show()
true
runOnUiThread {
binding.groupsContent.addView(groupMemberView)
}
})
}
binding.groupsContent.addView(groupMemberView)
}
})
}
fun amIAnAdminIn(groupId: Int): Boolean {
fun amIAnAdminIn(groupId: Int, callback: (Boolean) -> Unit) {
val net = Net()
net.token = sharedPreferences.getString("token", "")!!
net.server = sharedPreferences.getString("server", "")!!
net.language = sharedPreferences.getString("language", "en-US")!!
val result = sharedPreferences.getInt("userId", 0) == net.getGroupAdminId(groupId).body!!.string().toInt()
return result
net.getGroupAdminId(groupId, { response ->
val result = sharedPreferences.getInt("userId", 0) == response.body!!.string().toInt()
callback(result)
})
}
fun setUpAdminRelatedButtons() {
isAdmin = amIAnAdminIn(groupId)
if (!isAdmin) {
binding.renameButton.visibility = View.GONE
}
amIAnAdminIn(groupId, {isAdmin ->
if (!isAdmin) {
binding.renameButton.visibility = View.GONE
}
})
}
}

View File

@ -28,20 +28,28 @@ class MyGroupsActivity : AppCompatActivity(){
net.server = sharedPreferences.getString("server", "")!!
net.language = sharedPreferences.getString("language", "en-US")!!
val groups = parseIntArray(net.getMyGroups().body!!.string())
val container = findViewById<LinearLayout>(R.id.groupsLayout)
for (group in groups) {
val groupView = GroupView(this, this as Context, net.getGroupName(group), group)
net.getMyGroups { response ->
val groups = parseIntArray(response.body!!.string())
container.addView(groupView)
}
val container = findViewById<LinearLayout>(R.id.groupsLayout)
binding.newGroup.setOnClickListener {
val intent = Intent(this, GroupActivity::class.java)
startActivity(intent)
for (group in groups) {
net.getGroupName(group, {response ->
val groupView = GroupView(this, this as Context, response, group)
runOnUiThread {
container.addView(groupView)
}
})
}
binding.newGroup.setOnClickListener {
runOnUiThread {
val intent = Intent(this, GroupActivity::class.java)
startActivity(intent)
}
}
}
}
}

View File

@ -18,16 +18,19 @@ class NavigatorActivity : Activity() {
var intent = Intent(this, MainActivity::class.java)
if (!isInGroup() && !isOffline()) {
intent = Intent(this, GroupActivity::class.java)
}
isInGroup { flag ->
if (!flag && !isOffline()) {
intent = Intent(this, GroupActivity::class.java)
}
if (!isAuthenticated() && !isOffline()) {
intent = Intent(this, LoginActivity::class.java);
}
if (!isAuthenticated() && !isOffline()) {
intent = Intent(this, LoginActivity::class.java);
runOnUiThread {
startActivity(intent);
finish();
}
}
startActivity(intent);
finish();
}
private fun isOffline(): Boolean {
@ -38,26 +41,28 @@ class NavigatorActivity : Activity() {
return sharedPreferences.getString("token", "") != ""
}
private fun isInGroup(): Boolean {
private fun isInGroup(callback: (Boolean) -> Unit) {
val groups = sharedPreferences.getStringSet("groups", emptySet())!!
if (groups.isEmpty()) {
if(sharedPreferences.getString("token", "")!! == "") return false
if (sharedPreferences.getString("token", "")!! == "") callback(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
net.getMyGroups { response ->
val responseBody = response.body!!.string()
if (responseBody == "" || responseBody == "[]") callback(false)
val groupsFromServer = parseStringList(responseBody)
if (groupsFromServer.isNotEmpty()) {
sharedPreferences.edit().putStringSet("groups", groupsFromServer.toSet()).apply()
sharedPreferences.edit().putString("currentGroup", groupsFromServer[0]).apply()
callback(true)
} else {
callback(false)
}
}
}
return true
callback(true)
}
}

View File

@ -15,6 +15,7 @@ class SettingsActivity : AppCompatActivity() {
lateinit var myGroups: List<String>
lateinit var currentGroup: String
lateinit var groupsNames: MutableList<String>
lateinit var namesMap: MutableMap<Int, String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -38,20 +39,26 @@ class SettingsActivity : AppCompatActivity() {
if (isOffline()) {
binding.currentGroupSetting.visibility = View.GONE
} else {
groupsNames = mutableListOf()
namesMap = mutableMapOf()
for (myGroup in myGroups) {
groupsNames.add(net.getGroupName(myGroup.toInt()))
net.getGroupName(myGroup.toInt(), { name ->
namesMap[myGroup.toInt()] = name
fillUpCurrentGroupSpinner()
})
}
fillUpCurrentGroupSpinner()
}
binding.saveButton.setOnClickListener {
sharedPreferences.edit().putString("currentGroup", net.getGroupId(binding.currentGroupSpinner.selectedItem.toString())).apply()
sharedPreferences.edit().putInt("imageCompression", binding.imageCompressionFactorSeekBar.progress + 1).apply()
setResult(Activity.RESULT_OK)
finish()
net.getGroupId(binding.currentGroupSpinner.selectedItem.toString(), { groupId ->
sharedPreferences.edit().putString("currentGroup", groupId).apply()
sharedPreferences.edit().putInt("imageCompression", binding.imageCompressionFactorSeekBar.progress + 1)
.apply()
runOnUiThread {
setResult(Activity.RESULT_OK)
finish()
}
})
}
binding.cancelButton.setOnClickListener {
@ -70,14 +77,27 @@ class SettingsActivity : AppCompatActivity() {
}
private fun fillUpCurrentGroupSpinner() {
if (currentGroup == "offline") {
binding.currentGroupSetting.visibility = View.GONE
runOnUiThread {
if (currentGroup == "offline") {
binding.currentGroupSetting.visibility = View.GONE
}
groupsNames = mutableListOf()
groupsNames.clear()
val sortedMap = namesMap.entries.sortedBy { it.key }.associate { it.toPair() }
for ((id, name) in sortedMap) {
groupsNames.add(name)
}
val arrayAdapter =
ArrayAdapter(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, groupsNames)
arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
binding.currentGroupSpinner.adapter = arrayAdapter
if (myGroups.indexOf(currentGroup) < groupsNames.size) binding.currentGroupSpinner.setSelection(
myGroups.indexOf(
currentGroup
)
)
}
val arrayAdapter =
ArrayAdapter(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, groupsNames)
arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
binding.currentGroupSpinner.adapter = arrayAdapter
binding.currentGroupSpinner.setSelection(myGroups.indexOf(currentGroup))
}
}

View File

@ -66,11 +66,12 @@ class CategoriesFragment : Fragment() {
val currentGroup = sharedPreferences.getString("currentGroup", "")!!.toInt()
categoryDAO.eraseCategory(view.category.id, requireContext())
val response = net.deleteCategory(currentGroup, view.category.id)
activity!!.runOnUiThread{
Toast.makeText(context, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
net.deleteCategory(currentGroup, view.category.id, {response ->
activity!!.runOnUiThread{
Toast.makeText(context, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
})
deleted = true
}
}

View File

@ -157,10 +157,11 @@ class ShelfFragment : Fragment() {
val currentGroup = sharedPreferences.getString("currentGroup", "")!!.toInt()
productDAO.eraseProduct(view.product.id)
val response = net.deleteProduct(currentGroup, view.product.id)
activity!!.runOnUiThread{
Toast.makeText(context, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
net.deleteProduct(currentGroup, view.product.id, {response ->
activity!!.runOnUiThread{
Toast.makeText(context, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
})
deleted = true
}

View File

@ -102,10 +102,12 @@ class StorageFragment : Fragment() {
val currentGroup = sharedPreferences.getString("currentGroup", "")!!.toInt()
abstractProductDAO.eraseAbstractProduct(view.abstractProduct.id, requireContext())
val response = net.deleteAbstractProduct(currentGroup, view.abstractProduct.id)
activity!!.runOnUiThread{
Toast.makeText(context, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
net.deleteAbstractProduct(currentGroup, view.abstractProduct.id, {response ->
activity!!.runOnUiThread{
Toast.makeText(context, response.body!!.string(), Toast.LENGTH_SHORT).show()
}
})
deleted = true
}

View File

@ -223,21 +223,23 @@ class ProductView : LinearLayout {
@RequiresApi(Build.VERSION_CODES.O)
fun updateStroke() {
if (isProductSelected) {
this.background = ContextCompat.getDrawable(context, R.drawable.outline_selected)
} else {
if (product.id != 0) {
thread {
this.outline = GradientDrawable()
backgroundColor = evaluateColor()
strokeColor = darkenColor(backgroundColor, 0.25) // (backgroundColor and 0xfefefe ) shr 1
this.outline.setColor(backgroundColor)
this.outline.setStroke(4, strokeColor)
this.outline.alpha = 84
this.background = outline
}
activity.runOnUiThread {
if (isProductSelected) {
this.background = ContextCompat.getDrawable(context, R.drawable.outline_selected)
} else {
this.background = ContextCompat.getDrawable(context, R.drawable.outline)
if (product.id != 0) {
thread {
this.outline = GradientDrawable()
backgroundColor = evaluateColor()
strokeColor = darkenColor(backgroundColor, 0.25) // (backgroundColor and 0xfefefe ) shr 1
this.outline.setColor(backgroundColor)
this.outline.setStroke(4, strokeColor)
this.outline.alpha = 84
this.background = outline
}
} else {
this.background = ContextCompat.getDrawable(context, R.drawable.outline)
}
}
}
}

View File

@ -126,6 +126,8 @@
<string name="transfer_ownership_confirmation">Are you sure you want to transfer ownership on current group to that
user?
</string>
<string name="loading_please_wait">Loading, please wait</string>
<string name="loading">Loading</string>
<string-array name="languages">
<item>en-US</item>
<item>ru-RU</item>

View File

@ -124,6 +124,8 @@
<string name="transfer_ownership_confirmation">Are you sure you want to transfer ownership on current group to that
user?
</string>
<string name="loading_please_wait">Loading, please wait</string>
<string name="loading">Loading</string>
<string-array name="languages">
<item>en-US</item>
<item>ru-RU</item>