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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package org.foxarmy.barcodescannerforemployees.activities package org.foxarmy.barcodescannerforemployees.activities
import android.app.Activity import android.app.Activity
import android.app.ProgressDialog
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build import android.os.Build
@ -54,11 +55,18 @@ class AddProductActivity : AppCompatActivity() {
private lateinit var abstractProductDAO: AbstractProductDAO private lateinit var abstractProductDAO: AbstractProductDAO
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private lateinit var loadingDialog: ProgressDialog
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_add_product) 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) sharedPreferences = org.foxarmy.barcodescannerforemployees.getPreferences(this)
val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "offline")!!) val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "offline")!!)
@ -169,23 +177,17 @@ class AddProductActivity : AppCompatActivity() {
return@setOnClickListener 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) { if (updatingExistentProduct) {
productDAO.updateProduct(product!!) productDAO.updateProduct(product!!)
if (currentGroup > 0) response = net.updateProduct(currentGroup, product!!) if (currentGroup > 0) net.updateProduct(currentGroup, product!!, this::notifyUserAndExit)
} else { } else {
product!!.id = productDAO.insertNewProduct(product!!).toInt() 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() 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 = private val intentLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) { if (result.resultCode == Activity.RESULT_OK) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -223,6 +223,7 @@ class ProductView : LinearLayout {
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
fun updateStroke() { fun updateStroke() {
activity.runOnUiThread {
if (isProductSelected) { if (isProductSelected) {
this.background = ContextCompat.getDrawable(context, R.drawable.outline_selected) this.background = ContextCompat.getDrawable(context, R.drawable.outline_selected)
} else { } else {
@ -241,6 +242,7 @@ class ProductView : LinearLayout {
} }
} }
} }
}
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
fun evaluateColor(): Int { fun evaluateColor(): Int {

View File

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

View File

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