diff --git a/firka/android/app/src/main/kotlin/app/firka/naplo/MainActivity.kt b/firka/android/app/src/main/kotlin/app/firka/naplo/MainActivity.kt index 035da97..4f44326 100644 --- a/firka/android/app/src/main/kotlin/app/firka/naplo/MainActivity.kt +++ b/firka/android/app/src/main/kotlin/app/firka/naplo/MainActivity.kt @@ -1,12 +1,15 @@ package app.firka.naplo +import android.appwidget.AppWidgetManager import android.content.ComponentName import android.content.Intent import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.util.Log +import androidx.glance.appwidget.updateAll import app.firka.naplo.glance.TimetableWidget +import app.firka.naplo.glance.TimetableWidgetReceiver import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel @@ -107,7 +110,19 @@ class MainActivity : FlutterActivity() { "refreshTimetableWidget" -> { CoroutineScope(SupervisorJob() + Dispatchers.Default).launch { try { - TimetableWidget().updateAll(context.applicationContext) + val appContext = context.applicationContext + val appWidgetManager = AppWidgetManager.getInstance(appContext) + val componentName = ComponentName(appContext, TimetableWidgetReceiver::class.java) + val ids = appWidgetManager.getAppWidgetIds(componentName) + if (ids.isNotEmpty()) { + val intent = Intent(appContext, TimetableWidgetReceiver::class.java).apply { + action = AppWidgetManager.ACTION_APPWIDGET_UPDATE + putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids) + addFlags(Intent.FLAG_RECEIVER_FOREGROUND) + } + appContext.sendBroadcast(intent) + } + TimetableWidget().updateAll(appContext) result.success(true) } catch (e: Exception) { result.error("refresh_failed", e.message, null) diff --git a/firka/android/app/src/main/kotlin/app/firka/naplo/glance/TimetableWidget.kt b/firka/android/app/src/main/kotlin/app/firka/naplo/glance/TimetableWidget.kt index b762dcb..5672f7b 100644 --- a/firka/android/app/src/main/kotlin/app/firka/naplo/glance/TimetableWidget.kt +++ b/firka/android/app/src/main/kotlin/app/firka/naplo/glance/TimetableWidget.kt @@ -27,6 +27,8 @@ import androidx.glance.text.Text import androidx.glance.text.TextStyle import app.firka.naplo.model.Colors import app.firka.naplo.glance.WidgetLesson +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import org.json.JSONObject import java.io.File import java.time.LocalDate @@ -38,19 +40,47 @@ class TimetableWidget : GlanceAppWidget() { get() = HomeWidgetGlanceStateDefinition() override suspend fun provideGlance(context: Context, id: GlanceId) { + val data = withContext(Dispatchers.IO) { + loadWidgetData(context) + } provideContent { - GlanceContent(context, currentState()) + GlanceContent(context, currentState(), data) } } - @Composable - private fun GlanceContent(context: Context, currentState: HomeWidgetGlanceState) { + private fun loadWidgetData(context: Context): WidgetData? { val appFlutter = File(context.applicationContext.dataDir, "app_flutter") val widgetStateFile = File(appFlutter, "widget_state.json") + if (!widgetStateFile.exists()) return null + val widgetState = JSONObject(widgetStateFile.readText(Charsets.UTF_8)) + val colors = Colors(widgetState) + val tt = widgetState.getJSONArray("timetable") + val lessons = mutableListOf() + for (i in 0..() - - for (i in 0.. lesson.start.isAfter(start) && lesson.end.isBefore(end) }.toMutableList() - - val headerText = if (displayDateStr.isNotEmpty()) displayDateStr else "Mai órarend" - - Box(modifier = - GlanceModifier - .background(colors.background) + Box( + modifier = GlanceModifier + .background(data.colors.background) .padding(16.dp) .fillMaxSize() ) { Column { Text( - headerText, + data.headerText, style = TextStyle( - color = ColorProvider(colors.textSecondary, colors.textSecondary), + color = ColorProvider(data.colors.textSecondary, data.colors.textSecondary), fontSize = 12.sp, fontWeight = FontWeight.Medium ) ) Spacer(modifier = GlanceModifier.height(4.dp)) - for (lesson in lessons) { - LessonCard(lesson, colors) + for (lesson in data.lessons) { + LessonCard(lesson, data.colors) Spacer(modifier = GlanceModifier.height(4.dp)) } } } } +} -} \ No newline at end of file +private data class WidgetData( + val colors: Colors, + val headerText: String, + val lessons: List, +) \ No newline at end of file diff --git a/firka/lib/ui/phone/screens/debug/debug_screen.dart b/firka/lib/ui/phone/screens/debug/debug_screen.dart index ff48959..10ab5ed 100644 --- a/firka/lib/ui/phone/screens/debug/debug_screen.dart +++ b/firka/lib/ui/phone/screens/debug/debug_screen.dart @@ -19,6 +19,7 @@ import 'package:firka/data/widget.dart'; import 'package:firka/ui/shared/firka_icon.dart'; import 'package:firka/ui/theme/style.dart'; import 'package:flutter/services.dart'; +import 'package:home_widget/home_widget.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; @@ -148,6 +149,10 @@ class _DebugScreen extends FirkaState { widget.data.client, ); if (Platform.isAndroid) { + await HomeWidget.updateWidget( + qualifiedAndroidName: + 'app.firka.naplo.glance.TimetableWidgetReceiver', + ); await const MethodChannel( 'firka.app/main', ).invokeMethod('refreshTimetableWidget');