fixed websockets, synchronization works properly, and a bunch of bugfixes
This commit is contained in:
		@@ -2,8 +2,10 @@ package org.foxarmy.barcodescannerforemployees
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import android.content.Context
 | 
					import android.content.Context
 | 
				
			||||||
import android.os.Build
 | 
					import android.os.Build
 | 
				
			||||||
 | 
					import android.util.Log
 | 
				
			||||||
import androidx.annotation.RequiresApi
 | 
					import androidx.annotation.RequiresApi
 | 
				
			||||||
import okhttp3.*
 | 
					import okhttp3.*
 | 
				
			||||||
 | 
					import org.foxarmy.barcodescannerforemployees.activities.MainActivity
 | 
				
			||||||
import org.foxarmy.barcodescannerforemployees.database.AbstractProductDAO
 | 
					import org.foxarmy.barcodescannerforemployees.database.AbstractProductDAO
 | 
				
			||||||
import org.foxarmy.barcodescannerforemployees.database.CategoryDAO
 | 
					import org.foxarmy.barcodescannerforemployees.database.CategoryDAO
 | 
				
			||||||
import org.foxarmy.barcodescannerforemployees.database.DBStorageController
 | 
					import org.foxarmy.barcodescannerforemployees.database.DBStorageController
 | 
				
			||||||
@@ -12,18 +14,30 @@ import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
 | 
				
			|||||||
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
 | 
					import org.foxarmy.barcodescannerforemployees.dataclasses.Category
 | 
				
			||||||
import org.foxarmy.barcodescannerforemployees.dataclasses.Product
 | 
					import org.foxarmy.barcodescannerforemployees.dataclasses.Product
 | 
				
			||||||
import org.json.JSONObject
 | 
					import org.json.JSONObject
 | 
				
			||||||
 | 
					import java.io.File
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun connect(token: String, currentGroup: String) {
 | 
					    fun connect(token: String, currentGroup: String) {
 | 
				
			||||||
        val client = OkHttpClient()
 | 
					        val client = OkHttpClient.Builder()
 | 
				
			||||||
        val request = Request.Builder().url("ws://$server:8282").build()
 | 
					            .connectTimeout(5, TimeUnit.SECONDS)
 | 
				
			||||||
 | 
					            .readTimeout(1, TimeUnit.MINUTES)
 | 
				
			||||||
 | 
					            .writeTimeout(10, TimeUnit.SECONDS)
 | 
				
			||||||
 | 
					            .callTimeout(1, TimeUnit.MINUTES)
 | 
				
			||||||
 | 
					            .build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        val request = Request.Builder()
 | 
				
			||||||
 | 
					            .url("wss://$server")
 | 
				
			||||||
 | 
					            .build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        client.newWebSocket(request, object : WebSocketListener() {
 | 
					        client.newWebSocket(request, object : WebSocketListener() {
 | 
				
			||||||
            override fun onOpen(webSocket: WebSocket, response: Response) {
 | 
					            override fun onOpen(webSocket: WebSocket, response: Response) {
 | 
				
			||||||
                this@WebSocketClient.webSocket = webSocket
 | 
					                this@WebSocketClient.webSocket = webSocket
 | 
				
			||||||
                sendMessage("\"token\":\"$token\",\"currentGroup\":\"$currentGroup\"")
 | 
					                sendMessage("{\"token\":\"$token\",\"currentGroup\":\"$currentGroup\"}")
 | 
				
			||||||
 | 
					                keepAlive()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            @RequiresApi(Build.VERSION_CODES.O)
 | 
					            @RequiresApi(Build.VERSION_CODES.O)
 | 
				
			||||||
@@ -45,6 +59,19 @@ class WebSocketClient(private val context: Context, private val server: String)
 | 
				
			|||||||
                        when (item) {
 | 
					                        when (item) {
 | 
				
			||||||
                            "abstractproduct" -> {
 | 
					                            "abstractproduct" -> {
 | 
				
			||||||
                                val newAbstractProduct = AbstractProduct.createFromJSON(data)
 | 
					                                val newAbstractProduct = AbstractProduct.createFromJSON(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                val net = Net()
 | 
				
			||||||
 | 
					                                net.server = server
 | 
				
			||||||
 | 
					                                net.token = token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                val picturesDir = File(context.filesDir, "pictures")
 | 
				
			||||||
 | 
					                                picturesDir.mkdirs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                val pictureFile =
 | 
				
			||||||
 | 
					                                    File(picturesDir, "${data["image_filename"]}.png")
 | 
				
			||||||
 | 
					                                val url = "https://${net.server}/api/abstractproduct/getImage/${currentGroup}/${data["local_id"]}"
 | 
				
			||||||
 | 
					                                net.downloadImage(url, pictureFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                abstractProductDAO.addAbstractProduct(newAbstractProduct)
 | 
					                                abstractProductDAO.addAbstractProduct(newAbstractProduct)
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,6 +91,19 @@ class WebSocketClient(private val context: Context, private val server: String)
 | 
				
			|||||||
                        when (item) {
 | 
					                        when (item) {
 | 
				
			||||||
                            "abstractproduct" -> {
 | 
					                            "abstractproduct" -> {
 | 
				
			||||||
                                val updatedAbstractProduct = AbstractProduct.createFromJSON(data)
 | 
					                                val updatedAbstractProduct = AbstractProduct.createFromJSON(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                val net = Net()
 | 
				
			||||||
 | 
					                                net.server = server
 | 
				
			||||||
 | 
					                                net.token = token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                val picturesDir = File(context.filesDir, "pictures")
 | 
				
			||||||
 | 
					                                picturesDir.mkdirs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                val pictureFile =
 | 
				
			||||||
 | 
					                                    File(picturesDir, "${data["image_filename"]}.png")
 | 
				
			||||||
 | 
					                                val url = "https://${net.server}/api/abstractproduct/getImage/${currentGroup}/${data["local_id"]}"
 | 
				
			||||||
 | 
					                                net.downloadImage(url, pictureFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                abstractProductDAO.updateAbstractProduct(updatedAbstractProduct)
 | 
					                                abstractProductDAO.updateAbstractProduct(updatedAbstractProduct)
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            "product" -> {
 | 
					                            "product" -> {
 | 
				
			||||||
@@ -78,31 +118,44 @@ class WebSocketClient(private val context: Context, private val server: String)
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    "delete" -> {
 | 
					                    "delete" -> {
 | 
				
			||||||
                        val id = data["local_id"] as Int
 | 
					                        val id = data["local_id"] as String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        when(item) {
 | 
					                        when(item) {
 | 
				
			||||||
                            "abstractproduct" -> {
 | 
					                            "abstractproduct" -> {
 | 
				
			||||||
                                abstractProductDAO.eraseAbstractProduct(id, context)
 | 
					                                abstractProductDAO.eraseAbstractProduct(id.toInt(), context)
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            "product" -> {
 | 
					                            "product" -> {
 | 
				
			||||||
                                productDAO.eraseProduct(id)
 | 
					                                productDAO.eraseProduct(id.toInt())
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            "category" -> {
 | 
					                            "category" -> {
 | 
				
			||||||
                                categoryDAO.eraseCategory(id, context)
 | 
					                                categoryDAO.eraseCategory(id.toInt(), context)
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                (context as MainActivity).updateAll()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            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")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
 | 
					            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
 | 
				
			||||||
 | 
					                Log.d("QWERTYUIOP","Connection failed: ${t.message}")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun keepAlive() {
 | 
				
			||||||
 | 
					        Thread {
 | 
				
			||||||
 | 
					            while (true) {
 | 
				
			||||||
 | 
					                Thread.sleep(30000)
 | 
				
			||||||
 | 
					                webSocket.send("keepalive")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }.start()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun sendMessage(message: String) {
 | 
					    fun sendMessage(message: String) {
 | 
				
			||||||
        webSocket.send(message)
 | 
					        webSocket.send(message)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,7 +73,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
				
			|||||||
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
					            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "database")!!)
 | 
					        val dbHelper = DBStorageController(this, sharedPreferences.getString("currentGroup", "offline")!!)
 | 
				
			||||||
        DAO = AbstractProductDAO(dbHelper)
 | 
					        DAO = AbstractProductDAO(dbHelper)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        picturesPath = File(filesDir, "pictures")
 | 
					        picturesPath = File(filesDir, "pictures")
 | 
				
			||||||
@@ -109,24 +109,24 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
				
			|||||||
        action = extras!!.get("action") as String
 | 
					        action = extras!!.get("action") as String
 | 
				
			||||||
        when (action) {
 | 
					        when (action) {
 | 
				
			||||||
            "update" -> {
 | 
					            "update" -> {
 | 
				
			||||||
                abstractProduct = extras.get("abstractProduct") as AbstractProduct?
 | 
					                abstractProduct = extras.get("abstractProduct") as AbstractProduct
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "new_from_barcode" -> {
 | 
					            "new_from_barcode" -> {
 | 
				
			||||||
                abstractProduct = extras.get("abstractProduct") as AbstractProduct?
 | 
					                abstractProduct = extras.get("abstractProduct") as AbstractProduct
 | 
				
			||||||
                barcode = abstractProduct!!.barcode
 | 
					                barcode = abstractProduct!!.barcode
 | 
				
			||||||
                performRequest(abstractProduct!!.barcode)
 | 
					                performRequest(abstractProduct!!.barcode)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (abstractProduct != null) {
 | 
					        if (abstractProduct != null && action == "update") {
 | 
				
			||||||
            val imageThumbnailUri = getImageUri(this, File(thumbnailsDir, "${abstractProduct!!.imageHash}.webp"))
 | 
					            val imageThumbnailUri = getImageUri(this, File(thumbnailsDir, "${abstractProduct!!.imageHash}.webp"))
 | 
				
			||||||
            pictureFile = File(picturesPath, "${abstractProduct!!.imageHash}.png]")
 | 
					            pictureFile = File(picturesPath, "${abstractProduct!!.imageHash}.png")
 | 
				
			||||||
            imageView.setImageURI(imageThumbnailUri)
 | 
					            imageView.setImageURI(imageThumbnailUri)
 | 
				
			||||||
            barcodeText.setText(abstractProduct!!.barcode)
 | 
					            barcodeText.setText(abstractProduct!!.barcode)
 | 
				
			||||||
            productNameText.text = abstractProduct!!.name
 | 
					            productNameText.text = abstractProduct!!.name
 | 
				
			||||||
            netWeightText.text = abstractProduct!!.netWeight.toString()
 | 
					            netWeightText.text = abstractProduct!!.netWeight.toString()
 | 
				
			||||||
            categorySpinner.setSelection(abstractProduct!!.category)
 | 
					            categorySpinner.setSelection(abstractProduct!!.category - 1)
 | 
				
			||||||
            unitTypeSpinner.setSelection(abstractProduct!!.unit)
 | 
					            unitTypeSpinner.setSelection(abstractProduct!!.unit)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -149,6 +149,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            if (netWeight.toString() == "" || netWeight.toString().toDoubleOrNull() == null) {
 | 
					            if (netWeight.toString() == "" || netWeight.toString().toDoubleOrNull() == null) {
 | 
				
			||||||
                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
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            val net = Net()
 | 
					            val net = Net()
 | 
				
			||||||
@@ -157,7 +158,7 @@ class AddAbstractProductActivity : 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 currentGroup = sharedPreferences.getString("currentGroup", "offline")!!
 | 
					            val currentGroup: Int = if (sharedPreferences.getString("currentGroup", "offline")!! == "offline") 0 else sharedPreferences.getString("currentGroup", "")!!.toInt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            lateinit var response: Response
 | 
					            lateinit var response: Response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -174,10 +175,10 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (action == "update") {
 | 
					            if (action == "update") {
 | 
				
			||||||
                DAO.updateAbstractProduct(abstractProduct!!)
 | 
					                DAO.updateAbstractProduct(abstractProduct!!)
 | 
				
			||||||
                response = net.updateAbstractProduct(currentGroup.toInt(), abstractProduct!!, pictureFile)
 | 
					                response = net.updateAbstractProduct(currentGroup, abstractProduct!!, pictureFile)
 | 
				
			||||||
            } 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()
 | 
				
			||||||
                response = net.uploadAbstractProduct(currentGroup.toInt(), abstractProduct!!, pictureFile);
 | 
					                response = net.uploadAbstractProduct(currentGroup, abstractProduct!!, pictureFile);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
 | 
					            Toast.makeText(this, response.body!!.string(), Toast.LENGTH_LONG).show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -198,7 +199,6 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
				
			|||||||
        barcodeText.setText(this.barcode)
 | 
					        barcodeText.setText(this.barcode)
 | 
				
			||||||
        val net = Net();
 | 
					        val net = Net();
 | 
				
			||||||
        val result = net.requestProductFromOnlineDB(barcode)
 | 
					        val result = net.requestProductFromOnlineDB(barcode)
 | 
				
			||||||
        Log.d("QWERTYUIOP", "Result of request: $result")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var abstractProduct: AbstractProduct
 | 
					        var abstractProduct: AbstractProduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -272,18 +272,11 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
				
			|||||||
        if (success) {
 | 
					        if (success) {
 | 
				
			||||||
            //Move picture to a proper directory according to its calculated hash
 | 
					            //Move picture to a proper directory according to its calculated hash
 | 
				
			||||||
            val tempfile = File(filesDir, "image.png")
 | 
					            val tempfile = File(filesDir, "image.png")
 | 
				
			||||||
            val imageHash = calculateMd5Hash(tempfile)
 | 
					 | 
				
			||||||
//            val imageContent = tempfile.inputStream().readBytes()
 | 
					 | 
				
			||||||
//            val imageHash = imageContent.toString(Charsets.UTF_8).md5()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            pictureFile = File(picturesPath, "$imageHash.png")
 | 
					            val imageContent = tempfile.inputStream().readBytes()
 | 
				
			||||||
            Files.move(tempfile.toPath(), pictureFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
 | 
					 | 
				
			||||||
            tempfile.delete()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            val imageContent = pictureFile.inputStream().readBytes()
 | 
					 | 
				
			||||||
            var img = BitmapFactory.decodeByteArray(imageContent, 0, imageContent.size)
 | 
					            var img = BitmapFactory.decodeByteArray(imageContent, 0, imageContent.size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            val exif = ExifInterface(pictureFile.absoluteFile.toString())
 | 
					            val exif = ExifInterface(tempfile.absoluteFile.toString())
 | 
				
			||||||
            val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
 | 
					            val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
 | 
				
			||||||
            val matrix = Matrix()
 | 
					            val matrix = Matrix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -298,9 +291,15 @@ class AddAbstractProductActivity : AppCompatActivity() {
 | 
				
			|||||||
            rotated.compress(
 | 
					            rotated.compress(
 | 
				
			||||||
                Bitmap.CompressFormat.WEBP_LOSSY,
 | 
					                Bitmap.CompressFormat.WEBP_LOSSY,
 | 
				
			||||||
                100 * (15 / (16 - compressionFactor)),
 | 
					                100 * (15 / (16 - compressionFactor)),
 | 
				
			||||||
                FileOutputStream(pictureFile)
 | 
					                FileOutputStream(tempfile)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            val imageHash = calculateMd5Hash(tempfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            pictureFile = File(picturesPath, "$imageHash.png")
 | 
				
			||||||
 | 
					            Files.move(tempfile.toPath(), pictureFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
 | 
				
			||||||
 | 
					            tempfile.delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            generateThumbnailForImage(this, imageHash)
 | 
					            generateThumbnailForImage(this, imageHash)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            imageView.setImageURI(getImageUri(this, pictureFile))
 | 
					            imageView.setImageURI(getImageUri(this, pictureFile))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ 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 = sharedPreferences.getString("currentGroup", "offline")!!.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() == "") {
 | 
				
			||||||
@@ -59,11 +59,11 @@ class AddCategoryActivity : Activity() {
 | 
				
			|||||||
            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()
 | 
				
			||||||
                net.uploadCategory(currentGroup, newCategory)
 | 
					                if (currentGroup > 0) net.uploadCategory(currentGroup, newCategory)
 | 
				
			||||||
            } else { // Updating existing category
 | 
					            } else { // Updating existing category
 | 
				
			||||||
                category.name = categoryNameTextEdit.text.toString()
 | 
					                category.name = categoryNameTextEdit.text.toString()
 | 
				
			||||||
                DAO.updateCategory(category)
 | 
					                DAO.updateCategory(category)
 | 
				
			||||||
                net.updateCategory(currentGroup, category)
 | 
					                if (currentGroup > 0) net.updateCategory(currentGroup, category)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            finish()
 | 
					            finish()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -177,7 +177,7 @@ class AddProductActivity : AppCompatActivity() {
 | 
				
			|||||||
                return@setOnClickListener
 | 
					                return@setOnClickListener
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            val currentGroup: Int = if (sharedPreferences.getString("currentGroup", "")!! == "") 0 else sharedPreferences.getString("currentGroup", "")!!.toInt()
 | 
					            val currentGroup: Int = if (sharedPreferences.getString("currentGroup", "offline")!! == "offline") 0 else sharedPreferences.getString("currentGroup", "")!!.toInt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var response: Response? = null
 | 
					            var response: Response? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -200,8 +200,11 @@ class AddProductActivity : AppCompatActivity() {
 | 
				
			|||||||
        val today = SimpleDateFormat("dd.MM.yyyy").format(Calendar.getInstance().time).split(".")
 | 
					        val today = SimpleDateFormat("dd.MM.yyyy").format(Calendar.getInstance().time).split(".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dateOfProductionDatePicker.updateDate(today[2].toInt(), today[1].toInt(), today[0].toInt())
 | 
					        dateOfProductionDatePicker.updateDate(today[2].toInt(), today[1].toInt() - 1, today[0].toInt())
 | 
				
			||||||
        expiryDatePicker.updateDate(today[2].toInt(), today[1].toInt(), today[0].toInt())
 | 
					        expiryDatePicker.updateDate(today[2].toInt(), today[1].toInt() - 1, today[0].toInt())
 | 
				
			||||||
 | 
					        product!!.dateOfProduction = SimpleDateFormat("dd.MM.yyyy").parse("${today[0]}.${today[1]}.${today[2]}")!!.time / 1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val intentLauncher =
 | 
					    private val intentLauncher =
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import android.app.Activity
 | 
				
			|||||||
import android.content.DialogInterface
 | 
					import android.content.DialogInterface
 | 
				
			||||||
import android.content.Intent
 | 
					import android.content.Intent
 | 
				
			||||||
import android.os.Bundle
 | 
					import android.os.Bundle
 | 
				
			||||||
 | 
					import android.util.Log
 | 
				
			||||||
import android.view.Menu
 | 
					import android.view.Menu
 | 
				
			||||||
import android.view.MenuItem
 | 
					import android.view.MenuItem
 | 
				
			||||||
import android.widget.Toast
 | 
					import android.widget.Toast
 | 
				
			||||||
@@ -17,7 +18,6 @@ import androidx.security.crypto.EncryptedSharedPreferences
 | 
				
			|||||||
import androidx.security.crypto.MasterKeys
 | 
					import androidx.security.crypto.MasterKeys
 | 
				
			||||||
import androidx.viewpager.widget.ViewPager
 | 
					import androidx.viewpager.widget.ViewPager
 | 
				
			||||||
import com.google.android.material.navigation.NavigationView
 | 
					import com.google.android.material.navigation.NavigationView
 | 
				
			||||||
import okhttp3.internal.wait
 | 
					 | 
				
			||||||
import org.foxarmy.barcodescannerforemployees.*
 | 
					import org.foxarmy.barcodescannerforemployees.*
 | 
				
			||||||
import org.foxarmy.barcodescannerforemployees.database.AbstractProductDAO
 | 
					import org.foxarmy.barcodescannerforemployees.database.AbstractProductDAO
 | 
				
			||||||
import org.foxarmy.barcodescannerforemployees.database.CategoryDAO
 | 
					import org.foxarmy.barcodescannerforemployees.database.CategoryDAO
 | 
				
			||||||
@@ -38,9 +38,10 @@ import java.io.File
 | 
				
			|||||||
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
 | 
					class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private lateinit var binding: ActivityMainBinding
 | 
					    private lateinit var binding: ActivityMainBinding
 | 
				
			||||||
    lateinit var adapter: ViewPagerAdapter
 | 
					    private lateinit var adapter: ViewPagerAdapter
 | 
				
			||||||
    var drawerLayout: DrawerLayout? = null
 | 
					    private var drawerLayout: DrawerLayout? = null
 | 
				
			||||||
    var actionBarDrawerToggle: ActionBarDrawerToggle? = null
 | 
					    private var actionBarDrawerToggle: ActionBarDrawerToggle? = null
 | 
				
			||||||
 | 
					    private lateinit var ws: WebSocketClient
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
					    override fun onCreate(savedInstanceState: Bundle?) {
 | 
				
			||||||
        super.onCreate(savedInstanceState)
 | 
					        super.onCreate(savedInstanceState)
 | 
				
			||||||
@@ -115,7 +116,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
 | 
				
			|||||||
            noInternetConnectionAvailableNotification(this)
 | 
					            noInternetConnectionAvailableNotification(this)
 | 
				
			||||||
        } else if (currentGroup != "offline" && net.serverIsAvailable(this)) {
 | 
					        } else if (currentGroup != "offline" && net.serverIsAvailable(this)) {
 | 
				
			||||||
            synchronize()
 | 
					            synchronize()
 | 
				
			||||||
            val 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)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -395,6 +396,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun updateAll() {
 | 
					    fun updateAll() {
 | 
				
			||||||
 | 
					        runOnUiThread {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
                val storageFragment: StorageFragment = adapter.getItem(0) as StorageFragment
 | 
					                val storageFragment: StorageFragment = adapter.getItem(0) as StorageFragment
 | 
				
			||||||
                val shelfFragment: ShelfFragment = adapter.getItem(1) as ShelfFragment
 | 
					                val shelfFragment: ShelfFragment = adapter.getItem(1) as ShelfFragment
 | 
				
			||||||
                val categoriesFragment: CategoriesFragment = adapter.getItem(2) as CategoriesFragment
 | 
					                val categoriesFragment: CategoriesFragment = adapter.getItem(2) as CategoriesFragment
 | 
				
			||||||
@@ -402,6 +405,10 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
 | 
				
			|||||||
                storageFragment.updateContent()
 | 
					                storageFragment.updateContent()
 | 
				
			||||||
                shelfFragment.updateContent()
 | 
					                shelfFragment.updateContent()
 | 
				
			||||||
                categoriesFragment.updateContent()
 | 
					                categoriesFragment.updateContent()
 | 
				
			||||||
 | 
					            } catch (e:Exception) {
 | 
				
			||||||
 | 
					                Log.e("BSFE/MainActivity", e.message!!)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
 | 
					    override fun onOptionsItemSelected(item: MenuItem): Boolean {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -163,7 +163,7 @@ class AbstractProductDAO(private val dbHelper: DBStorageController) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        with(cursor) {
 | 
					        with(cursor) {
 | 
				
			||||||
            while (moveToNext()) {
 | 
					            while (moveToNext()) {
 | 
				
			||||||
                val id = getInt(getColumnIndexOrThrow(android.provider.BaseColumns._ID))
 | 
					                val id = getInt(getColumnIndexOrThrow(BaseColumns._ID))
 | 
				
			||||||
                val productName =
 | 
					                val productName =
 | 
				
			||||||
                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
					                    getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
 | 
				
			||||||
                val imageFilename =
 | 
					                val imageFilename =
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user