From ae66a462e75254118a4c835c1a106c74e0e2fbae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horv=C3=A1th=20Gergely?= Date: Mon, 6 May 2024 06:01:15 +0200 Subject: [PATCH 1/3] LiveActivities design fix - Fixed if the user opens the app 1 hour before their first class, the Room section is empty in LiveActivity lock screen - DynamicIsland reworked and improved - The room section moved to Flutter side --- refilc/ios/livecard/livecard.swift | 87 ++++++++++++------- .../lib/api/providers/live_card_provider.dart | 6 +- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/refilc/ios/livecard/livecard.swift b/refilc/ios/livecard/livecard.swift index f5f27e7..b59b707 100644 --- a/refilc/ios/livecard/livecard.swift +++ b/refilc/ios/livecard/livecard.swift @@ -52,14 +52,24 @@ struct LockScreenLiveActivityView: View { VStack(alignment: .center) { // Jelenlegi óra VStack { + if(context.state.title.contains("Az első órádig")) { + Text(context.state.title) + .font(.system(size: 15)) + .bold() + .multilineTextAlignment(.center) + } else { Text(context.state.index + " " + context.state.title) - .font(.body) - .bold() - .multilineTextAlignment(.center) - - Text("Terem: \(context.state.subtitle)") - .italic() - .font(.caption) + .font(.body) + .bold() + .multilineTextAlignment(.center) + } + + //Terem + if (!context.state.subtitle.isEmpty) { + Text(context.state.subtitle) + .italic() + .font(.caption) + } } // Leírás @@ -84,14 +94,14 @@ struct LockScreenLiveActivityView: View { .padding(15) Spacer() - + // Visszaszámláló Text(timerInterval: context.state.date, countsDown: true) .multilineTextAlignment(.center) .frame(width: 85) .font(.title2) .monospacedDigit() - .padding(.trailing, CGFloat(24)) + .padding(.trailing) } .activityBackgroundTint( context.state.color != "#676767" @@ -109,7 +119,7 @@ struct LiveCardWidget: Widget { LockScreenLiveActivityView(context: context) /// Dynamic Island } dynamicIsland: { context in - + /// Expanded return DynamicIsland { DynamicIslandExpandedRegion(.leading) { @@ -135,30 +145,49 @@ struct LiveCardWidget: Widget { } DynamicIslandExpandedRegion(.center) { VStack(alignment: .center) { + if(context.state.title.contains("Az első órádig")) { + Text("Az első órád:") + .font(.body) + .bold() + .padding(.leading, 15) + Text(context.state.nextSubject) + .font(.body) + .padding(.leading, 15) + + Text("Ebben a teremben:") + .font(.body) + .bold() + .padding(.leading, 15) + Text(context.state.nextRoom) + .font(.body) + .padding(.leading, 15) + } else { Text(context.state.index + context.state.title) - .lineLimit(1) - .font(.body) - .bold() - + .lineLimit(1) + .font(.body) + .bold() + Text(context.state.subtitle) - .lineLimit(1) - .font(.subheadline) - Spacer() - - Text(context.state.description) - .lineLimit(2) - .font(.caption) + .lineLimit(1) + .font(.subheadline) + Spacer(minLength: 5) + + Text("Következő óra és terem:") + .font(.system(size: 13)) + Text(context.state.nextSubject) + .font(.caption) + Text(context.state.nextRoom) + .font(.caption2) + } + + }.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0)) + } - + /// Compact } compactLeading: { - Label { - Text(context.state.title) - } icon: { - Image(systemName: context.state.icon) - } - .font(.caption2) + Image(systemName: context.state.icon) } compactTrailing: { Text(timerInterval: context.state.date, countsDown: true) @@ -191,7 +220,7 @@ struct LiveCardWidget: Widget { context.state.color != "#676767" ? Color(hex: context.state.color) : Color.clear - ) + ) } } } diff --git a/refilc/lib/api/providers/live_card_provider.dart b/refilc/lib/api/providers/live_card_provider.dart index 7ace094..ab5acd3 100644 --- a/refilc/lib/api/providers/live_card_provider.dart +++ b/refilc/lib/api/providers/live_card_provider.dart @@ -91,7 +91,7 @@ class LiveCardProvider extends ChangeNotifier { "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", - "title": "Első órádig:", + "title": "Jó reggelt! Az első órádig:", "subtitle": "", "description": "", "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", @@ -111,7 +111,7 @@ class LiveCardProvider extends ChangeNotifier { "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", - "title": "Első órádig:", + "title": "Jó napot! Az első órádig:", "subtitle": "", "description": "", "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", @@ -131,7 +131,7 @@ class LiveCardProvider extends ChangeNotifier { "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", - "title": "Első órádig:", + "title": "Jó estét! Az első órádig:", "subtitle": "", "description": "", "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", From 2ca8f4b8fececf8fd0e4eb8fdd851a840f1ff58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horv=C3=A1th=20Gergely?= Date: Mon, 6 May 2024 06:03:06 +0200 Subject: [PATCH 2/3] LiveActivities design fix - Fixed if the user opens the app 1 hour before their first class, the Room section is empty in LiveActivity lock screen - DynamicIsland reworked and improved - The room section moved to Flutter side --- .../lib/api/providers/live_card_provider.dart | 139 +++++++++++------- 1 file changed, 84 insertions(+), 55 deletions(-) diff --git a/refilc/lib/api/providers/live_card_provider.dart b/refilc/lib/api/providers/live_card_provider.dart index ab5acd3..4e0443b 100644 --- a/refilc/lib/api/providers/live_card_provider.dart +++ b/refilc/lib/api/providers/live_card_provider.dart @@ -1,7 +1,6 @@ // ignore_for_file: no_leading_underscores_for_local_identifiers import 'dart:async'; -import 'dart:io'; import 'package:refilc/api/providers/liveactivity/platform_channel.dart'; import 'package:refilc/helpers/subject.dart'; @@ -18,9 +17,10 @@ enum LiveCardState { duringLesson, duringBreak, morning, + weekendMorning, afternoon, night, - summary + summary, } class LiveCardProvider extends ChangeNotifier { @@ -34,18 +34,19 @@ class LiveCardProvider extends ChangeNotifier { static bool hasDayEnd = false; static DateTime? storeFirstRunDate; static bool hasActivitySettingsChanged = false; + // ignore: non_constant_identifier_names static Map LAData = {}; static DateTime? now; // LiveCardState currentState = LiveCardState.empty; + // ignore: unused_field late Timer _timer; late final TimetableProvider _timetable; late final SettingsProvider _settings; late Duration _delay; - bool _hasCheckedTimetable = false; LiveCardProvider({ @@ -87,19 +88,24 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.morning: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", "title": "Jó reggelt! Az első órádig:", "subtitle": "", "description": "", - "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", + "startDate": storeFirstRunDate != null + ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - + (_delay.inMilliseconds)) + .toString() + : "", "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -107,19 +113,24 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.afternoon: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", "title": "Jó napot! Az első órádig:", "subtitle": "", "description": "", - "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", + "startDate": storeFirstRunDate != null + ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - + (_delay.inMilliseconds)) + .toString() + : "", "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -127,19 +138,24 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.night: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", "title": "Jó estét! Az első órádig:", "subtitle": "", "description": "", - "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", + "startDate": storeFirstRunDate != null + ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - + (_delay.inMilliseconds)) + .toString() + : "", "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -147,25 +163,28 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.duringLesson: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": currentLesson != null ? SubjectIcon.resolveName(subject: currentLesson?.subject) : "book", "index": - currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "", + currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "", "title": currentLesson != null - ? currentLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: currentLesson?.subject).capital() + ? currentLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: currentLesson?.subject) + .capital() : "", - "subtitle": currentLesson?.room.replaceAll("_", " ") ?? "", + "subtitle": "Terem: ${currentLesson?.room.replaceAll("_", " ") ?? ""}", "description": currentLesson?.description ?? "", "startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -181,21 +200,23 @@ class LiveCardProvider extends ChangeNotifier { return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": iconFloorMap[diff] ?? "cup.and.saucer", "title": "Szünet", "description": "go $diff".i18n.fill([ diff != "to room" ? (nextLesson!.getFloor() ?? 0) : nextLesson!.room ]), "startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": (nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() - : "") + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject) + .capital() + : "") .capital(), "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", "index": "", @@ -219,12 +240,12 @@ class LiveCardProvider extends ChangeNotifier { ? Duration(seconds: _settings.bellDelay) : Duration.zero; - DateTime now = _now().add(_delay); if ((currentState == LiveCardState.morning || - currentState == LiveCardState.afternoon || - currentState == LiveCardState.night) && storeFirstRunDate == null) { + currentState == LiveCardState.afternoon || + currentState == LiveCardState.night) && + storeFirstRunDate == null) { storeFirstRunDate = now; } @@ -232,9 +253,9 @@ class LiveCardProvider extends ChangeNotifier { // Filter label lessons #128 today = today .where((lesson) => - lesson.status?.name != "Elmaradt" && - lesson.subject.id != '' && - !lesson.isEmpty) + lesson.status?.name != "Elmaradt" && + lesson.subject.id != '' && + !lesson.isEmpty) .toList(); if (today.isNotEmpty) { @@ -242,7 +263,7 @@ class LiveCardProvider extends ChangeNotifier { today.sort((a, b) => a.start.compareTo(b.start)); final _lesson = today.firstWhere( - (l) => l.start.isBefore(now) && l.end.isAfter(now), + (l) => l.start.isBefore(now) && l.end.isAfter(now), orElse: () => Lesson.fromJson({})); if (_lesson.start.year != 0) { @@ -283,7 +304,11 @@ class LiveCardProvider extends ChangeNotifier { } else if (now.hour >= 20) { currentState = LiveCardState.night; } else if (now.hour >= 5 && now.hour <= 10) { - currentState = LiveCardState.morning; + if (nextLesson == null || now.weekday == 6 || now.weekday == 7) { + currentState = LiveCardState.empty; + } else { + currentState = LiveCardState.morning; + } } else { currentState = LiveCardState.empty; } @@ -291,22 +316,21 @@ class LiveCardProvider extends ChangeNotifier { //LIVE ACTIVITIES //CREATE - if (!hasActivityStarted && nextLesson != null && nextLesson! - .start - .difference(now) - .inMinutes <= 60 && (currentState == LiveCardState.morning || - currentState == LiveCardState.afternoon || - currentState == LiveCardState.night)) { + if (!hasActivityStarted && + nextLesson != null && + nextLesson!.start.difference(now).inMinutes <= 60 && + (currentState == LiveCardState.morning || + currentState == LiveCardState.afternoon || + currentState == LiveCardState.night)) { debugPrint( "Az első óra előtt állunk, kevesebb mint egy órával. Létrehozás..."); PlatformChannel.createLiveActivity(toMap()); hasActivityStarted = true; - } - else if (!hasActivityStarted && ((currentState == LiveCardState.duringLesson && - currentLesson != null) || - currentState == LiveCardState.duringBreak)) { - debugPrint( - "Óra van, vagy szünet, de nincs LiveActivity. létrehozás..."); + } else if (!hasActivityStarted && + ((currentState == LiveCardState.duringLesson && + currentLesson != null) || + currentState == LiveCardState.duringBreak)) { + debugPrint("Óra van, vagy szünet, de nincs LiveActivity. létrehozás..."); PlatformChannel.createLiveActivity(toMap()); hasActivityStarted = true; } @@ -317,15 +341,18 @@ class LiveCardProvider extends ChangeNotifier { debugPrint("Valamelyik beállítás megváltozott. Frissítés..."); PlatformChannel.updateLiveActivity(toMap()); hasActivitySettingsChanged = false; - } - else if (nextLesson != null || currentLesson != null) { + } else if (nextLesson != null || currentLesson != null) { bool afterPrevLessonEnd = prevLesson != null && - now.subtract(const Duration(seconds: 1)).isBefore( - prevLesson!.end) && now.isAfter(prevLesson!.end); + now + .subtract(const Duration(seconds: 1)) + .isBefore(prevLesson!.end) && + now.isAfter(prevLesson!.end); bool afterCurrentLessonStart = currentLesson != null && - now.subtract(const Duration(seconds: 1)).isBefore( - currentLesson!.start) && now.isAfter(currentLesson!.start); + now + .subtract(const Duration(seconds: 1)) + .isBefore(currentLesson!.start) && + now.isAfter(currentLesson!.start); if (afterPrevLessonEnd || afterCurrentLessonStart) { debugPrint( "Óra kezdete/vége után 1 másodperccel vagyunk. Frissítés..."); @@ -335,7 +362,9 @@ class LiveCardProvider extends ChangeNotifier { } //END - if (hasActivityStarted && !hasDayEnd && nextLesson == null && + if (hasActivityStarted && + !hasDayEnd && + nextLesson == null && now.isAfter(prevLesson!.end)) { debugPrint("Az utolsó óra véget ért. Befejezés..."); PlatformChannel.endLiveActivity(); @@ -355,4 +384,4 @@ class LiveCardProvider extends ChangeNotifier { List _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? []) .where((l) => _sameDate(l.date, _now())) .toList(); -} \ No newline at end of file +} From 9901251cfc9c2ea85d78cebacf72d22338fc5793 Mon Sep 17 00:00:00 2001 From: Geryy <33695813+geryyhu@users.noreply.github.com> Date: Mon, 6 May 2024 15:25:54 +0200 Subject: [PATCH 3/3] LiveActivities design fix 2.0 --- refilc/ios/livecard/livecard.swift | 132 +++++++++++++++++++---------- 1 file changed, 89 insertions(+), 43 deletions(-) diff --git a/refilc/ios/livecard/livecard.swift b/refilc/ios/livecard/livecard.swift index b59b707..9ee1ac7 100644 --- a/refilc/ios/livecard/livecard.swift +++ b/refilc/ios/livecard/livecard.swift @@ -57,6 +57,12 @@ struct LockScreenLiveActivityView: View { .font(.system(size: 15)) .bold() .multilineTextAlignment(.center) + } else if(context.state.title == "Szünet") { + Text(context.state.title) + .font(.body) + .bold() + .padding(.trailing, 90) + } else { Text(context.state.index + " " + context.state.title) .font(.body) @@ -68,7 +74,7 @@ struct LockScreenLiveActivityView: View { if (!context.state.subtitle.isEmpty) { Text(context.state.subtitle) .italic() - .font(.caption) + .font(.system(size: 13)) } } @@ -79,6 +85,7 @@ struct LockScreenLiveActivityView: View { } // Következő óra + if(context.state.nextSubject != "" && context.state.nextRoom != "") { HStack { Image(systemName: "arrow.right") .resizable() @@ -90,6 +97,12 @@ struct LockScreenLiveActivityView: View { .font(.caption2) } .multilineTextAlignment(.center) + } else { + Spacer(minLength: 5) + Text("Ez az utolsó óra! Kitartást!") + .font(.system(size: 15)) + } + } .padding(15) @@ -143,47 +156,80 @@ struct LiveCardWidget: Widget { ).progressViewStyle(.circular) } } - DynamicIslandExpandedRegion(.center) { - VStack(alignment: .center) { - if(context.state.title.contains("Az első órádig")) { - Text("Az első órád:") - .font(.body) - .bold() - .padding(.leading, 15) - Text(context.state.nextSubject) - .font(.body) - .padding(.leading, 15) - - Text("Ebben a teremben:") - .font(.body) - .bold() - .padding(.leading, 15) - Text(context.state.nextRoom) - .font(.body) - .padding(.leading, 15) - } else { - Text(context.state.index + context.state.title) - .lineLimit(1) - .font(.body) - .bold() - - Text(context.state.subtitle) - .lineLimit(1) - .font(.subheadline) - Spacer(minLength: 5) - - Text("Következő óra és terem:") - .font(.system(size: 13)) - Text(context.state.nextSubject) - .font(.caption) - Text(context.state.nextRoom) - .font(.caption2) - } - - - }.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0)) - - } + DynamicIslandExpandedRegion(.center) { + VStack(alignment: .center) { + // Első óra előtti expanded DynamicIsland + if(context.state.title.contains("Az első órádig")) { + Text("Az első órád:") + .font(.body) + .bold() + .padding(.leading, 15) + Text(context.state.nextSubject) + .font(.body) + .padding(.leading, 15) + + Text("Ebben a teremben:") + .font(.body) + .bold() + .padding(.leading, 15) + Text(context.state.nextRoom) + .font(.body) + .padding(.leading, 15) + } else if(context.state.title == "Szünet") { + // Amikor szünet van, expanded DynamicIsland + Text(context.state.title) + .lineLimit(1) + .font(.body) + .bold() + .padding(.leading, 15) + + Spacer(minLength: 5) + Text("Következő óra és terem:") + .font(.system(size: 13)) + .padding(.leading, 25) + Text(context.state.nextSubject) + .font(.caption) + .padding(.leading, 15) + Text(context.state.nextRoom) + .font(.caption2) + .padding(.leading, 15) + + } else { + // Amikor óra van, expanded DynamicIsland + Text(context.state.index + context.state.title) + .lineLimit(1) + .font(.body) + .bold() + .padding(.trailing, -35) + + Text(context.state.subtitle) + .lineLimit(1) + .font(.subheadline) + .padding(.trailing, -50) + + Spacer(minLength: 5) + + if(context.state.nextRoom != "" && context.state.nextSubject != "") { + Text("Következő óra és terem:") + .font(.system(size: 13)) + .padding(.trailing, -35) + Text(context.state.nextSubject) + .font(.caption) + .padding(.trailing, -35) + Text(context.state.nextRoom) + .font(.caption2) + .padding(.trailing, -35) + } else { + Text("Ez az utolsó óra! Kitartást!") + .font(.system(size: 14)) + .padding(.trailing, -30) + } + } + + + }.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0)) + + } /// Compact } compactLeading: { @@ -194,7 +240,7 @@ struct LiveCardWidget: Widget { .multilineTextAlignment(.center) .frame(width: 40) .font(.caption2) - + /// Collapsed } minimal: { VStack(alignment: .center, content: {