Upload via GUI (4909 Dateien)
This commit is contained in:
Binary file not shown.
@@ -1,60 +1,71 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<!-- Popups bei neuen Tickets (ab Android 13 fragt die App einmal nach) -->
|
<!-- Popups bei neuen Tickets (ab Android 13 fragt die App einmal nach) -->
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
<!-- Für „Jetzt aktualisieren“: die heruntergeladene neue Version installieren -->
|
||||||
<application
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
android:name=".DeskHubApplication"
|
|
||||||
android:allowBackup="false"
|
<application
|
||||||
android:fullBackupContent="false"
|
android:name=".DeskHubApplication"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:allowBackup="false"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:fullBackupContent="false"
|
||||||
android:label="@string/app_name"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/Theme.DeskHub">
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
<meta-data
|
android:supportsRtl="true"
|
||||||
android:name="de.deskhub.staff.creator"
|
android:theme="@style/Theme.DeskHub">
|
||||||
android:value="M_Viper" />
|
<meta-data
|
||||||
<meta-data
|
android:name="de.deskhub.staff.creator"
|
||||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
android:value="M_Viper" />
|
||||||
android:resource="@drawable/ic_stat_notification" />
|
<meta-data
|
||||||
<meta-data
|
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||||
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
android:resource="@drawable/ic_stat_notification" />
|
||||||
android:value="tickets" />
|
<meta-data
|
||||||
<service
|
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||||
android:name=".push.DeskHubMessagingService"
|
android:value="tickets" />
|
||||||
android:exported="false">
|
<provider
|
||||||
<intent-filter>
|
android:name="androidx.core.content.FileProvider"
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
android:authorities="${applicationId}.updates"
|
||||||
</intent-filter>
|
android:exported="false"
|
||||||
</service>
|
android:grantUriPermissions="true">
|
||||||
<receiver
|
<meta-data
|
||||||
android:name=".push.PushReplyReceiver"
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
android:exported="false" />
|
android:resource="@xml/update_paths" />
|
||||||
<activity
|
</provider>
|
||||||
android:name=".MainActivity"
|
<service
|
||||||
android:exported="true"
|
android:name=".push.DeskHubMessagingService"
|
||||||
android:launchMode="singleTop">
|
android:exported="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
</intent-filter>
|
||||||
</intent-filter>
|
</service>
|
||||||
</activity>
|
<receiver
|
||||||
<receiver
|
android:name=".push.PushReplyReceiver"
|
||||||
android:name=".DeskHubWidget"
|
android:exported="false" />
|
||||||
android:exported="true"
|
<activity
|
||||||
android:label="DeskHub Tickets">
|
android:name=".MainActivity"
|
||||||
<intent-filter>
|
android:exported="true"
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
android:launchMode="singleTop">
|
||||||
</intent-filter>
|
<intent-filter>
|
||||||
<meta-data
|
<action android:name="android.intent.action.MAIN" />
|
||||||
android:name="android.appwidget.provider"
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
android:resource="@xml/deskhub_widget_info" />
|
</intent-filter>
|
||||||
</receiver>
|
</activity>
|
||||||
|
<receiver
|
||||||
|
android:name=".DeskHubWidget"
|
||||||
|
android:exported="true"
|
||||||
|
android:label="DeskHub Tickets">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data
|
||||||
|
android:name="android.appwidget.provider"
|
||||||
|
android:resource="@xml/deskhub_widget_info" />
|
||||||
|
</receiver>
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".WidgetActionReceiver"
|
android:name=".WidgetActionReceiver"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,66 @@
|
|||||||
|
package de.deskhub.staff
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Constraints
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.NetworkType
|
||||||
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import de.deskhub.staff.data.remote.DeskHubApi
|
||||||
|
import de.deskhub.staff.data.security.SecureSessionStore
|
||||||
|
import kotlinx.coroutines.CancellationException
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
/** Sends a liveness request without changing the staff member's presence status. */
|
||||||
|
class AppConnectionWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
|
||||||
|
override suspend fun doWork(): Result {
|
||||||
|
val session = SecureSessionStore(applicationContext).load() ?: return Result.success()
|
||||||
|
if (session.token.isBlank() || session.serverUrl.isBlank()) return Result.success()
|
||||||
|
return try {
|
||||||
|
DeskHubApi(session.serverUrl) { session.token }.me()
|
||||||
|
Result.success()
|
||||||
|
} catch (cancelled: CancellationException) {
|
||||||
|
throw cancelled
|
||||||
|
} catch (_: Exception) {
|
||||||
|
Result.retry()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object AppConnectionPing {
|
||||||
|
private const val WORK_NAME = "deskhub-app-connection-heartbeat"
|
||||||
|
|
||||||
|
/** Quick heartbeat while the app is visible. */
|
||||||
|
fun send(context: Context) {
|
||||||
|
val app = context.applicationContext
|
||||||
|
thread(name = "app-connection-ping") {
|
||||||
|
try {
|
||||||
|
val session = SecureSessionStore(app).load() ?: return@thread
|
||||||
|
if (session.token.isBlank() || session.serverUrl.isBlank()) return@thread
|
||||||
|
runBlocking { DeskHubApi(session.serverUrl) { session.token }.me() }
|
||||||
|
} catch (_: Exception) {
|
||||||
|
// The next foreground or background heartbeat will retry.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Android schedules this network-constrained worker periodically, including in the background. */
|
||||||
|
fun scheduleBackground(context: Context) {
|
||||||
|
val constraints = Constraints.Builder()
|
||||||
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
|
.build()
|
||||||
|
val request = PeriodicWorkRequestBuilder<AppConnectionWorker>(15, TimeUnit.MINUTES)
|
||||||
|
.setConstraints(constraints)
|
||||||
|
.build()
|
||||||
|
WorkManager.getInstance(context.applicationContext)
|
||||||
|
.enqueueUniquePeriodicWork(WORK_NAME, ExistingPeriodicWorkPolicy.UPDATE, request)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cancelBackground(context: Context) {
|
||||||
|
WorkManager.getInstance(context.applicationContext).cancelUniqueWork(WORK_NAME)
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1211,3 +1211,11 @@ data class AutoCloseSaveRequest(val action: String = "save_auto_close", val enab
|
|||||||
// ─── Bild-Upload (z.B. für Signaturen) ───────────────────────────────────────
|
// ─── Bild-Upload (z.B. für Signaturen) ───────────────────────────────────────
|
||||||
|
|
||||||
data class UploadImageResponse(val url: String = "")
|
data class UploadImageResponse(val url: String = "")
|
||||||
|
|
||||||
|
data class AppUpdateDto(
|
||||||
|
val available: Boolean = false,
|
||||||
|
val version: String = "",
|
||||||
|
val sha256: String = "",
|
||||||
|
val size: Long = 0,
|
||||||
|
val notes: String = "",
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user