fixed notification minden is

This commit is contained in:
Kima 2023-08-30 01:22:41 +02:00
parent 91255182d2
commit c05b358b49
6 changed files with 499 additions and 366 deletions

View File

@ -20,7 +20,11 @@ const settingsDB = DatabaseStruct("settings", {
"grade_color4": int, "grade_color5": int, // grade colors "grade_color4": int, "grade_color5": int, // grade colors
"vibration_strength": int, "ab_weeks": int, "swap_ab_weeks": int, "vibration_strength": int, "ab_weeks": int, "swap_ab_weeks": int,
"notifications": int, "notifications_bitfield": int, "notifications": int, "notifications_bitfield": int,
"notification_poll_interval": int, "notifications_grades":int, "notifications_absences":int, "notifications_messages": int, "notifications_lessons":int, // notifications "notification_poll_interval": int,
"notifications_grades": int,
"notifications_absences": int,
"notifications_messages": int,
"notifications_lessons": int, // notifications
"x_filc_id": String, "graph_class_avg": int, "presentation_mode": int, "x_filc_id": String, "graph_class_avg": int, "presentation_mode": int,
"bell_delay": int, "bell_delay_enabled": int, "bell_delay": int, "bell_delay_enabled": int,
"grade_opening_fun": int, "icon_pack": String, "premium_scopes": String, "grade_opening_fun": int, "icon_pack": String, "premium_scopes": String,

View File

@ -1,9 +1,6 @@
import 'dart:ui';
import 'package:filcnaplo/api/providers/database_provider.dart'; import 'package:filcnaplo/api/providers/database_provider.dart';
import 'package:filcnaplo/api/providers/status_provider.dart'; import 'package:filcnaplo/api/providers/status_provider.dart';
import 'package:filcnaplo/api/providers/user_provider.dart'; import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo/database/init.dart';
import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/helpers/notification_helper.i18n.dart'; import 'package:filcnaplo/helpers/notification_helper.i18n.dart';
import 'package:filcnaplo_kreta_api/client/api.dart'; import 'package:filcnaplo_kreta_api/client/api.dart';
@ -14,7 +11,8 @@ import 'package:filcnaplo_kreta_api/models/lesson.dart';
import 'package:filcnaplo_kreta_api/models/week.dart'; import 'package:filcnaplo_kreta_api/models/week.dart';
import 'package:filcnaplo_kreta_api/providers/grade_provider.dart'; import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart'; import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart' hide Message; import 'package:flutter_local_notifications/flutter_local_notifications.dart'
hide Message;
import 'package:i18n_extension/i18n_widget.dart'; import 'package:i18n_extension/i18n_widget.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:filcnaplo_kreta_api/models/message.dart'; import 'package:filcnaplo_kreta_api/models/message.dart';
@ -24,10 +22,15 @@ class NotificationsHelper {
late SettingsProvider settingsProvider; late SettingsProvider settingsProvider;
late UserProvider userProvider; late UserProvider userProvider;
late KretaClient kretaClient; late KretaClient kretaClient;
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
List<T> combineLists<T, K>(List<T> list1, List<T> list2, K Function(T) keyExtractor,) { List<T> combineLists<T, K>(
Set<K> uniqueKeys = Set<K>(); List<T> list1,
List<T> list2,
K Function(T) keyExtractor,
) {
Set<K> uniqueKeys = <K>{};
List<T> combinedList = []; List<T> combinedList = [];
for (T item in list1) { for (T item in list1) {
@ -48,10 +51,10 @@ class NotificationsHelper {
return combinedList; return combinedList;
} }
String dayTitle(DateTime date) { String dayTitle(DateTime date) {
try { try {
return DateFormat("EEEE", I18n.locale.languageCode) return DateFormat("EEEE", I18n.locale.languageCode).format(date);
.format(date);
} catch (e) { } catch (e) {
return "Unknown"; return "Unknown";
} }
@ -60,13 +63,9 @@ class NotificationsHelper {
@pragma('vm:entry-point') @pragma('vm:entry-point')
void backgroundJob() async { void backgroundJob() async {
// initialize providers // initialize providers
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
database = DatabaseProvider(); database = DatabaseProvider();
var db = await initDB(database);
await database.init(); await database.init();
settingsProvider = settingsProvider = await database.query.getSettings(database);
await database.query.getSettings(database);
userProvider = await database.query.getUsers(settingsProvider); userProvider = await database.query.getUsers(settingsProvider);
if (userProvider.id != null && settingsProvider.notificationsEnabled) { if (userProvider.id != null && settingsProvider.notificationsEnabled) {
@ -75,78 +74,93 @@ class NotificationsHelper {
kretaClient = KretaClient( kretaClient = KretaClient(
user: userProvider, settings: settingsProvider, status: status); user: userProvider, settings: settingsProvider, status: status);
kretaClient.refreshLogin(); kretaClient.refreshLogin();
if(settingsProvider.notificationsGradesEnabled) gradeNotification(); if (settingsProvider.notificationsGradesEnabled) gradeNotification();
if(settingsProvider.notificationsAbsencesEnabled) absenceNotification(); if (settingsProvider.notificationsAbsencesEnabled) absenceNotification();
if(settingsProvider.notificationsMessagesEnabled) messageNotification(); if (settingsProvider.notificationsMessagesEnabled) messageNotification();
if(settingsProvider.notificationsLessonsEnabled) lessonNotification(); if (settingsProvider.notificationsLessonsEnabled) lessonNotification();
} }
} }
void gradeNotification() async { void gradeNotification() async {
// fetch grades // fetch grades
GradeProvider gradeProvider = GradeProvider( GradeProvider gradeProvider = GradeProvider(
settings: settingsProvider, settings: settingsProvider,
user: userProvider, user: userProvider,
database: database, database: database,
kreta: kretaClient); kreta: kretaClient);
gradeProvider.fetch(); gradeProvider.fetch();
List<Grade> grades = List<Grade> grades =
await database.userQuery.getGrades(userId: userProvider.id ?? ""); await database.userQuery.getGrades(userId: userProvider.id ?? "");
DateTime lastSeenGrade = DateTime lastSeenGrade =
await database.userQuery.lastSeenGrade(userId: userProvider.id ?? ""); await database.userQuery.lastSeenGrade(userId: userProvider.id ?? "");
// loop through grades and see which hasn't been seen yet // loop through grades and see which hasn't been seen yet
for (Grade grade in grades) { for (Grade grade in grades) {
// if grade is not a normal grade (1-5), don't show it // if grade is not a normal grade (1-5), don't show it
if ([1, 2, 3, 4, 5].contains(grade.value.value)) { if ([1, 2, 3, 4, 5].contains(grade.value.value)) {
// if the grade was added over a week ago, don't show it to avoid notification spam // if the grade was added over a week ago, don't show it to avoid notification spam
if (grade.seenDate.isAfter(lastSeenGrade) && grade.date.difference(DateTime.now()).inDays * -1 < 7) { if (grade.seenDate.isAfter(lastSeenGrade) &&
// send notificiation about new grade grade.date.difference(DateTime.now()).inDays * -1 < 7) {
const AndroidNotificationDetails androidNotificationDetails = // send notificiation about new grade
AndroidNotificationDetails('GRADES', 'Jegyek', AndroidNotificationDetails androidNotificationDetails =
channelDescription: 'Értesítés jegyek beírásakor', AndroidNotificationDetails(
importance: Importance.max, 'GRADES',
priority: Priority.max, 'Jegyek',
color: const Color(0xFF3D7BF4), channelDescription: 'Értesítés jegyek beírásakor',
ticker: 'Jegyek'); importance: Importance.max,
const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails); priority: Priority.max,
if(userProvider.getUsers().length == 1) { color: settingsProvider.customAccentColor,
await flutterLocalNotificationsPlugin.show( ticker: 'Jegyek',
grade.id.hashCode, );
"title_grade".i18n, NotificationDetails notificationDetails =
"body_grade".i18n.fill([ NotificationDetails(android: androidNotificationDetails);
grade.value.value.toString(), if (userProvider.getUsers().length == 1) {
grade.subject.isRenamed && await flutterLocalNotificationsPlugin.show(
settingsProvider.renamedSubjectsEnabled grade.id.hashCode,
? grade.subject.renamedTo! "title_grade".i18n,
: grade.subject.name "body_grade".i18n.fill(
]), [
notificationDetails); grade.value.value.toString(),
} else { // multiple users are added, also display student name grade.subject.isRenamed &&
await flutterLocalNotificationsPlugin.show( settingsProvider.renamedSubjectsEnabled
grade.id.hashCode, ? grade.subject.renamedTo!
"title_grade".i18n, : grade.subject.name
"body_grade_multiuser".i18n.fill([ ],
userProvider.displayName!, ),
grade.value.value.toString(), notificationDetails,
grade.subject.isRenamed && );
settingsProvider.renamedSubjectsEnabled } else {
? grade.subject.renamedTo! // multiple users are added, also display student name
: grade.subject.name await flutterLocalNotificationsPlugin.show(
]), grade.id.hashCode,
notificationDetails); "title_grade".i18n,
} "body_grade_multiuser".i18n.fill(
[
userProvider.displayName!,
grade.value.value.toString(),
grade.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? grade.subject.renamedTo!
: grade.subject.name
],
),
notificationDetails,
);
}
} }
} }
} }
// set grade seen status // set grade seen status
gradeProvider.seenAll(); gradeProvider.seenAll();
} }
void absenceNotification() async { void absenceNotification() async {
// get absences from api // get absences from api
List? absenceJson = await kretaClient.getAPI(KretaAPI.absences(userProvider.instituteCode ?? "")); List? absenceJson = await kretaClient
List<Absence> storedAbsences = await database.userQuery.getAbsences(userId: userProvider.id!); .getAPI(KretaAPI.absences(userProvider.instituteCode ?? ""));
if(absenceJson == null) { List<Absence> storedAbsences =
await database.userQuery.getAbsences(userId: userProvider.id!);
if (absenceJson == null) {
return; return;
} }
// format api absences to correct format while preserving isSeen value // format api absences to correct format while preserving isSeen value
@ -159,64 +173,77 @@ class NotificationsHelper {
return apiAbsence; return apiAbsence;
}).toList(); }).toList();
List<Absence> modifiedAbsences = []; List<Absence> modifiedAbsences = [];
if(absences != storedAbsences) { if (absences != storedAbsences) {
// remove absences that are not new // remove absences that are not new
absences.removeWhere((element) => storedAbsences.contains(element)); absences.removeWhere((element) => storedAbsences.contains(element));
for(Absence absence in absences) { for (Absence absence in absences) {
if(!absence.isSeen) { if (!absence.isSeen) {
absence.isSeen = true; absence.isSeen = true;
modifiedAbsences.add(absence); modifiedAbsences.add(absence);
const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('ABSENCES', 'Hiányzások', AndroidNotificationDetails(
channelDescription: 'Értesítés hiányzások beírásakor', 'ABSENCES',
importance: Importance.max, 'Hiányzások',
priority: Priority.max, channelDescription: 'Értesítés hiányzások beírásakor',
color: const Color(0xFF3D7BF4), importance: Importance.max,
ticker: 'Hiányzások'); priority: Priority.max,
const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails); color: settingsProvider.customAccentColor,
if(userProvider.getUsers().length == 1) { ticker: 'Hiányzások',
await flutterLocalNotificationsPlugin.show( );
absence.id.hashCode, NotificationDetails notificationDetails =
"title_absence".i18n, NotificationDetails(android: androidNotificationDetails);
"body_absence".i18n.fill([ if (userProvider.getUsers().length == 1) {
DateFormat("yyyy-MM-dd").format(absence.date), await flutterLocalNotificationsPlugin.show(
absence.subject.isRenamed && absence.id.hashCode,
settingsProvider.renamedSubjectsEnabled "title_absence".i18n,
? absence.subject.renamedTo! "body_absence".i18n.fill(
: absence.subject.name [
]), DateFormat("yyyy-MM-dd").format(absence.date),
notificationDetails); absence.subject.isRenamed &&
} else { settingsProvider.renamedSubjectsEnabled
await flutterLocalNotificationsPlugin.show( ? absence.subject.renamedTo!
absence.id.hashCode, : absence.subject.name
"title_absence".i18n, ],
"body_absence_multiuser".i18n.fill([ ),
userProvider.displayName!, notificationDetails,
DateFormat("yyyy-MM-dd").format(absence.date), );
absence.subject.isRenamed && } else {
settingsProvider.renamedSubjectsEnabled await flutterLocalNotificationsPlugin.show(
? absence.subject.renamedTo! absence.id.hashCode,
: absence.subject.name "title_absence".i18n,
]), "body_absence_multiuser".i18n.fill(
notificationDetails); [
} userProvider.displayName!,
DateFormat("yyyy-MM-dd").format(absence.date),
absence.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? absence.subject.renamedTo!
: absence.subject.name
],
),
notificationDetails,
);
}
} }
} }
} }
// combine modified absences and storedabsences list and save them to the database // combine modified absences and storedabsences list and save them to the database
List<Absence> combinedAbsences = combineLists( List<Absence> combinedAbsences = combineLists(
modifiedAbsences, modifiedAbsences,
storedAbsences, storedAbsences,
(Absence absence) => absence.id, (Absence absence) => absence.id,
); );
await database.userStore.storeAbsences(combinedAbsences, userId: userProvider.id!); await database.userStore
.storeAbsences(combinedAbsences, userId: userProvider.id!);
} }
void messageNotification() async { void messageNotification() async {
// get messages from api // get messages from api
List? messageJson = await kretaClient.getAPI(KretaAPI.messages("beerkezett")); List? messageJson =
List<Message> storedmessages = await database.userQuery.getMessages(userId: userProvider.id!); await kretaClient.getAPI(KretaAPI.messages("beerkezett"));
if(messageJson == null) { List<Message> storedmessages =
await database.userQuery.getMessages(userId: userProvider.id!);
if (messageJson == null) {
return; return;
} }
// format api messages to correct format while preserving isSeen value // format api messages to correct format while preserving isSeen value
@ -224,58 +251,69 @@ class NotificationsHelper {
List<Message> messages = []; List<Message> messages = [];
await Future.wait(List.generate(messageJson.length, (index) { await Future.wait(List.generate(messageJson.length, (index) {
return () async { return () async {
Map message = messageJson!.cast<Map>()[index]; Map message = messageJson.cast<Map>()[index];
Map? innerMessageJson = await kretaClient.getAPI(KretaAPI.message(message["azonosito"].toString())); Map? innerMessageJson = await kretaClient
if (innerMessageJson != null) messages.add(Message.fromJson(innerMessageJson, forceType: MessageType.inbox)); .getAPI(KretaAPI.message(message["azonosito"].toString()));
if (innerMessageJson != null) {
messages.add(
Message.fromJson(innerMessageJson, forceType: MessageType.inbox));
}
}(); }();
})); }));
for(Message message in messages) { for (Message message in messages) {
for(Message storedMessage in storedmessages) { for (Message storedMessage in storedmessages) {
if(message.id == storedMessage.id) { if (message.id == storedMessage.id) {
message.isSeen = storedMessage.isSeen; message.isSeen = storedMessage.isSeen;
} }
} }
} }
List<Message> modifiedmessages = []; List<Message> modifiedmessages = [];
if(messages != storedmessages) { if (messages != storedmessages) {
// remove messages that are not new // remove messages that are not new
messages.removeWhere((element) => storedmessages.contains(element)); messages.removeWhere((element) => storedmessages.contains(element));
for(Message message in messages) { for (Message message in messages) {
if(!message.isSeen) { if (!message.isSeen) {
message.isSeen = true; message.isSeen = true;
modifiedmessages.add(message); modifiedmessages.add(message);
const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('MESSAGES', 'Üzenetek', AndroidNotificationDetails(
channelDescription: 'Értesítés kapott üzenetekkor', 'MESSAGES',
importance: Importance.max, 'Üzenetek',
priority: Priority.max, channelDescription: 'Értesítés kapott üzenetekkor',
color: const Color(0xFF3D7BF4), importance: Importance.max,
ticker: 'Üzenetek'); priority: Priority.max,
const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails); color: settingsProvider.customAccentColor,
if(userProvider.getUsers().length == 1) { ticker: 'Üzenetek',
await flutterLocalNotificationsPlugin.show( );
message.id.hashCode, NotificationDetails notificationDetails =
message.author, NotificationDetails(android: androidNotificationDetails);
message.content.replaceAll(RegExp(r'<[^>]*>'), ''), if (userProvider.getUsers().length == 1) {
notificationDetails); await flutterLocalNotificationsPlugin.show(
} else { message.id.hashCode,
await flutterLocalNotificationsPlugin.show( message.author,
message.id.hashCode, message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
"(${userProvider.displayName!}) ${message.author}", notificationDetails,
message.content.replaceAll(RegExp(r'<[^>]*>'), ''), );
notificationDetails); } else {
} await flutterLocalNotificationsPlugin.show(
message.id.hashCode,
"(${userProvider.displayName!}) ${message.author}",
message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
notificationDetails,
);
}
} }
} }
} }
// combine modified messages and storedmessages list and save them to the database // combine modified messages and storedmessages list and save them to the database
List<Message> combinedmessages = combineLists( List<Message> combinedmessages = combineLists(
modifiedmessages, modifiedmessages,
storedmessages, storedmessages,
(Message message) => message.id, (Message message) => message.id,
); );
await database.userStore.storeMessages(combinedmessages, userId: userProvider.id!); await database.userStore
.storeMessages(combinedmessages, userId: userProvider.id!);
} }
void lessonNotification() async { void lessonNotification() async {
@ -300,15 +338,18 @@ class NotificationsHelper {
if (!lesson.isSeen && lesson.isChanged) { if (!lesson.isSeen && lesson.isChanged) {
lesson.isSeen = true; lesson.isSeen = true;
modifiedlessons.add(lesson); modifiedlessons.add(lesson);
const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('LESSONS', 'Órák', AndroidNotificationDetails(
channelDescription: 'LESSONS',
'Értesítés órák elmaradásáról, helyettesítésről', 'Órák',
importance: Importance.max, channelDescription:
priority: Priority.max, 'Értesítés órák elmaradásáról, helyettesítésről',
color: const Color(0xFF3D7BF4), importance: Importance.max,
ticker: 'Órák'); priority: Priority.max,
const NotificationDetails notificationDetails = color: settingsProvider.customAccentColor,
ticker: 'Órák',
);
NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails); NotificationDetails(android: androidNotificationDetails);
if (userProvider.getUsers().length == 1) { if (userProvider.getUsers().length == 1) {
if (lesson.status?.name == "Elmaradt") { if (lesson.status?.name == "Elmaradt") {
@ -316,40 +357,49 @@ class NotificationsHelper {
case "en_en": case "en_en":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_canceled".i18n.fill([ "body_lesson_canceled".i18n.fill(
[
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
dayTitle(lesson.date) dayTitle(lesson.date)
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
case "hu_hu": case "hu_hu":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_canceled".i18n.fill([ "body_lesson_canceled".i18n.fill(
[
dayTitle(lesson.date), dayTitle(lesson.date),
lesson.lessonIndex, lesson.lessonIndex,
lesson.name lesson.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
default: default:
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_canceled".i18n.fill([ "body_lesson_canceled".i18n.fill(
[
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
dayTitle(lesson.date) dayTitle(lesson.date)
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
} }
@ -358,49 +408,58 @@ class NotificationsHelper {
case "en_en": case "en_en":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_substituted".i18n.fill([ "body_lesson_substituted".i18n.fill(
[
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
dayTitle(lesson.date), dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo! ? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name : lesson.substituteTeacher!.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
case "hu_hu": case "hu_hu":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_substituted".i18n.fill([ "body_lesson_substituted".i18n.fill(
[
dayTitle(lesson.date), dayTitle(lesson.date),
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
lesson.substituteTeacher!.isRenamed lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo! ? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name : lesson.substituteTeacher!.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
default: default:
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_substituted".i18n.fill([ "body_lesson_substituted".i18n.fill(
[
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
dayTitle(lesson.date), dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo! ? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name : lesson.substituteTeacher!.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
} }
@ -411,43 +470,52 @@ class NotificationsHelper {
case "en_en": case "en_en":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_canceled".i18n.fill([ "body_lesson_canceled".i18n.fill(
[
userProvider.displayName!, userProvider.displayName!,
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
dayTitle(lesson.date) dayTitle(lesson.date)
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
case "hu_hu": case "hu_hu":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_canceled".i18n.fill([ "body_lesson_canceled".i18n.fill(
[
userProvider.displayName!, userProvider.displayName!,
dayTitle(lesson.date), dayTitle(lesson.date),
lesson.lessonIndex, lesson.lessonIndex,
lesson.name lesson.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
default: default:
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_canceled".i18n.fill([ "body_lesson_canceled".i18n.fill(
[
userProvider.displayName!, userProvider.displayName!,
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
dayTitle(lesson.date) dayTitle(lesson.date)
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
} }
@ -456,9 +524,10 @@ class NotificationsHelper {
case "en_en": case "en_en":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_substituted".i18n.fill([ "body_lesson_substituted".i18n.fill(
[
userProvider.displayName!, userProvider.displayName!,
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
@ -466,16 +535,19 @@ class NotificationsHelper {
lesson.substituteTeacher!.isRenamed lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo! ? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name : lesson.substituteTeacher!.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
case "hu_hu": case "hu_hu":
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_substituted".i18n.fill([ "body_lesson_substituted".i18n.fill(
[
userProvider.displayName!, userProvider.displayName!,
dayTitle(lesson.date), dayTitle(lesson.date),
lesson.lessonIndex, lesson.lessonIndex,
@ -483,16 +555,19 @@ class NotificationsHelper {
lesson.substituteTeacher!.isRenamed lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo! ? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name : lesson.substituteTeacher!.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
default: default:
{ {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode, lesson.id.hashCode,
"title_lesson".i18n, "title_lesson".i18n,
"body_lesson_substituted".i18n.fill([ "body_lesson_substituted".i18n.fill(
[
userProvider.displayName!, userProvider.displayName!,
lesson.lessonIndex, lesson.lessonIndex,
lesson.name, lesson.name,
@ -500,8 +575,10 @@ class NotificationsHelper {
lesson.substituteTeacher!.isRenamed lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo! ? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name : lesson.substituteTeacher!.name
]), ],
notificationDetails); ),
notificationDetails,
);
break; break;
} }
} }

View File

@ -1,7 +1,6 @@
import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/theme/colors/colors.dart'; import 'package:filcnaplo/theme/colors/colors.dart';
import 'package:filcnaplo/ui/widgets/grade/grade_tile.dart'; import 'package:filcnaplo_mobile_ui/common/beta_chip.dart';
import 'package:filcnaplo_kreta_api/models/grade.dart';
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart'; import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
import 'package:filcnaplo_mobile_ui/common/panel/panel_button.dart'; import 'package:filcnaplo_mobile_ui/common/panel/panel_button.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -21,15 +20,23 @@ class MenuNotifications extends StatelessWidget {
padding: const EdgeInsets.only(left: 14.0), padding: const EdgeInsets.only(left: 14.0),
onPressed: () { onPressed: () {
Navigator.of(context, rootNavigator: true).push( Navigator.of(context, rootNavigator: true).push(
CupertinoPageRoute(builder: (context) => NotificationsScreen()), CupertinoPageRoute(builder: (context) => const NotificationsScreen()),
); );
}, },
title: Text( title: Row(
"notifications_screen".i18n, children: [
style: TextStyle( Text(
color: AppColors.of(context) "notifications_screen".i18n,
.text style: TextStyle(
.withOpacity(settings.notificationsEnabled ? 1.0 : .5)), color: AppColors.of(context)
.text
.withOpacity(settings.notificationsEnabled ? 1.0 : .5)),
),
const SizedBox(width: 5.0),
BetaChip(
disabled: !settings.notificationsEnabled,
),
],
), ),
leading: settings.notificationsEnabled leading: settings.notificationsEnabled
? const Icon(FeatherIcons.messageSquare) ? const Icon(FeatherIcons.messageSquare)
@ -48,128 +55,172 @@ class MenuNotifications extends StatelessWidget {
} }
class NotificationsScreen extends StatelessWidget { class NotificationsScreen extends StatelessWidget {
NotificationsScreen({super.key}); const NotificationsScreen({super.key});
late SettingsProvider settings;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
settings = Provider.of<SettingsProvider>(context); SettingsProvider settings = Provider.of<SettingsProvider>(context);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor, surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
leading: BackButton(color: AppColors.of(context).text), leading: BackButton(color: AppColors.of(context).text),
title: Text( title: Text(
"notifications_screen".i18n, "notifications_screen".i18n,
style: TextStyle(color: AppColors.of(context).text), style: TextStyle(color: AppColors.of(context).text),
),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
child: Panel(
child: Column(
children: [
Material(
type: MaterialType.transparency,
child: SwitchListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
value: settings.notificationsGradesEnabled,
onChanged: (v) =>
settings.update(notificationsGradesEnabled: v),
title: Row(
children: [
Icon(
FeatherIcons.bookmark,
color: settings.notificationsGradesEnabled
? Theme.of(context).colorScheme.secondary
: AppColors.of(context).text.withOpacity(.25),
),
const SizedBox(width: 14.0),
Expanded(
child: Text(
"grades".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsGradesEnabled
? 1.0
: .5,
),
),
),
),
],
),
),
),
Material(
type: MaterialType.transparency,
child: SwitchListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
value: settings.notificationsAbsencesEnabled,
onChanged: (v) =>
settings.update(notificationsAbsencesEnabled: v),
title: Row(
children: [
Icon(
FeatherIcons.clock,
color: settings.notificationsAbsencesEnabled
? Theme.of(context).colorScheme.secondary
: AppColors.of(context).text.withOpacity(.25),
),
const SizedBox(width: 14.0),
Expanded(
child: Text(
"absences".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsAbsencesEnabled
? 1.0
: .5,
),
),
),
),
],
),
),
),
Material(
type: MaterialType.transparency,
child: SwitchListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
value: settings.notificationsMessagesEnabled,
onChanged: (v) =>
settings.update(notificationsMessagesEnabled: v),
title: Row(
children: [
Icon(
FeatherIcons.messageSquare,
color: settings.notificationsMessagesEnabled
? Theme.of(context).colorScheme.secondary
: AppColors.of(context).text.withOpacity(.25),
),
const SizedBox(width: 14.0),
Expanded(
child: Text(
"messages".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsMessagesEnabled
? 1.0
: .5,
),
),
),
),
],
),
),
),
Material(
type: MaterialType.transparency,
child: SwitchListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
value: settings.notificationsLessonsEnabled,
onChanged: (v) =>
settings.update(notificationsLessonsEnabled: v),
title: Row(
children: [
Icon(
FeatherIcons.calendar,
color: settings.notificationsLessonsEnabled
? Theme.of(context).colorScheme.secondary
: AppColors.of(context).text.withOpacity(.25),
),
const SizedBox(width: 14.0),
Expanded(
child: Text(
"lessons".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsLessonsEnabled
? 1.0
: .5,
),
),
),
),
],
),
),
),
],
),
), ),
), ),
body: Padding( ),
padding: );
const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
child: SingleChildScrollView(
child: Panel(
child: Column(children: [
SwitchListTile(
value: settings.notificationsGradesEnabled,
onChanged: (v) => {settings.update(notificationsGradesEnabled: v)},
title: Row(
children: [
GradeValueWidget(GradeValue(5, "", "", 100), fill: true, size: 30, color: settings.gradeColors[4].withOpacity(
settings.notificationsGradesEnabled ? 1.0 : .5)),
const SizedBox(width: 14.0),
Expanded(
child: Text(
"grades".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsGradesEnabled ? 1.0 : .5),
),
),
),
],
),
),
SwitchListTile(
value: settings.notificationsAbsencesEnabled,
onChanged: (v) => {settings.update(notificationsAbsencesEnabled: v)},
title: Row(
children: [
const SizedBox(width: 8),
settings.notificationsAbsencesEnabled
? const Icon(FeatherIcons.clock)
: Icon(FeatherIcons.clock,
color:
AppColors.of(context).text.withOpacity(.25)),
const SizedBox(width: 23.0),
Expanded(
child: Text(
"absences".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsAbsencesEnabled ? 1.0 : .5),
),
),
),
],
),
),
SwitchListTile(
value: settings.notificationsMessagesEnabled,
onChanged: (v) => {settings.update(notificationsMessagesEnabled: v)},
title: Row(
children: [
const SizedBox(width: 8),
settings.notificationsMessagesEnabled
? const Icon(FeatherIcons.messageSquare)
: Icon(FeatherIcons.messageSquare,
color:
AppColors.of(context).text.withOpacity(.25)),
const SizedBox(width: 23.0),
Expanded(
child: Text(
"messages".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsMessagesEnabled ? 1.0 : .5),
),
),
),
],
),
),
SwitchListTile(
value: settings.notificationsLessonsEnabled,
onChanged: (v) => {settings.update(notificationsLessonsEnabled: v)},
title: Row(
children: [
const SizedBox(width: 8),
settings.notificationsLessonsEnabled
? const Icon(FeatherIcons.calendar)
: Icon(FeatherIcons.calendar,
color:
AppColors.of(context).text.withOpacity(.25)),
const SizedBox(width: 23.0),
Expanded(
child: Text(
"lessons".i18n,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.0,
color: AppColors.of(context).text.withOpacity(
settings.notificationsLessonsEnabled ? 1.0 : .5),
),
),
),
],
),
)
]),
))));
} }
} }

View File

@ -15,7 +15,6 @@ import 'package:filcnaplo/models/user.dart';
import 'package:filcnaplo/theme/colors/colors.dart'; import 'package:filcnaplo/theme/colors/colors.dart';
import 'package:filcnaplo_kreta_api/client/client.dart'; import 'package:filcnaplo_kreta_api/client/client.dart';
import 'package:filcnaplo_mobile_ui/common/action_button.dart'; import 'package:filcnaplo_mobile_ui/common/action_button.dart';
import 'package:filcnaplo_mobile_ui/common/beta_chip.dart';
import 'package:filcnaplo_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart'; import 'package:filcnaplo_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart';
import 'package:filcnaplo_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu_item.dart'; import 'package:filcnaplo_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu_item.dart';
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart'; import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
@ -453,9 +452,8 @@ class _SettingsScreenState extends State<SettingsScreen>
), ),
), ),
Material( Material(
type: MaterialType.transparency, type: MaterialType.transparency,
child: MenuNotifications(settings: settings) child: MenuNotifications(settings: settings)),
),
], ],
), ),
), ),
@ -708,7 +706,7 @@ class _SettingsScreenState extends State<SettingsScreen>
padding: padding:
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0), const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
child: Panel( child: Panel(
title: Text("notifications".i18n), title: Text("popups".i18n),
child: Material( child: Material(
type: MaterialType.transparency, type: MaterialType.transparency,
child: SwitchListTile( child: SwitchListTile(

View File

@ -27,6 +27,7 @@ extension SettingsLocalization on String {
"grade_colors": "Grade Colors", "grade_colors": "Grade Colors",
"live_activity_color": "Live Activity Color", "live_activity_color": "Live Activity Color",
"notifications": "Notifications", "notifications": "Notifications",
"popups": "Pop-up Alerts",
"news": "News", "news": "News",
"extras": "Extras", "extras": "Extras",
"about": "About", "about": "About",
@ -97,6 +98,7 @@ extension SettingsLocalization on String {
"grade_colors": "Jegyek színei", "grade_colors": "Jegyek színei",
"live_activity_color": "Live Activity színe", "live_activity_color": "Live Activity színe",
"notifications": "Értesítések", "notifications": "Értesítések",
"popups": "Pop-up értesítések",
"news": "Hírek", "news": "Hírek",
"extras": "Extrák", "extras": "Extrák",
"about": "Névjegy", "about": "Névjegy",
@ -167,6 +169,7 @@ extension SettingsLocalization on String {
"grade_colors": "Grad Farben", "grade_colors": "Grad Farben",
"live_activity_color": "Live Activity Farben", "live_activity_color": "Live Activity Farben",
"notifications": "Mitteilung", "notifications": "Mitteilung",
"popups": "Popup-Nachrichten",
"news": "Nachrichten", "news": "Nachrichten",
"extras": "Extras", "extras": "Extras",
"about": "Informationen", "about": "Informationen",

View File

@ -172,7 +172,7 @@ class _AllSumBodyState extends State<AllSumBody> {
], ],
); );
// TODO: az orakat es a hazikat szarul keri le, de majd meg lesz csinalva // TO-DO: az orakat es a hazikat szarul keri le, de majd meg lesz csinalva
if (firstSixTiles.length < 6) { if (firstSixTiles.length < 6) {
firstSixTiles.add(w); firstSixTiles.add(w);
} else if (lastSixTiles.length < 6) { } else if (lastSixTiles.length < 6) {