- data backup
- I can't test it because I'm stuck on the login screen.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:refilc/api/providers/liveactivity/platform_channel.dart';
|
||||
import 'package:refilc/helpers/subject.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc_kreta_api/models/lesson.dart';
|
||||
@@ -10,7 +11,6 @@ import 'package:refilc_kreta_api/models/week.dart';
|
||||
import 'package:refilc/utils/format.dart';
|
||||
import 'package:refilc_kreta_api/providers/timetable_provider.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:live_activities/live_activities.dart';
|
||||
import 'package:refilc_mobile_ui/pages/home/live_card/live_card.i18n.dart';
|
||||
|
||||
enum LiveCardState {
|
||||
@@ -29,6 +29,15 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
Lesson? prevLesson;
|
||||
List<Lesson>? nextLessons;
|
||||
|
||||
// new variables
|
||||
static bool hasActivityStarted = false;
|
||||
static bool hasDayEnd = false;
|
||||
static DateTime? storeFirstRunDate;
|
||||
static bool hasActivitySettingsChanged = false;
|
||||
static Map<String, String> LAData = {};
|
||||
static DateTime? now;
|
||||
//
|
||||
|
||||
LiveCardState currentState = LiveCardState.empty;
|
||||
late Timer _timer;
|
||||
late final TimetableProvider _timetable;
|
||||
@@ -36,9 +45,6 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
|
||||
late Duration _delay;
|
||||
|
||||
final _liveActivitiesPlugin = LiveActivities();
|
||||
String? _latestActivityId;
|
||||
Map<String, String> _lastActivity = {};
|
||||
|
||||
bool _hasCheckedTimetable = false;
|
||||
|
||||
@@ -47,23 +53,6 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
required SettingsProvider settings,
|
||||
}) : _timetable = timetable,
|
||||
_settings = settings {
|
||||
if (Platform.isIOS) {
|
||||
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
||||
// Console log
|
||||
if (kDebugMode) {
|
||||
print("iOS LiveActivity enabled: $value");
|
||||
}
|
||||
|
||||
if (value) {
|
||||
_liveActivitiesPlugin.init(appGroupId: "group.refilc2.livecard");
|
||||
|
||||
_liveActivitiesPlugin.getAllActivitiesIds().then((value) {
|
||||
_latestActivityId = value.isNotEmpty ? value.first : null;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
|
||||
_delay = settings.bellDelayEnabled
|
||||
? Duration(seconds: settings.bellDelay)
|
||||
@@ -71,21 +60,6 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
update();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer.cancel();
|
||||
if (Platform.isIOS) {
|
||||
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
||||
if (value) {
|
||||
if (_latestActivityId != null) {
|
||||
_liveActivitiesPlugin.endActivity(_latestActivityId!);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// Debugging
|
||||
static DateTime _now() {
|
||||
// return DateTime(2023, 9, 27, 9, 30);
|
||||
@@ -110,31 +84,88 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
|
||||
Map<String, String> toMap() {
|
||||
switch (currentState) {
|
||||
case LiveCardState.morning:
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": nextLesson != null
|
||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||
: "book",
|
||||
"title": "Első órádig:",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "",
|
||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
: "",
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
};
|
||||
|
||||
case LiveCardState.afternoon:
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": nextLesson != null
|
||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||
: "book",
|
||||
"title": "Első órádig:",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "",
|
||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
: "",
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
};
|
||||
|
||||
case LiveCardState.night:
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": nextLesson != null
|
||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||
: "book",
|
||||
"title": "Első órádig:",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "",
|
||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
: "",
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
};
|
||||
|
||||
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("_", " ") ?? "",
|
||||
"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("_", " ") ?? "",
|
||||
};
|
||||
@@ -150,23 +181,21 @@ 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": "",
|
||||
@@ -178,37 +207,6 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void update() async {
|
||||
if (Platform.isIOS) {
|
||||
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
||||
if (value) {
|
||||
final cmap = toMap();
|
||||
if (!mapEquals(cmap, _lastActivity)) {
|
||||
_lastActivity = cmap;
|
||||
try {
|
||||
if (_lastActivity.isNotEmpty) {
|
||||
if (_latestActivityId == null) {
|
||||
_liveActivitiesPlugin
|
||||
.createActivity(_lastActivity)
|
||||
.then((value) => _latestActivityId = value);
|
||||
} else {
|
||||
_liveActivitiesPlugin.updateActivity(
|
||||
_latestActivityId!, _lastActivity);
|
||||
}
|
||||
} else {
|
||||
if (_latestActivityId != null) {
|
||||
_liveActivitiesPlugin.endActivity(_latestActivityId!);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('ERROR: Unable to create or update iOS LiveActivity!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
List<Lesson> today = _today(_timetable);
|
||||
|
||||
if (today.isEmpty && !_hasCheckedTimetable) {
|
||||
@@ -221,15 +219,22 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
? Duration(seconds: _settings.bellDelay)
|
||||
: Duration.zero;
|
||||
|
||||
final now = _now().add(_delay);
|
||||
|
||||
DateTime now = _now().add(_delay);
|
||||
|
||||
if ((currentState == LiveCardState.morning ||
|
||||
currentState == LiveCardState.afternoon ||
|
||||
currentState == LiveCardState.night) && storeFirstRunDate == null) {
|
||||
storeFirstRunDate = now;
|
||||
}
|
||||
|
||||
// Filter cancelled lessons #20
|
||||
// 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) {
|
||||
@@ -237,7 +242,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,11 +288,65 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
currentState = LiveCardState.empty;
|
||||
}
|
||||
|
||||
//LIVE ACTIVITIES
|
||||
|
||||
//CREATE
|
||||
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...");
|
||||
PlatformChannel.createLiveActivity(toMap());
|
||||
hasActivityStarted = true;
|
||||
}
|
||||
|
||||
//UPDATE
|
||||
else if (hasActivityStarted) {
|
||||
if (hasActivitySettingsChanged) {
|
||||
debugPrint("Valamelyik beállítás megváltozott. Frissítés...");
|
||||
PlatformChannel.updateLiveActivity(toMap());
|
||||
hasActivitySettingsChanged = false;
|
||||
}
|
||||
else if (nextLesson != null || currentLesson != null) {
|
||||
bool afterPrevLessonEnd = prevLesson != null &&
|
||||
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);
|
||||
if (afterPrevLessonEnd || afterCurrentLessonStart) {
|
||||
debugPrint(
|
||||
"Óra kezdete/vége után 1 másodperccel vagyunk. Frissítés...");
|
||||
PlatformChannel.updateLiveActivity(toMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//END
|
||||
if (hasActivityStarted && !hasDayEnd && nextLesson == null &&
|
||||
now.isAfter(prevLesson!.end)) {
|
||||
debugPrint("Az utolsó óra véget ért. Befejezés...");
|
||||
PlatformChannel.endLiveActivity();
|
||||
hasDayEnd = true;
|
||||
hasActivityStarted = false;
|
||||
}
|
||||
LAData = toMap();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get show => currentState != LiveCardState.empty;
|
||||
|
||||
Duration get delay => _delay;
|
||||
|
||||
bool _sameDate(DateTime a, DateTime b) =>
|
||||
@@ -296,4 +355,4 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
List<Lesson> _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? [])
|
||||
.where((l) => _sameDate(l.date, _now()))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
43
refilc/lib/api/providers/liveactivity/platform_channel.dart
Normal file
43
refilc/lib/api/providers/liveactivity/platform_channel.dart
Normal file
@@ -0,0 +1,43 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class PlatformChannel {
|
||||
static const MethodChannel _channel = MethodChannel('hu.refilc/liveactivity');
|
||||
|
||||
static Future<void> createLiveActivity(
|
||||
Map<String, dynamic> activityData) async {
|
||||
if (Platform.isIOS) {
|
||||
try {
|
||||
debugPrint("creating...");
|
||||
await _channel.invokeMethod('createLiveActivity', activityData);
|
||||
} on PlatformException catch (e) {
|
||||
debugPrint("Hiba történt a Live Activity létrehozásakor: ${e.message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> updateLiveActivity(
|
||||
Map<String, dynamic> activityData) async {
|
||||
if (Platform.isIOS) {
|
||||
try {
|
||||
debugPrint("updating...");
|
||||
await _channel.invokeMethod('updateLiveActivity', activityData);
|
||||
} on PlatformException catch (e) {
|
||||
debugPrint("Hiba történt a Live Activity frissítésekor: ${e.message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> endLiveActivity() async {
|
||||
if (Platform.isIOS) {
|
||||
try {
|
||||
debugPrint("finishing...");
|
||||
await _channel.invokeMethod('endLiveActivity');
|
||||
} on PlatformException catch (e) {
|
||||
debugPrint("Hiba történt a Live Activity befejezésekor: ${e.message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:home_widget/home_widget.dart';
|
||||
|
||||
import 'live_card_provider.dart';
|
||||
import 'liveactivity/platform_channel.dart';
|
||||
|
||||
// Mutex
|
||||
bool lock = false;
|
||||
|
||||
@@ -86,10 +89,17 @@ Future<void> syncAll(BuildContext context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return Future.wait(tasks).then((value) {
|
||||
// Unlock
|
||||
lock = false;
|
||||
|
||||
if(Platform.isIOS && LiveCardProvider.hasActivityStarted == true){
|
||||
PlatformChannel.endLiveActivity();
|
||||
LiveCardProvider.hasActivityStarted = false;
|
||||
}
|
||||
|
||||
// Update Widget
|
||||
if (Platform.isAndroid) updateWidget();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user