added offline mode and improved coachcode system

This commit is contained in:
oxidiert
2025-09-29 13:02:00 +02:00
parent 851676f6c3
commit dcfa261c1c
3 changed files with 85 additions and 30 deletions

View File

@ -13,6 +13,7 @@ import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import java.io.File
class MainActivity : AppCompatActivity() {
@ -23,15 +24,33 @@ class MainActivity : AppCompatActivity() {
private var progress: ProgressBar? = null
// LIVE: Network-Callback (wird in onResume registriert, in onPause deregistriert)
// LIVE: Network-Callback (optional für Statusleiste)
private var netCb: ConnectivityManager.NetworkCallback? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Login-Dialog -> Login -> Auto-Download -> OpeningScreen
// === Offline-Start ermöglichen ===
// Bedingung: gespeicherter User/Token UND lokale DB vorhanden -> direkt OpeningScreen
val hasCreds = !TokenStore.getUsername(this).isNullOrBlank() && !TokenStore.getToken(this).isNullOrBlank()
val hasDb = hasLocalDb()
if (hasCreds && hasDb) {
openingScreenHandler = HandlerOpeningScreen(this)
openingScreenHandler.init()
return
}
// Sonst: Login-Dialog -> Login -> DB (einmalig) laden -> OpeningScreen
showLoginThenDownload()
}
/** Prüft, ob die lokale DB-Datei vorhanden ist. */
private fun hasLocalDb(): Boolean {
val dbFile = getDatabasePath("questionnaire_database")
return dbFile != null && dbFile.exists() && dbFile.length() > 0
}
/** Zeigt den Login-Dialog an, führt Login aus und lädt danach einmalig die DB. */
private fun showLoginThenDownload() {
val container = LinearLayout(this).apply {
orientation = LinearLayout.VERTICAL
@ -47,7 +66,8 @@ class MainActivity : AppCompatActivity() {
inputType = android.text.InputType.TYPE_CLASS_TEXT or
android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
}
container.addView(etUser); container.addView(etPass)
container.addView(etUser)
container.addView(etPass)
val dialog = AlertDialog.Builder(this)
.setTitle("Login erforderlich")
@ -67,18 +87,29 @@ class MainActivity : AppCompatActivity() {
username = user,
password = pass,
onSuccess = { token ->
// Token & Login-Timestamp werden in TokenStore gespeichert (siehe LoginManager/TokenStore).
// Nach erfolgreichem Login: einmalig komplette DB ziehen
DatabaseDownloader.downloadAndReplaceDatabase(
context = this,
token = token
) { ok ->
showBusy(false)
if (!ok) {
Toast.makeText(this, "Download fehlgeschlagen", Toast.LENGTH_LONG).show()
// Wenn Download fehlgeschlagen ist, aber evtl. schon eine DB lokal liegt,
// lassen wir den Nutzer trotzdem weiterarbeiten (Offline).
if (!ok && !hasLocalDb()) {
Toast.makeText(this, "Download fehlgeschlagen keine lokale Datenbank vorhanden", Toast.LENGTH_LONG).show()
// Zurück zum Login, damit man es erneut probieren kann
showLoginThenDownload()
return@downloadAndReplaceDatabase
}
if (!ok) {
Toast.makeText(this, "Download fehlgeschlagen arbeite offline mit vorhandener DB", Toast.LENGTH_LONG).show()
}
// Opening-Screen starten
openingScreenHandler = HandlerOpeningScreen(this)
openingScreenHandler.init()
// Ersten Status sofort anzeigen
openingScreenHandler.refreshHeaderStatusLive()
}
},
@ -111,11 +142,10 @@ class MainActivity : AppCompatActivity() {
private fun dp(v: Int): Int = (v * resources.displayMetrics.density).toInt()
// --- LIVE NETZSTATUS ---
// --- LIVE NETZSTATUS (optional, für deine Status-Leiste) ---
override fun onResume() {
super.onResume()
registerNetworkCallback()
// Falls die Startseite schon steht: Status jetzt gleich ziehen
if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
openingScreenHandler.refreshHeaderStatusLive()
}
@ -127,7 +157,7 @@ class MainActivity : AppCompatActivity() {
}
private fun registerNetworkCallback() {
if (netCb != null) return // schon aktiv
if (netCb != null) return
val cm = getSystemService(ConnectivityManager::class.java)
val req = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
@ -147,7 +177,6 @@ class MainActivity : AppCompatActivity() {
}
}
}
// Optional: auch auf „nicht validiert“ reagieren
override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
runOnUiThread {
if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {