forked from firka/firka
firka: rewrite Android widget and fix refresh
This commit is contained in:
@@ -18,7 +18,7 @@ import androidx.glance.text.FontWeight
|
||||
import androidx.glance.text.Text
|
||||
import androidx.glance.text.TextStyle
|
||||
import app.firka.naplo.model.Colors
|
||||
import app.firka.naplo.model.Lesson
|
||||
import app.firka.naplo.glance.WidgetLesson
|
||||
import java.time.format.DateTimeFormatterBuilder
|
||||
|
||||
val hhmm = DateTimeFormatterBuilder()
|
||||
@@ -26,7 +26,7 @@ val hhmm = DateTimeFormatterBuilder()
|
||||
.toFormatter()
|
||||
|
||||
@Composable
|
||||
fun LessonCard(lesson: Lesson, colors: Colors,
|
||||
fun LessonCard(lesson: WidgetLesson, colors: Colors,
|
||||
modifier: GlanceModifier = GlanceModifier) {
|
||||
Box(modifier =
|
||||
modifier
|
||||
@@ -38,7 +38,7 @@ fun LessonCard(lesson: Lesson, colors: Colors,
|
||||
var bgColor = colors.a15p
|
||||
var fgColor = colors.textSecondary
|
||||
|
||||
if (lesson.substituteTeacher == null) {
|
||||
if (lesson.substituteTeacher != null) {
|
||||
bgColor = colors.warning15p
|
||||
fgColor = colors.warningText
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import androidx.glance.text.FontWeight
|
||||
import androidx.glance.text.Text
|
||||
import androidx.glance.text.TextStyle
|
||||
import app.firka.naplo.model.Colors
|
||||
import app.firka.naplo.model.Lesson
|
||||
import app.firka.naplo.glance.WidgetLesson
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.time.LocalDate
|
||||
@@ -73,17 +73,28 @@ class TimetableWidget : GlanceAppWidget() {
|
||||
val colors = Colors(widgetState)
|
||||
|
||||
val tt = widgetState.getJSONArray("timetable")
|
||||
var lessons = mutableListOf<Lesson>()
|
||||
var lessons = mutableListOf<WidgetLesson>()
|
||||
|
||||
for (i in 0..<tt.length()) {
|
||||
lessons.add(Lesson(tt.getJSONObject(i)))
|
||||
lessons.add(WidgetLesson(tt.getJSONObject(i)))
|
||||
}
|
||||
|
||||
val now = LocalDate.now()
|
||||
val start = LocalDateTime.of(now.year, now.month, now.dayOfMonth, 0, 0)
|
||||
val displayDateStr = widgetState.optString("displayDate", "")
|
||||
val targetDate = if (displayDateStr.isNotEmpty()) {
|
||||
try {
|
||||
LocalDate.parse(displayDateStr)
|
||||
} catch (_: Exception) {
|
||||
LocalDate.now()
|
||||
}
|
||||
} else {
|
||||
LocalDate.now()
|
||||
}
|
||||
val start = LocalDateTime.of(targetDate.year, targetDate.month, targetDate.dayOfMonth, 0, 0)
|
||||
val end = start.plusHours(23)
|
||||
lessons = lessons.filter { lesson -> lesson.start.isAfter(start) && lesson.end.isBefore(end) }.toMutableList()
|
||||
|
||||
val headerText = if (displayDateStr.isNotEmpty()) displayDateStr else "Mai órarend"
|
||||
|
||||
Box(modifier =
|
||||
GlanceModifier
|
||||
.background(colors.background)
|
||||
@@ -92,7 +103,7 @@ class TimetableWidget : GlanceAppWidget() {
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
"Mai órarend",
|
||||
headerText,
|
||||
style = TextStyle(
|
||||
color = ColorProvider(colors.textSecondary, colors.textSecondary),
|
||||
fontSize = 12.sp,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package app.firka.naplo.glance
|
||||
|
||||
import app.firka.naplo.getIntOrNull
|
||||
import app.firka.naplo.getStringOrNull
|
||||
import org.json.JSONObject
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatterBuilder
|
||||
|
||||
class WidgetLesson(data: JSONObject) {
|
||||
val formatter = DateTimeFormatterBuilder()
|
||||
.appendPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
|
||||
.optionalStart()
|
||||
.appendLiteral('Z')
|
||||
.optionalEnd()
|
||||
.toFormatter()
|
||||
|
||||
val name: String = data.getString("Nev")
|
||||
val start: LocalDateTime = LocalDateTime.parse(data.getString("KezdetIdopont"), formatter)
|
||||
val end: LocalDateTime = LocalDateTime.parse(data.getString("VegIdopont"), formatter)
|
||||
val lessonNumber: Int? = data.getIntOrNull("Oraszam")
|
||||
val roomName: String? = data.getStringOrNull("TeremNeve")
|
||||
val substituteTeacher: String? = data.getStringOrNull("HelyettesTanarNeve")
|
||||
}
|
||||
@@ -3,5 +3,5 @@
|
||||
android:minWidth="300dp"
|
||||
android:minHeight="100dp"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:updatePeriodMillis="10000">
|
||||
android:updatePeriodMillis="1800000">
|
||||
</appwidget-provider>
|
||||
@@ -22,37 +22,56 @@ class WidgetCacheHelper {
|
||||
timetableJson.add(lesson.toJson());
|
||||
}
|
||||
|
||||
return {'colors': _colorsMap(style), 'timetable': timetableJson};
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toAndroidWidgetJson(
|
||||
FirkaStyle style,
|
||||
List<Lesson> timetable,
|
||||
) {
|
||||
final timetableJson = <Map<String, dynamic>>[];
|
||||
for (var lesson in timetable) {
|
||||
timetableJson.add({
|
||||
'Nev': lesson.name,
|
||||
'KezdetIdopont': lesson.start.toUtc().toIso8601String(),
|
||||
'VegIdopont': lesson.end.toUtc().toIso8601String(),
|
||||
'Oraszam': lesson.lessonNumber,
|
||||
'TeremNeve': lesson.roomName,
|
||||
'HelyettesTanarNeve': lesson.substituteTeacher,
|
||||
});
|
||||
}
|
||||
return {'colors': _colorsMap(style), 'timetable': timetableJson};
|
||||
}
|
||||
|
||||
static Map<String, dynamic> _colorsMap(FirkaStyle style) {
|
||||
return {
|
||||
'colors': {
|
||||
'background': style.colors.background.toARGB32(),
|
||||
'backgroundAmoled': style.colors.backgroundAmoled.toARGB32(),
|
||||
'background0p': style.colors.background0p.toARGB32(),
|
||||
'success': style.colors.success.toARGB32(),
|
||||
'textPrimary': style.colors.textPrimary.toARGB32(),
|
||||
'textSecondary': style.colors.textSecondary.toARGB32(),
|
||||
'textTertiary': style.colors.textTertiary.toARGB32(),
|
||||
'card': style.colors.card.toARGB32(),
|
||||
'cardTranslucent': style.colors.cardTranslucent.toARGB32(),
|
||||
'buttonSecondaryFill': style.colors.buttonSecondaryFill.toARGB32(),
|
||||
'accent': style.colors.accent.toARGB32(),
|
||||
'secondary': style.colors.secondary.toARGB32(),
|
||||
'shadowColor': style.colors.shadowColor.toARGB32(),
|
||||
'a15p': style.colors.a15p.toARGB32(),
|
||||
'warningAccent': style.colors.warningAccent.toARGB32(),
|
||||
'warningText': style.colors.warningText.toARGB32(),
|
||||
'warning15p': style.colors.warning15p.toARGB32(),
|
||||
'warningCard': style.colors.warningCard.toARGB32(),
|
||||
'errorAccent': style.colors.errorAccent.toARGB32(),
|
||||
'errorText': style.colors.errorText.toARGB32(),
|
||||
'error15p': style.colors.error15p.toARGB32(),
|
||||
'errorCard': style.colors.errorCard.toARGB32(),
|
||||
'grade5': style.colors.grade5.toARGB32(),
|
||||
'grade4': style.colors.grade4.toARGB32(),
|
||||
'grade3': style.colors.grade3.toARGB32(),
|
||||
'grade2': style.colors.grade2.toARGB32(),
|
||||
'grade1': style.colors.grade1.toARGB32(),
|
||||
},
|
||||
'timetable': timetableJson,
|
||||
'background': style.colors.background.toARGB32(),
|
||||
'backgroundAmoled': style.colors.backgroundAmoled.toARGB32(),
|
||||
'background0p': style.colors.background0p.toARGB32(),
|
||||
'success': style.colors.success.toARGB32(),
|
||||
'textPrimary': style.colors.textPrimary.toARGB32(),
|
||||
'textSecondary': style.colors.textSecondary.toARGB32(),
|
||||
'textTertiary': style.colors.textTertiary.toARGB32(),
|
||||
'card': style.colors.card.toARGB32(),
|
||||
'cardTranslucent': style.colors.cardTranslucent.toARGB32(),
|
||||
'buttonSecondaryFill': style.colors.buttonSecondaryFill.toARGB32(),
|
||||
'accent': style.colors.accent.toARGB32(),
|
||||
'secondary': style.colors.secondary.toARGB32(),
|
||||
'shadowColor': style.colors.shadowColor.toARGB32(),
|
||||
'a15p': style.colors.a15p.toARGB32(),
|
||||
'warningAccent': style.colors.warningAccent.toARGB32(),
|
||||
'warningText': style.colors.warningText.toARGB32(),
|
||||
'warning15p': style.colors.warning15p.toARGB32(),
|
||||
'warningCard': style.colors.warningCard.toARGB32(),
|
||||
'errorAccent': style.colors.errorAccent.toARGB32(),
|
||||
'errorText': style.colors.errorText.toARGB32(),
|
||||
'error15p': style.colors.error15p.toARGB32(),
|
||||
'errorCard': style.colors.errorCard.toARGB32(),
|
||||
'grade5': style.colors.grade5.toARGB32(),
|
||||
'grade4': style.colors.grade4.toARGB32(),
|
||||
'grade3': style.colors.grade3.toARGB32(),
|
||||
'grade2': style.colors.grade2.toARGB32(),
|
||||
'grade1': style.colors.grade1.toARGB32(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,6 +101,25 @@ class WidgetCacheHelper {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> generateWidgetStateForDate(
|
||||
DateTime date,
|
||||
FirkaStyle style,
|
||||
KretaClient client,
|
||||
) async {
|
||||
final dataDir = await getApplicationDocumentsDirectory();
|
||||
final dayStart = DateTime(date.year, date.month, date.day);
|
||||
final dayEnd = dayStart.add(Duration(hours: 23, minutes: 59));
|
||||
final lessons = await client.getTimeTable(dayStart, dayEnd, forceCache: false);
|
||||
final dayLessons = lessons.response ?? [];
|
||||
|
||||
final json = toJson(style, dayLessons);
|
||||
json['displayDate'] =
|
||||
'${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
|
||||
|
||||
final widgetFile = File(p.join(dataDir.path, "widget_state.json"));
|
||||
await widgetFile.writeAsString(jsonEncode(json));
|
||||
}
|
||||
|
||||
static Future<void> updateIOSWidgets({
|
||||
required String locale,
|
||||
required String theme,
|
||||
|
||||
@@ -198,7 +198,8 @@ class _HomeScreenState extends FirkaState<HomeScreen>
|
||||
if (Platform.isAndroid) {
|
||||
await WidgetCacheHelper.updateWidgetCache(appStyle, initData.client);
|
||||
await HomeWidget.updateWidget(
|
||||
qualifiedAndroidName: "app.firka.naplo.glance.TimetableWidget",
|
||||
qualifiedAndroidName:
|
||||
"app.firka.naplo.glance.TimetableWidgetReceiver",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user