Files
deskhub/mobile/src/main/java/de/deskhub/staff/MainActivity.kt
T
2026-10-25 17:57:13 +00:00

110 lines
4.4 KiB
Kotlin

package de.deskhub.staff
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.core.content.ContextCompat
import de.deskhub.staff.data.TicketRepository
import de.deskhub.staff.data.security.SecureSessionStore
import de.deskhub.staff.push.DeskHubPush
import de.deskhub.staff.push.PushRegistration
import de.deskhub.staff.ui.DeskHubApp
import de.deskhub.staff.ui.DeskHubViewModel
import de.deskhub.staff.ui.DeskHubViewModelFactory
class MainActivity : ComponentActivity() {
private val connectionPingHandler = Handler(Looper.getMainLooper())
private val connectionPing = object : Runnable {
override fun run() {
AppConnectionPing.send(applicationContext)
connectionPingHandler.postDelayed(this, 4 * 60 * 1000L)
}
}
private val viewModel: DeskHubViewModel by viewModels {
DeskHubViewModelFactory(TicketRepository(SecureSessionStore(applicationContext)))
}
private val notificationPermission = registerForActivityResult(ActivityResultContracts.RequestPermission()) { }
/** Jede Berührung meldet (höchstens einmal pro Minute) dem Server, dass die App benutzt wird. */
override fun onUserInteraction() {
super.onUserInteraction()
PresencePing.onUserInteraction(applicationContext)
}
override fun onResume() {
super.onResume()
connectionPingHandler.removeCallbacks(connectionPing)
connectionPing.run()
DeskHubWidget.requestUpdate(applicationContext)
}
override fun onPause() {
connectionPingHandler.removeCallbacks(connectionPing)
super.onPause()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
de.deskhub.staff.ui.I18n.init(applicationContext)
handleNotificationIntent(intent)
setContent {
val state by viewModel.state.collectAsState()
val signedIn = state.staff != null
// Nach der Anmeldung: um Erlaubnis für Benachrichtigungen bitten (einmal) und das Gerät für Push anmelden
LaunchedEffect(signedIn) {
if (signedIn) {
AppConnectionPing.scheduleBackground(applicationContext)
requestNotificationPermissionOnce()
PushRegistration.registerCurrent(applicationContext)
CrashReporter.sendPending(applicationContext)
} else {
AppConnectionPing.cancelBackground(applicationContext)
}
}
DeskHubApp(viewModel)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleNotificationIntent(intent)
}
/** Tipp auf eine Benachrichtigung: das Ticket aus dem Intent öffnen. */
private fun handleNotificationIntent(intent: Intent?) {
val number = intent?.getStringExtra(DeskHubPush.EXTRA_TICKET)?.trim().orEmpty()
if (number.isNotEmpty()) {
intent?.removeExtra(DeskHubPush.EXTRA_TICKET)
viewModel.openTicketFromNotification(number)
}
// Knöpfe im Widget: „Neues Ticket“ und „Alle Tickets"
val route = intent?.getStringExtra(DeskHubWidget.EXTRA_ROUTE)?.trim().orEmpty()
if (route == "newTicket" || route == "tickets") {
intent?.removeExtra(DeskHubWidget.EXTRA_ROUTE)
viewModel.requestRoute(route)
}
}
private fun requestNotificationPermissionOnce() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) return
val prefs = getSharedPreferences("deskhub_push", MODE_PRIVATE)
if (prefs.getBoolean("asked_notifications", false)) return
prefs.edit().putBoolean("asked_notifications", true).apply()
notificationPermission.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}