diff --git a/filcnaplo/ios/Runner/Runner.entitlements b/filcnaplo/ios/Runner/Runner.entitlements
index 2eb7e33..123fc6c 100644
--- a/filcnaplo/ios/Runner/Runner.entitlements
+++ b/filcnaplo/ios/Runner/Runner.entitlements
@@ -3,6 +3,8 @@
com.apple.security.application-groups
-
+
+ group.refilcnaplo.livecard
+
diff --git a/filcnaplo/ios/livecard/livecard.entitlements b/filcnaplo/ios/livecard/livecard.entitlements
index 2eb7e33..123fc6c 100644
--- a/filcnaplo/ios/livecard/livecard.entitlements
+++ b/filcnaplo/ios/livecard/livecard.entitlements
@@ -3,6 +3,8 @@
com.apple.security.application-groups
-
+
+ group.refilcnaplo.livecard
+
diff --git a/filcnaplo/lib/api/providers/live_card_provider.dart b/filcnaplo/lib/api/providers/live_card_provider.dart
index 56fc76a..96f0a85 100644
--- a/filcnaplo/lib/api/providers/live_card_provider.dart
+++ b/filcnaplo/lib/api/providers/live_card_provider.dart
@@ -13,7 +13,14 @@ import 'package:flutter/foundation.dart';
import 'package:live_activities/live_activities.dart';
import 'package:filcnaplo_mobile_ui/pages/home/live_card/live_card.i18n.dart';
-enum LiveCardState { empty, duringLesson, duringBreak, morning, afternoon, night }
+enum LiveCardState {
+ empty,
+ duringLesson,
+ duringBreak,
+ morning,
+ afternoon,
+ night
+}
class LiveCardProvider extends ChangeNotifier {
Lesson? currentLesson;
@@ -42,14 +49,17 @@ class LiveCardProvider extends ChangeNotifier {
_latestActivityId = value.isNotEmpty ? value.first : null;
});
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
- _delay = settings.bellDelayEnabled ? Duration(seconds: settings.bellDelay) : Duration.zero;
+ _delay = settings.bellDelayEnabled
+ ? Duration(seconds: settings.bellDelay)
+ : Duration.zero;
update();
}
@override
void dispose() {
_timer.cancel();
- if (_latestActivityId != null && Platform.isIOS) _liveActivitiesPlugin.endActivity(_latestActivityId!);
+ if (_latestActivityId != null && Platform.isIOS)
+ _liveActivitiesPlugin.endActivity(_latestActivityId!);
super.dispose();
}
@@ -78,14 +88,25 @@ class LiveCardProvider extends ChangeNotifier {
switch (currentState) {
case LiveCardState.duringLesson:
return {
- "icon": currentLesson != null ? SubjectIcon.resolveName(subject: currentLesson?.subject) : "book",
- "index": currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
- "title": currentLesson != null ? ShortSubject.resolve(subject: currentLesson?.subject).capital() : "",
+ "icon": currentLesson != null
+ ? SubjectIcon.resolveName(subject: currentLesson?.subject)
+ : "book",
+ "index":
+ currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
+ "title": currentLesson != null
+ ? ShortSubject.resolve(subject: currentLesson?.subject).capital()
+ : "",
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
"description": currentLesson?.description ?? "",
- "startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
- "endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
- "nextSubject": nextLesson != null ? ShortSubject.resolve(subject: nextLesson?.subject).capital() : "",
+ "startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) -
+ _delay.inMilliseconds)
+ .toString(),
+ "endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) -
+ _delay.inMilliseconds)
+ .toString(),
+ "nextSubject": nextLesson != null
+ ? ShortSubject.resolve(subject: nextLesson?.subject).capital()
+ : "",
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
};
case LiveCardState.duringBreak:
@@ -101,10 +122,19 @@ class LiveCardProvider extends ChangeNotifier {
return {
"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).toString(),
- "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
- "nextSubject": (nextLesson != null ? ShortSubject.resolve(subject: nextLesson?.subject) : "").capital(),
+ "description": "go $diff".i18n.fill([
+ diff != "to room" ? (nextLesson!.getFloor() ?? 0) : nextLesson!.room
+ ]),
+ "startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) -
+ _delay.inMilliseconds)
+ .toString(),
+ "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
+ _delay.inMilliseconds)
+ .toString(),
+ "nextSubject": (nextLesson != null
+ ? ShortSubject.resolve(subject: nextLesson?.subject)
+ : "")
+ .capital(),
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
"index": "",
"subtitle": "",
@@ -119,15 +149,25 @@ class LiveCardProvider extends ChangeNotifier {
final cmap = toMap();
if (!mapEquals(cmap, _lastActivity)) {
_lastActivity = cmap;
-
- if (_lastActivity.isNotEmpty) {
- if (_latestActivityId == null) {
- _liveActivitiesPlugin.createActivity(_lastActivity).then((value) => _latestActivityId = value);
+ try {
+ if (_lastActivity.isNotEmpty) {
+ if (_latestActivityId == null) {
+ _liveActivitiesPlugin
+ .createActivity(_lastActivity)
+ .then((value) => _latestActivityId = value);
+ } else {
+ _liveActivitiesPlugin.updateActivity(
+ _latestActivityId!, _lastActivity);
+ }
} else {
- _liveActivitiesPlugin.updateActivity(_latestActivityId!, _lastActivity);
+ if (_latestActivityId != null) {
+ _liveActivitiesPlugin.endActivity(_latestActivityId!);
+ }
+ }
+ } catch (e) {
+ if (kDebugMode) {
+ print('ERROR: Unable to create or update iOS LiveCard!');
}
- } else {
- if (_latestActivityId != null) _liveActivitiesPlugin.endActivity(_latestActivityId!);
}
}
}
@@ -139,19 +179,28 @@ class LiveCardProvider extends ChangeNotifier {
today = _today(_timetable);
}
- _delay = _settings.bellDelayEnabled ? Duration(seconds: _settings.bellDelay) : Duration.zero;
+ _delay = _settings.bellDelayEnabled
+ ? Duration(seconds: _settings.bellDelay)
+ : Duration.zero;
final now = _now().add(_delay);
// Filter cancelled lessons #20
// Filter label lessons #128
- today = today.where((lesson) => lesson.status?.name != "Elmaradt" && lesson.subject.id != '' && !lesson.isEmpty).toList();
+ today = today
+ .where((lesson) =>
+ lesson.status?.name != "Elmaradt" &&
+ lesson.subject.id != '' &&
+ !lesson.isEmpty)
+ .toList();
if (today.isNotEmpty) {
// sort
today.sort((a, b) => a.start.compareTo(b.start));
- final _lesson = today.firstWhere((l) => l.start.isBefore(now) && l.end.isAfter(now), orElse: () => Lesson.fromJson({}));
+ final _lesson = today.firstWhere(
+ (l) => l.start.isBefore(now) && l.end.isAfter(now),
+ orElse: () => Lesson.fromJson({}));
if (_lesson.start.year != 0) {
currentLesson = _lesson;
@@ -159,7 +208,8 @@ class LiveCardProvider extends ChangeNotifier {
currentLesson = null;
}
- final _next = today.firstWhere((l) => l.start.isAfter(now), orElse: () => Lesson.fromJson({}));
+ final _next = today.firstWhere((l) => l.start.isAfter(now),
+ orElse: () => Lesson.fromJson({}));
nextLessons = today.where((l) => l.start.isAfter(now)).toList();
if (_next.start.year != 0) {
@@ -168,7 +218,8 @@ class LiveCardProvider extends ChangeNotifier {
nextLesson = null;
}
- final _prev = today.lastWhere((l) => l.end.isBefore(now), orElse: () => Lesson.fromJson({}));
+ final _prev = today.lastWhere((l) => l.end.isBefore(now),
+ orElse: () => Lesson.fromJson({}));
if (_prev.start.year != 0) {
prevLesson = _prev;
@@ -198,7 +249,10 @@ class LiveCardProvider extends ChangeNotifier {
Duration get delay => _delay;
- bool _sameDate(DateTime a, DateTime b) => (a.year == b.year && a.month == b.month && a.day == b.day);
+ bool _sameDate(DateTime a, DateTime b) =>
+ (a.year == b.year && a.month == b.month && a.day == b.day);
- List _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? []).where((l) => _sameDate(l.date, _now())).toList();
+ List _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? [])
+ .where((l) => _sameDate(l.date, _now()))
+ .toList();
}
diff --git a/filcnaplo_premium/lib/ui/mobile/timetable/fs_timetable.dart b/filcnaplo_premium/lib/ui/mobile/timetable/fs_timetable.dart
index 611a462..1e3e429 100644
--- a/filcnaplo_premium/lib/ui/mobile/timetable/fs_timetable.dart
+++ b/filcnaplo_premium/lib/ui/mobile/timetable/fs_timetable.dart
@@ -11,7 +11,8 @@ import 'package:intl/intl.dart';
import 'package:i18n_extension/i18n_widget.dart';
class PremiumFSTimetable extends StatefulWidget {
- const PremiumFSTimetable({Key? key, required this.controller}) : super(key: key);
+ const PremiumFSTimetable({Key? key, required this.controller})
+ : super(key: key);
final TimetableController controller;
@@ -45,16 +46,21 @@ class _PremiumFSTimetableState extends State {
final everyLesson = days.expand((x) => x).toList();
everyLesson.sort((a, b) => a.start.compareTo(b.start));
- final int maxLessonCount = days.fold(0, (a, b) => math.max(a, b.where((l) => l.subject.id != "" || l.isEmpty).length));
+ final int maxLessonCount = days.fold(
+ 0,
+ (a, b) => math.max(
+ a, b.where((l) => l.subject.id != "" || l.isEmpty).length));
final int minIndex = int.tryParse(everyLesson.first.lessonIndex) ?? 0;
- final int maxIndex = int.tryParse(everyLesson.last.lessonIndex) ?? maxLessonCount;
+ final int maxIndex =
+ int.tryParse(everyLesson.last.lessonIndex) ?? maxLessonCount;
const prefixw = 40;
const padding = prefixw + 6 * 2;
final colw = (MediaQuery.of(context).size.width - padding) / days.length;
return Scaffold(
+ appBar: buildAppBar(),
body: ListView.builder(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 24.0),
@@ -63,7 +69,10 @@ class _PremiumFSTimetableState extends State {
List columns = [];
for (int dayIndex = -1; dayIndex < days.length; dayIndex++) {
- final dayOffset = dayIndex == -1 ? 0 : (int.tryParse(days[dayIndex].first.lessonIndex) ?? 0) - minIndex;
+ final dayOffset = dayIndex == -1
+ ? 0
+ : (int.tryParse(days[dayIndex].first.lessonIndex) ?? 0) -
+ minIndex;
final lessonIndex = index - 1;
if (dayIndex == -1) {
@@ -75,7 +84,9 @@ class _PremiumFSTimetableState extends State {
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
"${minIndex + lessonIndex}.",
- style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.secondary),
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ color: Theme.of(context).colorScheme.secondary),
),
),
));
@@ -85,12 +96,15 @@ class _PremiumFSTimetableState extends State {
continue;
}
- final lessons = days[dayIndex].where((l) => l.subject.id != "" || l.isEmpty).toList();
+ final lessons = days[dayIndex]
+ .where((l) => l.subject.id != "" || l.isEmpty)
+ .toList();
if (lessons.isEmpty) continue;
if (lessonIndex >= lessons.length) continue;
- if (dayIndex >= days.length || (lessonIndex + dayOffset) >= lessons.length) {
+ if (dayIndex >= days.length ||
+ (lessonIndex + dayOffset) >= lessons.length) {
columns.add(SizedBox(width: colw));
continue;
}
@@ -100,8 +114,11 @@ class _PremiumFSTimetableState extends State {
width: colw,
height: 40.0,
child: Text(
- DateFormat("EEEE", I18n.of(context).locale.languageCode).format(lessons.first.date).capital(),
- style: const TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
+ DateFormat("EEEE", I18n.of(context).locale.languageCode)
+ .format(lessons.first.date)
+ .capital(),
+ style: const TextStyle(
+ fontSize: 24.0, fontWeight: FontWeight.bold),
),
));
continue;
@@ -113,11 +130,14 @@ class _PremiumFSTimetableState extends State {
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Icon(FeatherIcons.slash, size: 18.0, color: AppColors.of(context).text.withOpacity(.3)),
+ Icon(FeatherIcons.slash,
+ size: 18.0,
+ color: AppColors.of(context).text.withOpacity(.3)),
const SizedBox(width: 8.0),
Text(
"Lyukas óra",
- style: TextStyle(color: AppColors.of(context).text.withOpacity(.3)),
+ style: TextStyle(
+ color: AppColors.of(context).text.withOpacity(.3)),
),
],
),
@@ -139,16 +159,27 @@ class _PremiumFSTimetableState extends State {
Row(
children: [
Icon(
- SubjectIcon.resolveVariant(context: context, subject: lessons[lessonIndex - dayOffset].subject),
+ SubjectIcon.resolveVariant(
+ context: context,
+ subject: lessons[lessonIndex - dayOffset].subject),
size: 18.0,
color: AppColors.of(context).text.withOpacity(.7),
),
const SizedBox(width: 8.0),
Expanded(
child: Text(
- lessons[lessonIndex - dayOffset].subject.renamedTo ?? lessons[lessonIndex - dayOffset].subject.name.capital(),
+ lessons[lessonIndex - dayOffset].subject.renamedTo ??
+ lessons[lessonIndex - dayOffset]
+ .subject
+ .name
+ .capital(),
maxLines: 1,
- style: TextStyle(fontStyle: lessons[lessonIndex - dayOffset].subject.isRenamed ? FontStyle.italic : null),
+ style: TextStyle(
+ fontStyle: lessons[lessonIndex - dayOffset]
+ .subject
+ .isRenamed
+ ? FontStyle.italic
+ : null),
overflow: TextOverflow.clip,
softWrap: false,
),
@@ -160,7 +191,9 @@ class _PremiumFSTimetableState extends State {
padding: const EdgeInsets.only(left: 26.0),
child: Text(
lessons[lessonIndex - dayOffset].room,
- style: TextStyle(color: AppColors.of(context).text.withOpacity(.5), overflow: TextOverflow.ellipsis),
+ style: TextStyle(
+ color: AppColors.of(context).text.withOpacity(.5),
+ overflow: TextOverflow.ellipsis),
),
),
],
@@ -176,4 +209,14 @@ class _PremiumFSTimetableState extends State {
),
);
}
+
+ AppBar buildAppBar() {
+ return AppBar(
+ backgroundColor: Colors.transparent,
+ automaticallyImplyLeading: false,
+ actions: const [
+ BackButton(),
+ ],
+ );
+ }
}