fixed project problems (warnings)

This commit is contained in:
Kima 2024-03-11 23:29:20 +01:00
parent 9ea0085ddb
commit 917d6d01db
34 changed files with 602 additions and 552 deletions

View File

@ -17,7 +17,7 @@ import 'package:refilc_kreta_api/providers/grade_provider.dart';
import 'package:refilc_kreta_api/providers/timetable_provider.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'
hide Message;
import 'package:i18n_extension/i18n_widget.dart';
import 'package:i18n_extension/i18n_extension.dart';
import 'package:intl/intl.dart';
import 'package:refilc_kreta_api/models/message.dart';
@ -38,7 +38,6 @@ class NotificationsHelper {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
String dayTitle(DateTime date) {
try {
String dayTitle =
@ -50,7 +49,7 @@ class NotificationsHelper {
return "Unknown";
}
}
@pragma('vm:entry-point')
void backgroundJob() async {
// initialize providers
@ -65,25 +64,37 @@ class NotificationsHelper {
// Process notifications for each user asynchronously
await Future.forEach(users, (User user) async {
// Create a new instance of userProvider for each user
UserProvider userProviderForUser = await database.query.getUsers(settingsProvider);
UserProvider userProviderForUser =
await database.query.getUsers(settingsProvider);
userProviderForUser.setUser(user.id);
// Refresh kreta login for current user
final status = StatusProvider();
KretaClient kretaClientForUser = KretaClient(
user: userProviderForUser, settings: settingsProvider, status: status);
user: userProviderForUser,
settings: settingsProvider,
status: status);
await kretaClientForUser.refreshLogin();
// Process notifications for current user
if (settingsProvider.notificationsGradesEnabled) await gradeNotification(userProviderForUser, kretaClientForUser);
if (settingsProvider.notificationsAbsencesEnabled) await absenceNotification(userProviderForUser, kretaClientForUser);
if (settingsProvider.notificationsMessagesEnabled) await messageNotification(userProviderForUser, kretaClientForUser);
if (settingsProvider.notificationsLessonsEnabled) await lessonNotification(userProviderForUser, kretaClientForUser);
if (settingsProvider.notificationsGradesEnabled) {
await gradeNotification(userProviderForUser, kretaClientForUser);
}
if (settingsProvider.notificationsAbsencesEnabled) {
await absenceNotification(userProviderForUser, kretaClientForUser);
}
if (settingsProvider.notificationsMessagesEnabled) {
await messageNotification(userProviderForUser, kretaClientForUser);
}
if (settingsProvider.notificationsLessonsEnabled) {
await lessonNotification(userProviderForUser, kretaClientForUser);
}
});
}
}
Future<void> gradeNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
Future<void> gradeNotification(
UserProvider currentuserProvider, KretaClient currentKretaClient) async {
// fetch grades
GradeProvider gradeProvider = GradeProvider(
settings: settingsProvider,
@ -119,56 +130,56 @@ class NotificationsHelper {
NotificationDetails(android: androidNotificationDetails);
if (currentuserProvider.getUsers().length == 1) {
await flutterLocalNotificationsPlugin.show(
grade.id.hashCode,
"title_grade".i18n,
"body_grade".i18n.fill(
[
grade.value.value.toString(),
grade.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? grade.subject.renamedTo!
: grade.subject.name
],
),
notificationDetails,
payload: "grades"
);
grade.id.hashCode,
"title_grade".i18n,
"body_grade".i18n.fill(
[
grade.value.value.toString(),
grade.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? grade.subject.renamedTo!
: grade.subject.name
],
),
notificationDetails,
payload: "grades");
} else {
// multiple users are added, also display student name
await flutterLocalNotificationsPlugin.show(
grade.id.hashCode,
"title_grade".i18n,
"body_grade_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
grade.value.value.toString(),
grade.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? grade.subject.renamedTo!
: grade.subject.name
],
),
notificationDetails,
payload: "grades"
);
grade.id.hashCode,
"title_grade".i18n,
"body_grade_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
grade.value.value.toString(),
grade.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? grade.subject.renamedTo!
: grade.subject.name
],
),
notificationDetails,
payload: "grades");
}
}
}
}
// set grade seen status
database.userStore.storeLastSeen(DateTime.now(), userId: currentuserProvider.id!, category: LastSeenCategory.grade);
database.userStore.storeLastSeen(DateTime.now(),
userId: currentuserProvider.id!, category: LastSeenCategory.grade);
});
}
Future<void> absenceNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
Future<void> absenceNotification(
UserProvider currentuserProvider, KretaClient currentKretaClient) async {
// get absences from api
List? absenceJson = await currentKretaClient
.getAPI(KretaAPI.absences(currentuserProvider.instituteCode ?? ""));
if (absenceJson == null) {
return;
}
DateTime lastSeenAbsence = await database.userQuery
.lastSeen(userId: currentuserProvider.id!, category: LastSeenCategory.absence);
DateTime lastSeenAbsence = await database.userQuery.lastSeen(
userId: currentuserProvider.id!, category: LastSeenCategory.absence);
// format api absences
List<Absence> absences =
absenceJson.map((e) => Absence.fromJson(e)).toList();
@ -188,425 +199,429 @@ class NotificationsHelper {
NotificationDetails(android: androidNotificationDetails);
if (currentuserProvider.getUsers().length == 1) {
await flutterLocalNotificationsPlugin.show(
absence.id.hashCode,
"title_absence"
.i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
"body_absence".i18n.fill(
[
DateFormat("yyyy-MM-dd").format(absence.date),
absence.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? absence.subject.renamedTo!
: absence.subject.name
],
),
absence.id.hashCode,
"title_absence"
.i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
"body_absence".i18n.fill(
[
DateFormat("yyyy-MM-dd").format(absence.date),
absence.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? absence.subject.renamedTo!
: absence.subject.name
],
),
notificationDetails,
payload: "absences");
} else {
await flutterLocalNotificationsPlugin.show(
absence.id.hashCode,
"title_absence"
.i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
"body_absence_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
DateFormat("yyyy-MM-dd").format(absence.date),
absence.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? absence.subject.renamedTo!
: absence.subject.name
],
),
notificationDetails,
payload: "absences");
}
}
}
await database.userStore.storeLastSeen(DateTime.now(),
userId: currentuserProvider.id!, category: LastSeenCategory.absence);
}
Future<void> messageNotification(
UserProvider currentuserProvider, KretaClient currentKretaClient) async {
// get messages from api
List? messageJson =
await currentKretaClient.getAPI(KretaAPI.messages("beerkezett"));
if (messageJson == null) {
return;
}
// format api messages to correct format
// Parse messages
List<Message> messages = [];
await Future.wait(List.generate(messageJson.length, (index) {
return () async {
Map message = messageJson.cast<Map>()[index];
Map? innerMessageJson = await currentKretaClient
.getAPI(KretaAPI.message(message["azonosito"].toString()));
await Future.delayed(const Duration(seconds: 1));
if (innerMessageJson != null) {
messages.add(
Message.fromJson(innerMessageJson, forceType: MessageType.inbox));
}
}();
}));
DateTime lastSeenMessage = await database.userQuery.lastSeen(
userId: currentuserProvider.id!, category: LastSeenCategory.message);
for (Message message in messages) {
if (message.date.isAfter(lastSeenMessage)) {
AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
'MESSAGES',
'Üzenetek',
channelDescription: 'Értesítés kapott üzenetekkor',
importance: Importance.max,
priority: Priority.max,
color: settingsProvider.customAccentColor,
ticker: 'Üzenetek',
);
NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
if (currentuserProvider.getUsers().length == 1) {
await flutterLocalNotificationsPlugin.show(
message.id.hashCode,
message.author,
message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
notificationDetails,
payload: "absences"
payload: "messages",
);
} else {
await flutterLocalNotificationsPlugin.show(
absence.id.hashCode,
"title_absence"
.i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
"body_absence_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
DateFormat("yyyy-MM-dd").format(absence.date),
absence.subject.isRenamed &&
settingsProvider.renamedSubjectsEnabled
? absence.subject.renamedTo!
: absence.subject.name
],
),
message.id.hashCode,
"(${currentuserProvider.displayName!}) ${message.author}",
message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
notificationDetails,
payload: "absences"
payload: "messages",
);
}
}
}
await database.userStore.storeLastSeen(DateTime.now(),
userId: currentuserProvider.id!, category: LastSeenCategory.absence);
userId: currentuserProvider.id!, category: LastSeenCategory.message);
}
Future<void> messageNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
// get messages from api
List? messageJson =
await currentKretaClient.getAPI(KretaAPI.messages("beerkezett"));
if (messageJson == null) {
return;
}
// format api messages to correct format
// Parse messages
List<Message> messages = [];
await Future.wait(List.generate(messageJson.length, (index) {
return () async {
Map message = messageJson.cast<Map>()[index];
Map? innerMessageJson = await currentKretaClient
.getAPI(KretaAPI.message(message["azonosito"].toString()));
await Future.delayed(const Duration(seconds: 1));
if (innerMessageJson != null) {
messages.add(Message.fromJson(innerMessageJson,
forceType: MessageType.inbox));
Future<void> lessonNotification(
UserProvider currentuserProvider, KretaClient currentKretaClient) async {
// get lessons from api
TimetableProvider timetableProvider = TimetableProvider(
user: currentuserProvider,
database: database,
kreta: currentKretaClient);
await timetableProvider.restoreUser();
await timetableProvider.fetch(week: Week.current());
List<Lesson> apilessons = timetableProvider.getWeek(Week.current()) ?? [];
DateTime lastSeenLesson = await database.userQuery.lastSeen(
userId: currentuserProvider.id!, category: LastSeenCategory.lesson);
Lesson? latestLesson;
for (Lesson lesson in apilessons) {
if ((lesson.status?.name != "Elmaradt" ||
lesson.substituteTeacher?.name != "") &&
lesson.date.isAfter(latestLesson?.start ?? DateTime(1970))) {
latestLesson = lesson;
}
if (lesson.date.isAfter(lastSeenLesson)) {
AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
'LESSONS',
'Órák',
channelDescription: 'Értesítés órák elmaradásáról, helyettesítésről',
importance: Importance.max,
priority: Priority.max,
color: settingsProvider.customAccentColor,
ticker: 'Órák',
);
NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
if (currentuserProvider.getUsers().length == 1) {
if (lesson.status?.name == "Elmaradt") {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable");
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled".i18n.fill(
[
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name
],
),
notificationDetails,
payload: "timetable");
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable");
break;
}
}
}();
}));
DateTime lastSeenMessage = await database.userQuery.lastSeen(
userId: currentuserProvider.id!, category: LastSeenCategory.message);
for (Message message in messages) {
if (message.date.isAfter(lastSeenMessage)) {
AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
'MESSAGES',
'Üzenetek',
channelDescription: 'Értesítés kapott üzenetekkor',
importance: Importance.max,
priority: Priority.max,
color: settingsProvider.customAccentColor,
ticker: 'Üzenetek',
);
NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
if (currentuserProvider.getUsers().length == 1) {
await flutterLocalNotificationsPlugin.show(
message.id.hashCode,
message.author,
message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
notificationDetails,
payload: "messages",
);
} else {
await flutterLocalNotificationsPlugin.show(
message.id.hashCode,
"(${currentuserProvider.displayName!}) ${message.author}",
message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
notificationDetails,
payload: "messages",
);
} else if (lesson.substituteTeacher?.name != "" &&
lesson.substituteTeacher != null) {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted".i18n.fill(
[
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name,
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
}
}
}
await database.userStore.storeLastSeen(DateTime.now(),
userId: currentuserProvider.id!, category: LastSeenCategory.message);
}
Future<void> lessonNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
// get lessons from api
TimetableProvider timetableProvider = TimetableProvider(
user: currentuserProvider, database: database, kreta: currentKretaClient);
await timetableProvider.restoreUser();
await timetableProvider.fetch(week: Week.current());
List<Lesson> apilessons =
timetableProvider.getWeek(Week.current()) ?? [];
DateTime lastSeenLesson = await database.userQuery.lastSeen(
userId: currentuserProvider.id!, category: LastSeenCategory.lesson);
Lesson? latestLesson;
for (Lesson lesson in apilessons) {
if((lesson.status?.name != "Elmaradt" || lesson.substituteTeacher?.name != "") && lesson.date.isAfter(latestLesson?.start ?? DateTime(1970))) {
latestLesson = lesson;
} else {
if (lesson.status?.name == "Elmaradt") {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable",
);
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable",
);
break;
}
}
if (lesson.date.isAfter(lastSeenLesson)) {
AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
'LESSONS',
'Órák',
channelDescription:
'Értesítés órák elmaradásáról, helyettesítésről',
importance: Importance.max,
priority: Priority.max,
color: settingsProvider.customAccentColor,
ticker: 'Órák',
);
NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
if (currentuserProvider.getUsers().length == 1) {
if (lesson.status?.name == "Elmaradt") {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable"
);
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled".i18n.fill(
[
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name
],
),
notificationDetails,
payload: "timetable"
);
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable"
);
break;
}
} else if (lesson.substituteTeacher?.name != "") {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
} else if (lesson.substituteTeacher?.name != "" && lesson.substituteTeacher != null) {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted".i18n.fill(
[
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name,
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted".i18n.fill(
[
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name,
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
}
} else {
if (lesson.status?.name == "Elmaradt") {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable",
);
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_canceled_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date)
],
),
notificationDetails,
payload: "timetable",
);
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
} else if (lesson.substituteTeacher?.name != "") {
switch (I18n.localeStr) {
case "en_en":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
case "hu_hu":
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
dayTitle(lesson.date),
lesson.lessonIndex,
lesson.name,
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
default:
{
await flutterLocalNotificationsPlugin.show(
lesson.id.hashCode,
"title_lesson".i18n,
"body_lesson_substituted_multiuser".i18n.fill(
[
currentuserProvider.displayName!,
lesson.lessonIndex,
lesson.name,
dayTitle(lesson.date),
lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo!
: lesson.substituteTeacher!.name
],
),
notificationDetails,
payload: "timetable",
);
break;
}
}
}
}
}
}
// lesson.date does not contain time, only the date
await database.userStore.storeLastSeen(latestLesson?.start ?? DateTime.now(),
userId: currentuserProvider.id!, category: LastSeenCategory.lesson);
}
// Called when the user taps a notification
void onDidReceiveNotificationResponse(NotificationResponse notificationResponse) async {
final String? payload = notificationResponse.payload;
if (notificationResponse.payload != null) {
debugPrint('notification payload: $payload');
}
switch(payload) {
case "timetable":
locator<NavigationService>().navigateTo("timetable");
break;
case "grades":
locator<NavigationService>().navigateTo("grades");
break;
case "messages":
locator<NavigationService>().navigateTo("messages");
break;
case "absences":
locator<NavigationService>().navigateTo("absences");
break;
case "settings":
locator<NavigationService>().navigateTo("settings");
break;
default:
break;
}
}
// Set all notification categories to seen
Future<void> setAllCategoriesSeen(UserProvider userProvider) async {
if(userProvider.id != null) {
for(LastSeenCategory category in LastSeenCategory.values) {
await database.userStore.storeLastSeen(DateTime.now(), userId: userProvider.id!, category: category);
}
}
}
}
// lesson.date does not contain time, only the date
await database.userStore.storeLastSeen(
latestLesson?.start ?? DateTime.now(),
userId: currentuserProvider.id!,
category: LastSeenCategory.lesson);
}
// Called when the user taps a notification
void onDidReceiveNotificationResponse(
NotificationResponse notificationResponse) async {
final String? payload = notificationResponse.payload;
if (notificationResponse.payload != null) {
debugPrint('notification payload: $payload');
}
switch (payload) {
case "timetable":
locator<NavigationService>().navigateTo("timetable");
break;
case "grades":
locator<NavigationService>().navigateTo("grades");
break;
case "messages":
locator<NavigationService>().navigateTo("messages");
break;
case "absences":
locator<NavigationService>().navigateTo("absences");
break;
case "settings":
locator<NavigationService>().navigateTo("settings");
break;
default:
break;
}
}
// Set all notification categories to seen
Future<void> setAllCategoriesSeen(UserProvider userProvider) async {
if (userProvider.id != null) {
for (LastSeenCategory category in LastSeenCategory.values) {
await database.userStore.storeLastSeen(DateTime.now(),
userId: userProvider.id!, category: category);
}
}
}
}

View File

@ -8,6 +8,7 @@ class ShareHelper {
Share.share(text, subject: subject);
// ignore: deprecated_member_use
static Future<void> shareFile(String path, {String? text, String? subject}) =>
// ignore: deprecated_member_use
Share.shareFiles([path], text: text, subject: subject);
static Future<void> shareAttachment(Attachment attachment,

View File

@ -10,7 +10,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:refilc/app.dart';
import 'package:flutter/services.dart';
import 'package:refilc/utils/navigation_service.dart';
import 'package:refilc/utils/service_locator.dart';
import 'package:refilc_mobile_ui/screens/error_screen.dart';
import 'package:refilc_mobile_ui/screens/error_report_screen.dart';
@ -34,11 +33,10 @@ void main() async {
// Custom error page
ErrorWidget.builder = errorBuilder;
// initialize stripe key
stripe.Stripe.publishableKey =
'pk_test_51Oo7iUBS0FxsTGxKjGZSQqzDKWHY5ZFYM9XeI0qSdIh2w8jWy6GhHlYpT7GLTzgpl1xhE5YP4BXpA4gMZqPmgMId00cGFYFzbh';
// initialize stripe key
// stripe.Stripe.publishableKey =
// 'pk_test_51Oo7iUBS0FxsTGxKjGZSQqzDKWHY5ZFYM9XeI0qSdIh2w8jWy6GhHlYpT7GLTzgpl1xhE5YP4BXpA4gMZqPmgMId00cGFYFzbh';
BackgroundFetch.registerHeadlessTask(backgroundHeadlessTask);
@ -126,7 +124,8 @@ class Startup {
// Initialize notifications
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: NotificationsHelper().onDidReceiveNotificationResponse,
onDidReceiveNotificationResponse:
NotificationsHelper().onDidReceiveNotificationResponse,
);
}

View File

@ -138,11 +138,15 @@ class ThirdPartyProvider with ChangeNotifier {
_googleCalendars = (await calendarApi.calendarList.list()).items ?? [];
print(_googleCalendars);
if (kDebugMode) {
print(_googleCalendars);
}
notifyListeners();
} catch (e) {
print(e);
if (kDebugMode) {
print(e);
}
// await _googleSignIn.signOut();
}
}

View File

@ -46,14 +46,16 @@ extension DateFormatUtils on DateTime {
DateTime now = DateTime.now();
if (now.year == year && now.month == month && now.day == day) {
if (hour == 0 && minute == 0 && second == 0 || forceToday)
if (hour == 0 && minute == 0 && second == 0 || forceToday) {
return "Today".i18n;
}
return DateFormat("HH:mm").format(this);
}
if (now.year == year &&
now.month == month &&
now.subtract(const Duration(days: 1)).day == day)
now.subtract(const Duration(days: 1)).day == day) {
return "Yesterday".i18n;
}
if (now.year == year &&
now.month == month &&
now.add(const Duration(days: 1)).day == day) return "Tomorrow".i18n;

View File

@ -3,15 +3,14 @@ import 'package:flutter/material.dart';
class FilterBar extends StatelessWidget implements PreferredSizeWidget {
const FilterBar({
Key? key,
super.key,
required this.items,
required this.controller,
this.onTap,
this.padding = const EdgeInsets.symmetric(horizontal: 24.0),
this.disableFading = false,
this.scrollable = true,
}) : assert(items.length == controller.length),
super(key: key);
}) : assert(items.length == controller.length);
final List<Widget> items;
final TabController controller;

View File

@ -3,14 +3,14 @@ import 'package:flutter/material.dart';
class PanelButton extends StatelessWidget {
const PanelButton({
Key? key,
super.key,
this.onPressed,
this.padding = const EdgeInsets.symmetric(horizontal: 14.0),
this.leading,
this.title,
this.trailing,
this.trailingDivider = false,
}) : super(key: key);
});
final void Function()? onPressed;
final EdgeInsetsGeometry padding;

View File

@ -5,12 +5,12 @@ import 'package:refilc/theme/colors/colors.dart';
class ProfileImage extends StatelessWidget {
const ProfileImage({
Key? key,
super.key,
this.name,
this.radius = 20.0,
this.role = Role.student,
this.backgroundColor,
}) : super(key: key);
});
final String? name;
final double radius;

View File

@ -3,7 +3,7 @@ import 'package:refilc_kreta_api/models/grade.dart';
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
class GradeViewable extends StatelessWidget {
const GradeViewable(this.grade, {Key? key}) : super(key: key);
const GradeViewable(this.grade, {super.key});
final Grade grade;

View File

@ -3,8 +3,7 @@ import 'package:refilc/ui/widgets/lesson/lesson_tile.dart';
import 'package:flutter/material.dart';
class LessonViewable extends StatelessWidget {
const LessonViewable(this.lesson, {Key? key, this.swapDesc = false})
: super(key: key);
const LessonViewable(this.lesson, {super.key, this.swapDesc = false});
final Lesson lesson;
final bool swapDesc;

View File

@ -40,13 +40,13 @@ class SubjectAbsence {
}
class AbsencesPage extends StatefulWidget {
const AbsencesPage({Key? key}) : super(key: key);
const AbsencesPage({super.key});
@override
_AbsencesPageState createState() => _AbsencesPageState();
AbsencesPageState createState() => AbsencesPageState();
}
class _AbsencesPageState extends State<AbsencesPage>
class AbsencesPageState extends State<AbsencesPage>
with TickerProviderStateMixin {
late UserProvider user;
late AbsenceProvider absenceProvider;
@ -87,6 +87,7 @@ class _AbsencesPageState extends State<AbsencesPage>
}
void buildSubjectAbsences() {
// ignore: no_leading_underscores_for_local_identifiers
Map<GradeSubject, SubjectAbsence> _absences = {};
for (final absence in absenceProvider.absences) {
@ -284,10 +285,10 @@ class _AbsencesPageState extends State<AbsencesPage>
Animation<double> secondaryAnimation,
) {
return FadeThroughTransition(
child: child,
animation: primaryAnimation,
secondaryAnimation: secondaryAnimation,
fillColor: Theme.of(context).colorScheme.background,
child: child,
);
},
child: Column(
@ -335,7 +336,7 @@ class _AbsencesPageState extends State<AbsencesPage>
.length;
title1 = "stat_1".i18n;
title2 = "stat_2".i18n;
suffix = " " + "hr".i18n;
suffix = " ${"hr".i18n}";
} else if (activeData == AbsenceFilter.delays.index) {
value1 = absenceProvider.absences
.where((e) =>
@ -349,7 +350,7 @@ class _AbsencesPageState extends State<AbsencesPage>
.fold(0, (a, b) => a + b);
title1 = "stat_3".i18n;
title2 = "stat_4".i18n;
suffix = " " + "min".i18n;
suffix = " ${"min".i18n}";
}
return Padding(

View File

@ -30,8 +30,7 @@ import 'grades_page.i18n.dart';
//import 'package:refilc_plus/ui/mobile/goal_planner/new_goal.dart';
class GradeSubjectView extends StatefulWidget {
const GradeSubjectView(this.subject, {Key? key, this.groupAverage = 0.0})
: super(key: key);
const GradeSubjectView(this.subject, {super.key, this.groupAverage = 0.0});
final GradeSubject subject;
final double groupAverage;
@ -90,6 +89,7 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
tiles.add(Container(height: 24.0));
}
// ignore: no_leading_underscores_for_local_identifiers
List<Widget> _gradeTiles = [];
if (!gradeCalcMode) {
@ -118,8 +118,8 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
animation: primaryAnimation,
secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.vertical,
child: child,
fillColor: Colors.transparent,
child: child,
);
},
child: _gradeTiles.isNotEmpty
@ -273,7 +273,8 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
_sheetController = _scaffoldKey.currentState?.showBottomSheet(
(context) => RoundedBottomSheet(
child: GradeCalculator(widget.subject), borderRadius: 14.0),
borderRadius: 14.0,
child: GradeCalculator(widget.subject)),
backgroundColor: const Color(0x00000000),
elevation: 12.0,
);

View File

@ -4,7 +4,7 @@ import 'package:refilc_desktop_ui/pages/grades/grades_count_item.dart';
import 'package:collection/collection.dart';
class GradesCount extends StatelessWidget {
const GradesCount({Key? key, required this.grades}) : super(key: key);
const GradesCount({super.key, required this.grades});
final List<Grade> grades;

View File

@ -3,8 +3,7 @@ import 'package:refilc_kreta_api/models/grade.dart';
import 'package:flutter/material.dart';
class GradesCountItem extends StatelessWidget {
const GradesCountItem({Key? key, required this.count, required this.value})
: super(key: key);
const GradesCountItem({super.key, required this.count, required this.value});
final int count;
final int value;

View File

@ -25,13 +25,13 @@ import 'package:refilc_mobile_ui/pages/grades/average_selector.dart';
import 'grades_page.i18n.dart';
class GradesPage extends StatefulWidget {
const GradesPage({Key? key}) : super(key: key);
const GradesPage({super.key});
@override
_GradesPageState createState() => _GradesPageState();
GradesPageState createState() => GradesPageState();
}
class _GradesPageState extends State<GradesPage> {
class GradesPageState extends State<GradesPage> {
late UserProvider user;
late GradeProvider gradeProvider;
late UpdateProvider updateProvider;
@ -294,8 +294,8 @@ class _GradesPageState extends State<GradesPage> {
return Padding(
padding: panelPadding,
child: PanelBody(
child: subjectTiles[index],
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: subjectTiles[index],
));
} else {
return Padding(

View File

@ -10,7 +10,7 @@ import 'package:refilc/ui/filter/sort.dart';
import 'home_page.i18n.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();

View File

@ -15,13 +15,13 @@ import 'package:provider/provider.dart';
import 'messages_page.i18n.dart';
class MessagesPage extends StatefulWidget {
const MessagesPage({Key? key}) : super(key: key);
const MessagesPage({super.key});
@override
_MessagesPageState createState() => _MessagesPageState();
MessagesPageState createState() => MessagesPageState();
}
class _MessagesPageState extends State<MessagesPage>
class MessagesPageState extends State<MessagesPage>
with TickerProviderStateMixin {
late UserProvider user;
late MessageProvider messageProvider;

View File

@ -23,8 +23,7 @@ import 'timetable_page.i18n.dart';
// todo: "fix" overflow (priority: -1)
class TimetablePage extends StatefulWidget {
const TimetablePage({Key? key, this.initialDay, this.initialWeek})
: super(key: key);
const TimetablePage({super.key, this.initialDay, this.initialWeek});
final DateTime? initialDay;
final Week? initialWeek;
@ -48,10 +47,10 @@ class TimetablePage extends StatefulWidget {
}
@override
_TimetablePageState createState() => _TimetablePageState();
TimetablePageState createState() => TimetablePageState();
}
class _TimetablePageState extends State<TimetablePage>
class TimetablePageState extends State<TimetablePage>
with TickerProviderStateMixin {
late UserProvider user;
late TimetableProvider timetableProvider;
@ -170,10 +169,10 @@ class _TimetablePageState extends State<TimetablePage>
Animation<double> secondaryAnimation,
) {
return FadeThroughTransition(
child: child,
animation: primaryAnimation,
secondaryAnimation: secondaryAnimation,
fillColor: Theme.of(context).scaffoldBackgroundColor,
child: child,
);
},
child: _controller.days != null
@ -208,9 +207,8 @@ class _TimetablePageState extends State<TimetablePage>
),
),
Text(
"${_controller.days![tab].first.date.day}"
.padLeft(2, '0') +
".",
"${"${_controller.days![tab].first.date.day}"
.padLeft(2, '0')}.",
style: TextStyle(
color: AppColors.of(context)
.text
@ -338,29 +336,19 @@ class _TimetablePageState extends State<TimetablePage>
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"${_controller.currentWeekId + 1}. " +
"week".i18n +
" (" +
// Week start
DateFormat(
(_controller.currentWeek.start.year !=
"${_controller.currentWeekId + 1}. ${"week".i18n} (${DateFormat(
"${_controller.currentWeek.start.year !=
DateTime.now().year
? "yy. "
: "") +
"MMM d.",
: ""}MMM d.",
I18n.of(context).locale.languageCode)
.format(_controller.currentWeek.start) +
" - " +
// Week end
DateFormat(
(_controller.currentWeek.start.year !=
.format(_controller.currentWeek.start)} - ${DateFormat(
"${_controller.currentWeek.start.year !=
DateTime.now().year
? "yy. "
: "") +
"MMM d.",
: ""}MMM d.",
I18n.of(context).locale.languageCode)
.format(_controller.currentWeek.end) +
")",
.format(_controller.currentWeek.end)})",
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 14.0,

View File

@ -25,15 +25,15 @@ const LinearGradient _backgroundGradient = LinearGradient(
);
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key, this.back = false}) : super(key: key);
const LoginScreen({super.key, this.back = false});
final bool back;
@override
_LoginScreenState createState() => _LoginScreenState();
LoginScreenState createState() => LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
class LoginScreenState extends State<LoginScreen> {
final usernameController = TextEditingController();
final passwordController = TextEditingController();
final schoolController = SchoolInputController();
@ -118,10 +118,10 @@ class _LoginScreenState extends State<LoginScreen> {
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Opacity(
opacity: 0.3,
child: Image.asset(
"assets/icons/ic_splash.png",
color: Colors.black),
opacity: 0.3),
color: Colors.black)),
),
BackdropFilter(
filter: ImageFilter.blur(
@ -253,15 +253,6 @@ class _LoginScreenState extends State<LoginScreen> {
child: Padding(
padding: const EdgeInsets.only(top: 42.0),
child: Visibility(
child: LoginButton(
child: Text("login".i18n,
maxLines: 1,
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15.0,
)),
onPressed: () => _loginAPI(context: context),
),
visible: _loginState != LoginState.inProgress,
replacement: const Padding(
padding: EdgeInsets.symmetric(vertical: 6.0),
@ -272,6 +263,15 @@ class _LoginScreenState extends State<LoginScreen> {
),
),
),
child: LoginButton(
child: Text("login".i18n,
maxLines: 1,
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15.0,
)),
onPressed: () => _loginAPI(context: context),
),
),
),
),

View File

@ -6,17 +6,16 @@ import 'package:flutter/material.dart';
import 'package:refilc_kreta_api/models/school.dart';
class SchoolInput extends StatefulWidget {
const SchoolInput({Key? key, required this.controller, required this.scroll})
: super(key: key);
const SchoolInput({super.key, required this.controller, required this.scroll});
final SchoolInputController controller;
final ScrollController scroll;
@override
_SchoolInputState createState() => _SchoolInputState();
SchoolInputState createState() => SchoolInputState();
}
class _SchoolInputState extends State<SchoolInput> {
class SchoolInputState extends State<SchoolInput> {
final _focusNode = FocusNode();
final _layerLink = LayerLink();
late SchoolInputOverlay overlay;

View File

@ -2,8 +2,7 @@ import 'package:refilc_kreta_api/models/school.dart';
import 'package:flutter/material.dart';
class SchoolInputTile extends StatelessWidget {
const SchoolInputTile({Key? key, required this.school, this.onTap})
: super(key: key);
const SchoolInputTile({super.key, required this.school, this.onTap});
final School school;
final Function()? onTap;

View File

@ -15,7 +15,7 @@ import 'package:refilc_kreta_api/client/client.dart';
import 'package:refilc_plus/providers/goal_provider.dart';
class NavigationScreen extends StatefulWidget {
const NavigationScreen({Key? key}) : super(key: key);
const NavigationScreen({super.key});
static NavigationScreenState? of(BuildContext context) =>
context.findAncestorStateOfType<NavigationScreenState>();

View File

@ -1,3 +1,5 @@
// ignore_for_file: no_leading_underscores_for_local_identifiers
import 'package:animations/animations.dart';
import 'package:refilc/api/providers/database_provider.dart';
import 'package:refilc/api/providers/user_provider.dart';
@ -27,11 +29,10 @@ import 'package:refilc/theme/colors/colors.dart';
class Sidebar extends StatefulWidget {
const Sidebar(
{Key? key,
{super.key,
required this.navigator,
required this.onRouteChange,
this.selected = "home"})
: super(key: key);
this.selected = "home"});
final NavigatorState navigator;
final String selected;
@ -183,6 +184,7 @@ class _SidebarState extends State<Sidebar> {
// delete user from app
user.removeUser(userId);
// ignore: use_build_context_synchronously
await Provider.of<DatabaseProvider>(context, listen: false)
.store
.removeUser(userId);
@ -192,6 +194,7 @@ class _SidebarState extends State<Sidebar> {
user.setUser(user.getUsers().first.id);
restore().then((_) => user.setUser(user.getUsers().first.id));
} else {
// ignore: use_build_context_synchronously
Navigator.of(context)
.pushNamedAndRemoveUntil("login", (_) => false);
}

View File

@ -3,8 +3,7 @@ import 'package:refilc/theme/colors/colors.dart';
class SidebarAction extends StatelessWidget {
const SidebarAction(
{Key? key, this.title, this.icon, this.onTap, this.selected = false})
: super(key: key);
{super.key, this.title, this.icon, this.onTap, this.selected = false});
final bool selected;
final Widget? icon;

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
class NewsView extends StatelessWidget {
const NewsView({Key? key}) : super(key: key);
const NewsView({super.key});
@override
Widget build(BuildContext context) {

View File

@ -1,3 +1,5 @@
// ignore_for_file: no_leading_underscores_for_local_identifiers
import 'package:refilc/api/providers/update_provider.dart';
import 'package:refilc_kreta_api/providers/absence_provider.dart';
import 'package:refilc_kreta_api/providers/event_provider.dart';
@ -41,13 +43,13 @@ import 'package:flutter/services.dart';
import 'package:refilc_mobile_ui/screens/settings/user/nickname.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({Key? key}) : super(key: key);
const SettingsScreen({super.key});
@override
_SettingsScreenState createState() => _SettingsScreenState();
SettingsScreenState createState() => SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen>
class SettingsScreenState extends State<SettingsScreen>
with SingleTickerProviderStateMixin {
int devmodeCountdown = 3;
final bool __ss = false; // secret settings
@ -506,6 +508,7 @@ class _SettingsScreenState extends State<SettingsScreen>
onPressed: () async {
await _hideContainersController
.forward();
// ignore: use_build_context_synchronously
SettingsHelper.accentColor(context);
setState(() {});
_hideContainersController.reset();
@ -915,9 +918,8 @@ class _SettingsScreenState extends State<SettingsScreen>
child: Center(
child: GestureDetector(
child: const Panel(
title: Text("v" +
String.fromEnvironment("APPVER",
defaultValue: "?"))),
title: Text("v${const String.fromEnvironment("APPVER",
defaultValue: "?")}")),
onTap: () {
if (devmodeCountdown > 0) {
ScaffoldMessenger.of(context)

View File

@ -17,6 +17,9 @@ dependencies:
# reFilc Plus
refilc_plus:
path: ../refilc_plus/
# reFilc Mobile
refilc_mobile_ui:
path: ../refilc_mobile_ui/
cupertino_icons: ^1.0.2
flutter_feather_icons: ^2.0.0+1
@ -30,6 +33,12 @@ dependencies:
flutter_acrylic: ^1.1.3
elegant_notification: ^1.13.0
flutter_staggered_grid_view: ^0.7.0
i18n_extension: ^11.0.12
flutter_expandable_fab: ^2.0.0
collection: ^1.18.0
animated_list_plus: ^0.5.2
intl: ^0.18.1
flutter_custom_tabs: ^2.0.0+1
dev_dependencies:
flutter_lints: ^3.0.1

View File

@ -50,7 +50,7 @@ class Absence {
DateTime lessonStart;
DateTime lessonEnd;
int? lessonIndex;
bool isSeen = json["isSeen"] ?? false;
// bool isSeen = json["isSeen"] ?? false;
if (json["Ora"] != null) {
lessonStart = json["Ora"]["KezdoDatum"] != null
? DateTime.parse(json["Ora"]["KezdoDatum"]).toLocal()

View File

@ -1,11 +1,14 @@
// ignore_for_file: dead_code
import 'dart:math';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:refilc/api/providers/live_card_provider.dart';
import 'package:refilc/theme/colors/colors.dart';
import 'package:refilc/ui/date_widget.dart';
import 'package:refilc/utils/format.dart';
import 'package:i18n_extension/i18n_extension.dart';
import 'package:intl/intl.dart';
import 'package:refilc_mobile_ui/common/soon_alert/soon_alert.dart';
import 'package:refilc_plus/providers/premium_provider.dart';
import 'package:animated_list_plus/animated_list_plus.dart';
import 'package:refilc/api/providers/update_provider.dart';
@ -243,6 +246,34 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
),
),
actions: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 5.0),
child: IconButton(
splashRadius: 24.0,
onPressed: () async {
// Navigator.of(context, rootNavigator: true)
// .push(PageRouteBuilder(
// pageBuilder: (context, animation, secondaryAnimation) =>
// PremiumFSTimetable(
// controller: controller,
// ),
// ))
// .then((_) {
// SystemChrome.setPreferredOrientations(
// [DeviceOrientation.portraitUp]);
// setSystemChrome(context);
// });
SoonAlert.show(context: context);
// await showSendMessageSheet(context);
},
icon: Icon(
FeatherIcons.messageCircle,
color: AppColors.of(context).text,
),
),
),
// Profile Icon
Padding(
padding: const EdgeInsets.only(right: 24.0),

View File

@ -14,7 +14,7 @@ class ErrorReportScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFE3EBFB),
backgroundColor: const Color(0xFFE3EBFB),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(12.0),
@ -28,7 +28,7 @@ class ErrorReportScreen extends StatelessWidget {
child: Text(
"ekretaYou".i18n,
style: TextStyle(
color: Color(0xFF011234).withOpacity(0.7),
color: const Color(0xFF011234).withOpacity(0.7),
fontSize: 24.0,
fontWeight: FontWeight.w700,
),
@ -120,7 +120,7 @@ class ErrorReportScreen extends StatelessWidget {
const EdgeInsets.symmetric(vertical: 14.0),
),
backgroundColor: MaterialStateProperty.all(
Color(0xFFF3F7FE),
const Color(0xFFF3F7FE),
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
@ -128,7 +128,7 @@ class ErrorReportScreen extends StatelessWidget {
),
),
side: MaterialStateProperty.all(
BorderSide(width: 1.0, color: Color(0xFFC7D3EB)),
const BorderSide(width: 1.0, color: Color(0xFFC7D3EB)),
),
),
child: Text(
@ -244,7 +244,7 @@ class ErrorDetail extends StatelessWidget {
const EdgeInsets.symmetric(horizontal: 6.5, vertical: 4.0),
margin: const EdgeInsets.only(top: 4.0),
decoration: BoxDecoration(
color: Color.fromARGB(255, 218, 218, 218),
color: const Color.fromARGB(255, 218, 218, 218),
borderRadius: BorderRadius.circular(4.0)),
child: Text(
content,

View File

@ -18,8 +18,9 @@ List<School> searchSchools(List<School> all, String pattern) {
if (contains == pattern.split(" ").length) results.add(item);
if (item.instituteCode.toLowerCase().specialChars().contains(pattern))
if (item.instituteCode.toLowerCase().specialChars().contains(pattern)) {
results.add(item);
}
}
results.sort((a, b) => a.name.compareTo(b.name));

View File

@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:flutter_svg/svg.dart';
import 'package:refilc/api/providers/update_provider.dart';
@ -201,9 +203,7 @@ class NavigationScreenState extends State<NavigationScreen>
@override
void didChangePlatformBrightness() {
if (settings.theme == ThemeMode.system) {
// ignore: deprecated_member_use
Brightness? brightness =
// ignore: deprecated_member_use
WidgetsBinding.instance.window.platformBrightness;
Provider.of<ThemeModeObserver>(context, listen: false).changeTheme(
brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark);
@ -242,7 +242,6 @@ class NavigationScreenState extends State<NavigationScreen>
// SvgTheme navIcTheme =
// SvgTheme(currentColor: Theme.of(context).colorScheme.primary);
// ignore: deprecated_member_use
return WillPopScope(
onWillPop: () async {
if (_navigatorState.currentState?.canPop() ?? false) {

View File

@ -1016,7 +1016,7 @@ class SettingsScreenState extends State<SettingsScreen>
);
showErrorScreen(context, fakeErrorDetails);
},
child: Text('hiba_tesztelese'),
child: const Text('hiba_tesztelese'),
),
// developer options

@ -1 +1 @@
Subproject commit 146ff9251c421f1982e90e07d36027c4d5d3342a
Subproject commit a4d569db8d8cffa5342fabacd7d1f3ee4fe43061