Compare commits

2 Commits
Author SHA1 Message Date
rapafun 7e947374b0 Merge remote-tracking branch 'main/master' 2026-08-18 18:18:30 +02:00
rapafun 889b1b03eb ver 1.2 2026-08-18 18:18:12 +02:00
3 changed files with 85 additions and 3 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-08-15T15:00:18.810512300Z"> <DropdownSelection timestamp="2026-08-16T12:33:41.457151500Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\rapaf\.android\avd\Pixel_9a.avd" /> <DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\rapaf\.android\avd\Pixel_9a.avd" />
+1 -1
View File
@@ -14,7 +14,7 @@ android {
minSdk = 26 minSdk = 26
targetSdk = 37 targetSdk = 37
versionCode = 1 versionCode = 1
versionName = "1.0" versionName = "1.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -16,6 +16,7 @@
package com.bartek.iwentaryzacja package com.bartek.iwentaryzacja
import android.content.Context import android.content.Context
import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
@@ -44,14 +45,20 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import org.apache.poi.ss.usermodel.WorkbookFactory import org.apache.poi.ss.usermodel.WorkbookFactory
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.io.InputStream import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL
import java.util.Scanner
// ========================================== // ==========================================
// 1. MODEL DANYCH MASZYNY // 1. MODEL DANYCH MASZYNY
@@ -80,6 +87,11 @@ class InventoryViewModel : ViewModel() {
private val _notes = MutableStateFlow("") private val _notes = MutableStateFlow("")
val notes: StateFlow<String> = _notes.asStateFlow() val notes: StateFlow<String> = _notes.asStateFlow()
private val _updateInfo = MutableStateFlow<UpdateInfo?>(null)
val updateInfo: StateFlow<UpdateInfo?> = _updateInfo.asStateFlow()
data class UpdateInfo(val versionCode: Int)
fun loadState(context: Context) { fun loadState(context: Context) {
val prefs = context.getSharedPreferences("inventory_prefs", Context.MODE_PRIVATE) val prefs = context.getSharedPreferences("inventory_prefs", Context.MODE_PRIVATE)
_notes.value = prefs.getString("notes", "") ?: "" _notes.value = prefs.getString("notes", "") ?: ""
@@ -154,6 +166,39 @@ class InventoryViewModel : ViewModel() {
_filterMissing.value = !_filterMissing.value _filterMissing.value = !_filterMissing.value
} }
fun checkForUpdates(context: Context) {
viewModelScope.launch(Dispatchers.IO) {
try {
val url = URL("https://bbjsolution.org/AR/InwentARyzacja/raw/branch/master/update.json")
val connection = url.openConnection() as HttpURLConnection
connection.connectTimeout = 5000
connection.readTimeout = 5000
if (connection.responseCode == 200) {
val scanner = Scanner(connection.inputStream).useDelimiter("\\A")
val result = if (scanner.hasNext()) scanner.next() else ""
val json = JSONObject(result)
val newVersionCode = json.getInt("versionCode")
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
@Suppress("DEPRECATION")
val currentVersionCode = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
packageInfo.longVersionCode.toInt()
} else {
packageInfo.versionCode
}
if (newVersionCode > currentVersionCode) {
_updateInfo.value = UpdateInfo(newVersionCode)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
fun getUniqueStatuses(): List<String> { fun getUniqueStatuses(): List<String> {
return _machines.value return _machines.value
.map { it.originalStatus } .map { it.originalStatus }
@@ -260,12 +305,49 @@ fun InventoryScreen(viewModel: InventoryViewModel = viewModel()) {
val searchQuery by viewModel.searchQuery.collectAsState() val searchQuery by viewModel.searchQuery.collectAsState()
val filterMissing by viewModel.filterMissing.collectAsState() val filterMissing by viewModel.filterMissing.collectAsState()
val notes by viewModel.notes.collectAsState() val notes by viewModel.notes.collectAsState()
val updateInfo by viewModel.updateInfo.collectAsState()
var showStatusDialog by remember { mutableStateOf(false) } var showStatusDialog by remember { mutableStateOf(false) }
var showNotesDialog by remember { mutableStateOf(false) } var showNotesDialog by remember { mutableStateOf(false) }
var showUpdateDialog by remember { mutableStateOf(false) }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
viewModel.loadState(context) viewModel.loadState(context)
viewModel.checkForUpdates(context)
}
LaunchedEffect(updateInfo) {
if (updateInfo != null) {
showUpdateDialog = true
}
}
if (showUpdateDialog) {
AlertDialog(
onDismissRequest = { showUpdateDialog = false },
title = { Text("Nowa wersja dostępna", color = Color.White) },
text = {
Text(
"Dostępna jest nowsza wersja aplikacji. Pobierz ją ze strony:\nar.bbjsolution.org",
color = Color.White
)
},
confirmButton = {
TextButton(onClick = {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://ar.bbjsolution.org"))
context.startActivity(intent)
showUpdateDialog = false
}) {
Text("Otwórz stronę")
}
},
dismissButton = {
TextButton(onClick = { showUpdateDialog = false }) {
Text("Później")
}
},
containerColor = Color(0xFF1E2638)
)
} }
// Launcher akceptujący pliki .xlsx oraz .xls // Launcher akceptujący pliki .xlsx oraz .xls
@@ -694,7 +776,7 @@ fun MachineItem(
if (machine.originalStatus.isNotEmpty()) { if (machine.originalStatus.isNotEmpty()) {
Text( Text(
text = machine.originalStatus, text = machine.originalStatus,
fontSize = 10.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
color = Color(0xFF11CAA0), color = Color(0xFF11CAA0),
modifier = Modifier.padding(start = 8.dp) modifier = Modifier.padding(start = 8.dp)