Notificaciones push, auto-update, admin panel v1.1.0 #23
@@ -12,8 +12,8 @@ android {
|
||||
applicationId = "com.devlab.app"
|
||||
minSdk = 26
|
||||
targetSdk = 37
|
||||
versionCode = 1
|
||||
versionName = "1.0.0"
|
||||
versionCode = 2
|
||||
versionName = "1.1.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
@@ -107,10 +107,17 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
@Composable
|
||||
fun AppRoot() {
|
||||
val context = androidx.compose.ui.platform.LocalContext.current
|
||||
val navController = rememberNavController()
|
||||
val loginViewModel: LoginViewModel = viewModel()
|
||||
var isLoggedIn by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(isLoggedIn) {
|
||||
if (isLoggedIn) {
|
||||
NotificationWorker.checkNow(context)
|
||||
}
|
||||
}
|
||||
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentDestination = navBackStackEntry?.destination
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.devlab.app.worker
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.work.*
|
||||
import com.devlab.app.data.api.RetrofitClient
|
||||
import com.devlab.app.data.model.AppNotification
|
||||
@@ -21,37 +22,51 @@ class NotificationWorker(
|
||||
val token = prefs.getToken()
|
||||
|
||||
if (token.isBlank()) {
|
||||
Log.d("NotificationWorker", "No token, skipping")
|
||||
return@withContext Result.success()
|
||||
}
|
||||
|
||||
val lastCheck = prefs.getLastNotificationCheck()
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
Log.d("NotificationWorker", "Checking notifications since $lastCheck")
|
||||
|
||||
RetrofitClient.setToken(token)
|
||||
val service = RetrofitClient.getApiService()
|
||||
|
||||
try {
|
||||
val response = service.getNotifications(page = 1, perPage = 50)
|
||||
if (response.success) {
|
||||
Log.d("NotificationWorker", "Got ${response.data.size} notifications, unread: ${response.unread_count}")
|
||||
|
||||
val newNotifications = response.data.filter { note ->
|
||||
val noteTime = parseTime(note.created_at)
|
||||
noteTime > lastCheck && note.is_read == 0
|
||||
}
|
||||
|
||||
Log.d("NotificationWorker", "New notifications to show: ${newNotifications.size}")
|
||||
|
||||
for (notification in newNotifications) {
|
||||
NotificationHelper.showNotification(applicationContext, notification)
|
||||
}
|
||||
|
||||
val lastTime = newNotifications.maxOfOrNull {
|
||||
val maxTime = newNotifications.maxOfOrNull {
|
||||
parseTime(it.created_at)
|
||||
} ?: System.currentTimeMillis()
|
||||
} ?: now
|
||||
|
||||
prefs.setLastNotificationCheck(
|
||||
if (newNotifications.isNotEmpty()) lastTime else System.currentTimeMillis()
|
||||
if (newNotifications.isNotEmpty()) maxTime else now
|
||||
)
|
||||
} else {
|
||||
Log.d("NotificationWorker", "API returned success=false: ${response.error}")
|
||||
}
|
||||
} catch (_: Exception) { }
|
||||
} catch (e: Exception) {
|
||||
Log.e("NotificationWorker", "API error: ${e.message}")
|
||||
}
|
||||
|
||||
Result.success()
|
||||
} catch (_: Exception) {
|
||||
} catch (e: Exception) {
|
||||
Log.e("NotificationWorker", "Worker error: ${e.message}")
|
||||
Result.retry()
|
||||
}
|
||||
}
|
||||
@@ -88,9 +103,10 @@ class NotificationWorker(
|
||||
|
||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
||||
WORK_NAME,
|
||||
ExistingPeriodicWorkPolicy.KEEP,
|
||||
ExistingPeriodicWorkPolicy.UPDATE,
|
||||
request
|
||||
)
|
||||
Log.d("NotificationWorker", "Scheduled periodic check every 15 min")
|
||||
}
|
||||
|
||||
fun checkNow(context: Context) {
|
||||
@@ -103,6 +119,7 @@ class NotificationWorker(
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(context).enqueue(request)
|
||||
Log.d("NotificationWorker", "Scheduled immediate check")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -469,7 +469,17 @@ class ApiController
|
||||
public function appVersion(): void
|
||||
{
|
||||
$db = \ServerManager\Core\Database::getInstance();
|
||||
$configs = $db->fetchAll('SELECT * FROM app_config');
|
||||
|
||||
try {
|
||||
$configs = $db->fetchAll('SELECT * FROM app_config');
|
||||
} catch (\Throwable $e) {
|
||||
$this->view->json([
|
||||
'success' => false,
|
||||
'error' => 'Database error',
|
||||
], 500);
|
||||
return;
|
||||
}
|
||||
|
||||
$config = [];
|
||||
foreach ($configs as $row) {
|
||||
$config[$row['key']] = $row['value'];
|
||||
|
||||
Reference in New Issue
Block a user