Мимо собственного кода
Я без шуток не хожу - То комменты не коммичу, То весь класс перепишу Кволити - не кволити, Хуй меня уволите
This commit is contained in:
		@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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?) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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() {
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        })
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -157,11 +157,12 @@ 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
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user