forked from firka/student-legacy
Merge branch 'master' into notifications
This commit is contained in:
commit
9e914974b7
@ -204,7 +204,7 @@ SPEC CHECKSUMS:
|
|||||||
connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a
|
connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a
|
||||||
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
||||||
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||||
file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95
|
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
flutter_custom_tabs: 7a10a08686955cb748e5d26e0ae586d30689bf89
|
flutter_custom_tabs: 7a10a08686955cb748e5d26e0ae586d30689bf89
|
||||||
flutter_image_compress: 5a5e9aee05b6553048b8df1c3bc456d0afaac433
|
flutter_image_compress: 5a5e9aee05b6553048b8df1c3bc456d0afaac433
|
||||||
@ -218,14 +218,14 @@ SPEC CHECKSUMS:
|
|||||||
live_activities: 9ff56a06a2d43ecd68f56deeed13b18a8304789c
|
live_activities: 9ff56a06a2d43ecd68f56deeed13b18a8304789c
|
||||||
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
|
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
|
||||||
open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d
|
open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d
|
||||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
|
||||||
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
|
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
|
||||||
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
||||||
quick_actions_ios: 9e80dcfadfbc5d47d9cf8f47bcf428b11cf383d4
|
quick_actions_ios: 9e80dcfadfbc5d47d9cf8f47bcf428b11cf383d4
|
||||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866
|
SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866
|
||||||
SDWebImageWebPCoder: 18503de6621dd2c420d680e33d46bf8e1d5169b0
|
SDWebImageWebPCoder: 18503de6621dd2c420d680e33d46bf8e1d5169b0
|
||||||
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028
|
||||||
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
||||||
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
|
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
|
||||||
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
|
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
|
||||||
|
@ -7,6 +7,7 @@ import 'package:filcnaplo/models/release.dart';
|
|||||||
import 'package:filcnaplo/models/settings.dart';
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
import 'package:filcnaplo/models/supporter.dart';
|
import 'package:filcnaplo/models/supporter.dart';
|
||||||
import 'package:filcnaplo_kreta_api/models/school.dart';
|
import 'package:filcnaplo_kreta_api/models/school.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
|
|
||||||
@ -68,7 +69,9 @@ class FilcAPI {
|
|||||||
http.Response res = await http.get(Uri.parse(config), headers: headers);
|
http.Response res = await http.get(Uri.parse(config), headers: headers);
|
||||||
|
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
print(jsonDecode(res.body));
|
if (kDebugMode) {
|
||||||
|
print(jsonDecode(res.body));
|
||||||
|
}
|
||||||
return Config.fromJson(jsonDecode(res.body));
|
return Config.fromJson(jsonDecode(res.body));
|
||||||
} else if (res.statusCode == 429) {
|
} else if (res.statusCode == 429) {
|
||||||
res = await http.get(Uri.parse(config));
|
res = await http.get(Uri.parse(config));
|
||||||
|
@ -57,14 +57,15 @@ Future loginApi({
|
|||||||
String nonceStr = await Provider.of<KretaClient>(context, listen: false)
|
String nonceStr = await Provider.of<KretaClient>(context, listen: false)
|
||||||
.getAPI(KretaAPI.nonce, json: false);
|
.getAPI(KretaAPI.nonce, json: false);
|
||||||
|
|
||||||
Nonce nonce = getNonce(nonceStr, username.replaceAll(' ', '') + ' ', instituteCode);
|
Nonce nonce =
|
||||||
|
getNonce(nonceStr, '${username.replaceAll(' ', '')} ', instituteCode);
|
||||||
headers.addAll(nonce.header());
|
headers.addAll(nonce.header());
|
||||||
|
|
||||||
Map? res = await Provider.of<KretaClient>(context, listen: false)
|
Map? res = await Provider.of<KretaClient>(context, listen: false)
|
||||||
.postAPI(KretaAPI.login,
|
.postAPI(KretaAPI.login,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
body: User.loginBody(
|
body: User.loginBody(
|
||||||
username: username.replaceAll(' ', '') + ' ',
|
username: '${username.replaceAll(' ', '')} ',
|
||||||
password: password,
|
password: password,
|
||||||
instituteCode: instituteCode,
|
instituteCode: instituteCode,
|
||||||
));
|
));
|
||||||
@ -83,7 +84,7 @@ Future loginApi({
|
|||||||
.getAPI(KretaAPI.student(instituteCode));
|
.getAPI(KretaAPI.student(instituteCode));
|
||||||
Student student = Student.fromJson(studentJson!);
|
Student student = Student.fromJson(studentJson!);
|
||||||
var user = User(
|
var user = User(
|
||||||
username: username.replaceAll(' ', '') + ' ',
|
username: '${username.replaceAll(' ', '')} ',
|
||||||
password: password,
|
password: password,
|
||||||
instituteCode: instituteCode,
|
instituteCode: instituteCode,
|
||||||
name: student.name,
|
name: student.name,
|
||||||
|
@ -2,7 +2,6 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:filcnaplo/database/query.dart';
|
import 'package:filcnaplo/database/query.dart';
|
||||||
import 'package:filcnaplo/database/store.dart';
|
import 'package:filcnaplo/database/store.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
|
||||||
// ignore: depend_on_referenced_packages
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||||
|
|
||||||
|
@ -47,7 +47,9 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
// Check if live card is enabled .areActivitiesEnabled()
|
// Check if live card is enabled .areActivitiesEnabled()
|
||||||
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
||||||
// Console log
|
// Console log
|
||||||
print("Live card enabled: $value");
|
if (kDebugMode) {
|
||||||
|
print("Live card enabled: $value");
|
||||||
|
}
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
_liveActivitiesPlugin.init(appGroupId: "group.refilc.livecard");
|
_liveActivitiesPlugin.init(appGroupId: "group.refilc.livecard");
|
||||||
|
@ -5,28 +5,36 @@ import 'dart:io';
|
|||||||
import 'package:filcnaplo/api/providers/database_provider.dart';
|
import 'package:filcnaplo/api/providers/database_provider.dart';
|
||||||
import 'package:filcnaplo/database/struct.dart';
|
import 'package:filcnaplo/database/struct.dart';
|
||||||
import 'package:filcnaplo/models/settings.dart';
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
|
||||||
// ignore: depend_on_referenced_packages
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||||
|
|
||||||
const settingsDB = DatabaseStruct("settings", {
|
const settingsDB = DatabaseStruct("settings", {
|
||||||
"language": String, "start_page": int, "rounding": int, "theme": int, "accent_color": int, "news": int, "news_state": int, "developer_mode": int,
|
"language": String, "start_page": int, "rounding": int, "theme": int,
|
||||||
"update_channel": int, "config": String, "custom_accent_color": int, "custom_background_color": int, "custom_highlight_color": int, // general
|
"accent_color": int, "news": int, "news_state": int, "developer_mode": int,
|
||||||
"grade_color1": int, "grade_color2": int, "grade_color3": int, "grade_color4": int, "grade_color5": int, // grade colors
|
"update_channel": int, "config": String, "custom_accent_color": int,
|
||||||
|
"custom_background_color": int, "custom_highlight_color": int, // general
|
||||||
|
"grade_color1": int, "grade_color2": int, "grade_color3": int,
|
||||||
|
"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, "notification_poll_interval": int, // notifications
|
"notifications": int, "notifications_bitfield": int,
|
||||||
"x_filc_id": String, "graph_class_avg": int, "presentation_mode": int, "bell_delay": int, "bell_delay_enabled": int,
|
"notification_poll_interval": int, // notifications
|
||||||
"grade_opening_fun": int, "icon_pack": String, "premium_scopes": String, "premium_token": String, "premium_login": String,
|
"x_filc_id": String, "graph_class_avg": int, "presentation_mode": int,
|
||||||
"last_account_id": String, "renamed_subjects_enabled": int, "renamed_subjects_italics":int,
|
"bell_delay": int, "bell_delay_enabled": int,
|
||||||
|
"grade_opening_fun": int, "icon_pack": String, "premium_scopes": String,
|
||||||
|
"premium_token": String, "premium_login": String,
|
||||||
|
"last_account_id": String, "renamed_subjects_enabled": int,
|
||||||
|
"renamed_subjects_italics": int,
|
||||||
});
|
});
|
||||||
// DON'T FORGET TO UPDATE DEFAULT VALUES IN `initDB` MIGRATION OR ELSE PARENTS WILL COMPLAIN ABOUT THEIR CHILDREN MISSING
|
// DON'T FORGET TO UPDATE DEFAULT VALUES IN `initDB` MIGRATION OR ELSE PARENTS WILL COMPLAIN ABOUT THEIR CHILDREN MISSING
|
||||||
// YOU'VE BEEN WARNED!!!
|
// YOU'VE BEEN WARNED!!!
|
||||||
const usersDB = DatabaseStruct("users", {
|
const usersDB = DatabaseStruct("users", {
|
||||||
"id": String, "name": String, "username": String, "password": String, "institute_code": String, "student": String, "role": int,
|
"id": String, "name": String, "username": String, "password": String,
|
||||||
|
"institute_code": String, "student": String, "role": int,
|
||||||
"nickname": String, "picture": String // premium only
|
"nickname": String, "picture": String // premium only
|
||||||
});
|
});
|
||||||
const userDataDB = DatabaseStruct("user_data", {
|
const userDataDB = DatabaseStruct("user_data", {
|
||||||
"id": String, "grades": String, "timetable": String, "exams": String, "homework": String, "messages": String, "notes": String,
|
"id": String, "grades": String, "timetable": String, "exams": String,
|
||||||
|
"homework": String, "messages": String, "notes": String,
|
||||||
"events": String, "absences": String, "group_averages": String,
|
"events": String, "absences": String, "group_averages": String,
|
||||||
// renamed subjects // non kreta data
|
// renamed subjects // non kreta data
|
||||||
"renamed_subjects": String,
|
"renamed_subjects": String,
|
||||||
@ -34,7 +42,8 @@ const userDataDB = DatabaseStruct("user_data", {
|
|||||||
"last_seen_grade": int,
|
"last_seen_grade": int,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> createTable(Database db, DatabaseStruct struct) => db.execute("CREATE TABLE IF NOT EXISTS ${struct.table} ($struct)");
|
Future<void> createTable(Database db, DatabaseStruct struct) =>
|
||||||
|
db.execute("CREATE TABLE IF NOT EXISTS ${struct.table} ($struct)");
|
||||||
|
|
||||||
Future<Database> initDB(DatabaseProvider database) async {
|
Future<Database> initDB(DatabaseProvider database) async {
|
||||||
Database db;
|
Database db;
|
||||||
@ -50,9 +59,11 @@ Future<Database> initDB(DatabaseProvider database) async {
|
|||||||
await createTable(db, usersDB);
|
await createTable(db, usersDB);
|
||||||
await createTable(db, userDataDB);
|
await createTable(db, userDataDB);
|
||||||
|
|
||||||
if ((await db.rawQuery("SELECT COUNT(*) FROM settings"))[0].values.first == 0) {
|
if ((await db.rawQuery("SELECT COUNT(*) FROM settings"))[0].values.first ==
|
||||||
|
0) {
|
||||||
// Set default values for table Settings
|
// Set default values for table Settings
|
||||||
await db.insert("settings", SettingsProvider.defaultSettings(database: database).toMap());
|
await db.insert("settings",
|
||||||
|
SettingsProvider.defaultSettings(database: database).toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate Databases
|
// Migrate Databases
|
||||||
@ -60,7 +71,8 @@ Future<Database> initDB(DatabaseProvider database) async {
|
|||||||
await migrateDB(
|
await migrateDB(
|
||||||
db,
|
db,
|
||||||
struct: settingsDB,
|
struct: settingsDB,
|
||||||
defaultValues: SettingsProvider.defaultSettings(database: database).toMap(),
|
defaultValues:
|
||||||
|
SettingsProvider.defaultSettings(database: database).toMap(),
|
||||||
);
|
);
|
||||||
await migrateDB(
|
await migrateDB(
|
||||||
db,
|
db,
|
||||||
@ -68,7 +80,8 @@ Future<Database> initDB(DatabaseProvider database) async {
|
|||||||
defaultValues: {"role": 0, "nickname": "", "picture": ""},
|
defaultValues: {"role": 0, "nickname": "", "picture": ""},
|
||||||
);
|
);
|
||||||
await migrateDB(db, struct: userDataDB, defaultValues: {
|
await migrateDB(db, struct: userDataDB, defaultValues: {
|
||||||
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]", "messages": "[]", "notes": "[]", "events": "[]", "absences": "[]",
|
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]",
|
||||||
|
"messages": "[]", "notes": "[]", "events": "[]", "absences": "[]",
|
||||||
"group_averages": "[]",
|
"group_averages": "[]",
|
||||||
// renamed subjects // non kreta data
|
// renamed subjects // non kreta data
|
||||||
"renamed_subjects": "{}",
|
"renamed_subjects": "{}",
|
||||||
@ -99,7 +112,8 @@ Future<void> migrateDB(
|
|||||||
|
|
||||||
// go through each row and add missing keys or delete non existing keys
|
// go through each row and add missing keys or delete non existing keys
|
||||||
await Future.forEach<Map<String, Object?>>(originalRows, (original) async {
|
await Future.forEach<Map<String, Object?>>(originalRows, (original) async {
|
||||||
bool migrationRequired = struct.struct.keys.any((key) => !original.containsKey(key) || original[key] == null) ||
|
bool migrationRequired = struct.struct.keys.any(
|
||||||
|
(key) => !original.containsKey(key) || original[key] == null) ||
|
||||||
original.keys.any((key) => !struct.struct.containsKey(key));
|
original.keys.any((key) => !struct.struct.containsKey(key));
|
||||||
|
|
||||||
if (migrationRequired) {
|
if (migrationRequired) {
|
||||||
|
@ -157,11 +157,15 @@ void backgroundHeadlessTask(HeadlessTask task) {
|
|||||||
String taskId = task.taskId;
|
String taskId = task.taskId;
|
||||||
bool isTimeout = task.timeout;
|
bool isTimeout = task.timeout;
|
||||||
if (isTimeout) {
|
if (isTimeout) {
|
||||||
print("[BackgroundFetch] Headless task timed-out: $taskId");
|
if (kDebugMode) {
|
||||||
|
print("[BackgroundFetch] Headless task timed-out: $taskId");
|
||||||
|
}
|
||||||
BackgroundFetch.finish(taskId);
|
BackgroundFetch.finish(taskId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print('[BackgroundFetch] Headless event received.');
|
if (kDebugMode) {
|
||||||
|
print('[BackgroundFetch] Headless event received.');
|
||||||
|
}
|
||||||
NotificationsHelper().backgroundJob();
|
NotificationsHelper().backgroundJob();
|
||||||
BackgroundFetch.finish(task.taskId);
|
BackgroundFetch.finish(task.taskId);
|
||||||
}
|
}
|
||||||
|
@ -366,66 +366,88 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
if (startPage != null && startPage != _startPage) _startPage = startPage;
|
if (startPage != null && startPage != _startPage) _startPage = startPage;
|
||||||
if (rounding != null && rounding != _rounding) _rounding = rounding;
|
if (rounding != null && rounding != _rounding) _rounding = rounding;
|
||||||
if (theme != null && theme != _theme) _theme = theme;
|
if (theme != null && theme != _theme) _theme = theme;
|
||||||
if (accentColor != null && accentColor != _accentColor)
|
if (accentColor != null && accentColor != _accentColor) {
|
||||||
_accentColor = accentColor;
|
_accentColor = accentColor;
|
||||||
if (gradeColors != null && gradeColors != _gradeColors)
|
}
|
||||||
|
if (gradeColors != null && gradeColors != _gradeColors) {
|
||||||
_gradeColors = gradeColors;
|
_gradeColors = gradeColors;
|
||||||
if (newsEnabled != null && newsEnabled != _newsEnabled)
|
}
|
||||||
|
if (newsEnabled != null && newsEnabled != _newsEnabled) {
|
||||||
_newsEnabled = newsEnabled;
|
_newsEnabled = newsEnabled;
|
||||||
|
}
|
||||||
if (newsState != null && newsState != _newsState) _newsState = newsState;
|
if (newsState != null && newsState != _newsState) _newsState = newsState;
|
||||||
if (notificationsEnabled != null &&
|
if (notificationsEnabled != null &&
|
||||||
notificationsEnabled != _notificationsEnabled)
|
notificationsEnabled != _notificationsEnabled) {
|
||||||
_notificationsEnabled = notificationsEnabled;
|
_notificationsEnabled = notificationsEnabled;
|
||||||
|
}
|
||||||
if (notificationsBitfield != null &&
|
if (notificationsBitfield != null &&
|
||||||
notificationsBitfield != _notificationsBitfield)
|
notificationsBitfield != _notificationsBitfield) {
|
||||||
_notificationsBitfield = notificationsBitfield;
|
_notificationsBitfield = notificationsBitfield;
|
||||||
if (developerMode != null && developerMode != _developerMode)
|
}
|
||||||
|
if (developerMode != null && developerMode != _developerMode) {
|
||||||
_developerMode = developerMode;
|
_developerMode = developerMode;
|
||||||
|
}
|
||||||
if (notificationPollInterval != null &&
|
if (notificationPollInterval != null &&
|
||||||
notificationPollInterval != _notificationPollInterval) {
|
notificationPollInterval != _notificationPollInterval) {
|
||||||
_notificationPollInterval = notificationPollInterval;
|
_notificationPollInterval = notificationPollInterval;
|
||||||
}
|
}
|
||||||
if (vibrate != null && vibrate != _vibrate) _vibrate = vibrate;
|
if (vibrate != null && vibrate != _vibrate) _vibrate = vibrate;
|
||||||
if (abWeeks != null && abWeeks != _abWeeks) _abWeeks = abWeeks;
|
if (abWeeks != null && abWeeks != _abWeeks) _abWeeks = abWeeks;
|
||||||
if (swapABweeks != null && swapABweeks != _swapABweeks)
|
if (swapABweeks != null && swapABweeks != _swapABweeks) {
|
||||||
_swapABweeks = swapABweeks;
|
_swapABweeks = swapABweeks;
|
||||||
if (updateChannel != null && updateChannel != _updateChannel)
|
}
|
||||||
|
if (updateChannel != null && updateChannel != _updateChannel) {
|
||||||
_updateChannel = updateChannel;
|
_updateChannel = updateChannel;
|
||||||
|
}
|
||||||
if (config != null && config != _config) _config = config;
|
if (config != null && config != _config) _config = config;
|
||||||
if (xFilcId != null && xFilcId != _xFilcId) _xFilcId = xFilcId;
|
if (xFilcId != null && xFilcId != _xFilcId) _xFilcId = xFilcId;
|
||||||
if (graphClassAvg != null && graphClassAvg != _graphClassAvg)
|
if (graphClassAvg != null && graphClassAvg != _graphClassAvg) {
|
||||||
_graphClassAvg = graphClassAvg;
|
_graphClassAvg = graphClassAvg;
|
||||||
|
}
|
||||||
if (goodStudent != null) _goodStudent = goodStudent;
|
if (goodStudent != null) _goodStudent = goodStudent;
|
||||||
if (presentationMode != null && presentationMode != _presentationMode)
|
if (presentationMode != null && presentationMode != _presentationMode) {
|
||||||
_presentationMode = presentationMode;
|
_presentationMode = presentationMode;
|
||||||
|
}
|
||||||
if (bellDelay != null && bellDelay != _bellDelay) _bellDelay = bellDelay;
|
if (bellDelay != null && bellDelay != _bellDelay) _bellDelay = bellDelay;
|
||||||
if (bellDelayEnabled != null && bellDelayEnabled != _bellDelayEnabled)
|
if (bellDelayEnabled != null && bellDelayEnabled != _bellDelayEnabled) {
|
||||||
_bellDelayEnabled = bellDelayEnabled;
|
_bellDelayEnabled = bellDelayEnabled;
|
||||||
if (gradeOpeningFun != null && gradeOpeningFun != _gradeOpeningFun)
|
}
|
||||||
|
if (gradeOpeningFun != null && gradeOpeningFun != _gradeOpeningFun) {
|
||||||
_gradeOpeningFun = gradeOpeningFun;
|
_gradeOpeningFun = gradeOpeningFun;
|
||||||
|
}
|
||||||
if (iconPack != null && iconPack != _iconPack) _iconPack = iconPack;
|
if (iconPack != null && iconPack != _iconPack) _iconPack = iconPack;
|
||||||
if (customAccentColor != null && customAccentColor != _customAccentColor)
|
if (customAccentColor != null && customAccentColor != _customAccentColor) {
|
||||||
_customAccentColor = customAccentColor;
|
_customAccentColor = customAccentColor;
|
||||||
|
}
|
||||||
if (customBackgroundColor != null &&
|
if (customBackgroundColor != null &&
|
||||||
customBackgroundColor != _customBackgroundColor)
|
customBackgroundColor != _customBackgroundColor) {
|
||||||
_customBackgroundColor = customBackgroundColor;
|
_customBackgroundColor = customBackgroundColor;
|
||||||
|
}
|
||||||
if (customHighlightColor != null &&
|
if (customHighlightColor != null &&
|
||||||
customHighlightColor != _customHighlightColor)
|
customHighlightColor != _customHighlightColor) {
|
||||||
_customHighlightColor = customHighlightColor;
|
_customHighlightColor = customHighlightColor;
|
||||||
if (premiumScopes != null && premiumScopes != _premiumScopes)
|
}
|
||||||
|
if (premiumScopes != null && premiumScopes != _premiumScopes) {
|
||||||
_premiumScopes = premiumScopes;
|
_premiumScopes = premiumScopes;
|
||||||
if (premiumAccessToken != null && premiumAccessToken != _premiumAccessToken)
|
}
|
||||||
|
if (premiumAccessToken != null &&
|
||||||
|
premiumAccessToken != _premiumAccessToken) {
|
||||||
_premiumAccessToken = premiumAccessToken;
|
_premiumAccessToken = premiumAccessToken;
|
||||||
if (premiumLogin != null && premiumLogin != _premiumLogin)
|
}
|
||||||
|
if (premiumLogin != null && premiumLogin != _premiumLogin) {
|
||||||
_premiumLogin = premiumLogin;
|
_premiumLogin = premiumLogin;
|
||||||
if (lastAccountId != null && lastAccountId != _lastAccountId)
|
}
|
||||||
|
if (lastAccountId != null && lastAccountId != _lastAccountId) {
|
||||||
_lastAccountId = lastAccountId;
|
_lastAccountId = lastAccountId;
|
||||||
|
}
|
||||||
if (renamedSubjectsEnabled != null &&
|
if (renamedSubjectsEnabled != null &&
|
||||||
renamedSubjectsEnabled != _renamedSubjectsEnabled)
|
renamedSubjectsEnabled != _renamedSubjectsEnabled) {
|
||||||
_renamedSubjectsEnabled = renamedSubjectsEnabled;
|
_renamedSubjectsEnabled = renamedSubjectsEnabled;
|
||||||
if (renamedSubjectsItalics != null &&
|
}
|
||||||
renamedSubjectsItalics != _renamedSubjectsItalics)
|
if (renamedSubjectsItalics != null &&
|
||||||
|
renamedSubjectsItalics != _renamedSubjectsItalics) {
|
||||||
_renamedSubjectsItalics = renamedSubjectsItalics;
|
_renamedSubjectsItalics = renamedSubjectsItalics;
|
||||||
|
}
|
||||||
if (store) await _database?.store.storeSettings(this);
|
if (store) await _database?.store.storeSettings(this);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ class DarkMobileAppColors implements ThemeAppColors {
|
|||||||
final gradeTwo = const Color(0xFFAE3DF4);
|
final gradeTwo = const Color(0xFFAE3DF4);
|
||||||
@override
|
@override
|
||||||
final gradeOne = const Color(0xFFF43DAB);
|
final gradeOne = const Color(0xFFF43DAB);
|
||||||
|
@override
|
||||||
final purple = const Color(0xffBF5AF2);
|
final purple = const Color(0xffBF5AF2);
|
||||||
@override
|
@override
|
||||||
final pink = const Color(0xffFF375F);
|
final pink = const Color(0xffFF375F);
|
||||||
|
@ -16,13 +16,15 @@ import 'package:filcnaplo_kreta_api/client/client.dart';
|
|||||||
class NavigationScreen extends StatefulWidget {
|
class NavigationScreen extends StatefulWidget {
|
||||||
const NavigationScreen({Key? key}) : super(key: key);
|
const NavigationScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
static NavigationScreenState? of(BuildContext context) => context.findAncestorStateOfType<NavigationScreenState>();
|
static NavigationScreenState? of(BuildContext context) =>
|
||||||
|
context.findAncestorStateOfType<NavigationScreenState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<NavigationScreen> createState() => NavigationScreenState();
|
State<NavigationScreen> createState() => NavigationScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class NavigationScreenState extends State<NavigationScreen> with WidgetsBindingObserver {
|
class NavigationScreenState extends State<NavigationScreen>
|
||||||
|
with WidgetsBindingObserver {
|
||||||
final _navigatorState = GlobalKey<NavigatorState>();
|
final _navigatorState = GlobalKey<NavigatorState>();
|
||||||
late NavigationRoute selected;
|
late NavigationRoute selected;
|
||||||
late SettingsProvider settings;
|
late SettingsProvider settings;
|
||||||
@ -40,7 +42,8 @@ class NavigationScreenState extends State<NavigationScreen> with WidgetsBindingO
|
|||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
|
||||||
// set client User-Agent
|
// set client User-Agent
|
||||||
Provider.of<KretaClient>(context, listen: false).userAgent = settings.config.userAgent;
|
Provider.of<KretaClient>(context, listen: false).userAgent =
|
||||||
|
settings.config.userAgent;
|
||||||
|
|
||||||
// Get news
|
// Get news
|
||||||
newsProvider = Provider.of<NewsProvider>(context, listen: false);
|
newsProvider = Provider.of<NewsProvider>(context, listen: false);
|
||||||
@ -54,7 +57,11 @@ class NavigationScreenState extends State<NavigationScreen> with WidgetsBindingO
|
|||||||
await Window.initialize();
|
await Window.initialize();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
// Transparent sidebar
|
// Transparent sidebar
|
||||||
await Window.setEffect(effect: WindowEffect.acrylic, color: Platform.isMacOS ? Colors.transparent : const Color.fromARGB(27, 27, 27, 27));
|
await Window.setEffect(
|
||||||
|
effect: WindowEffect.acrylic,
|
||||||
|
color: Platform.isMacOS
|
||||||
|
? Colors.transparent
|
||||||
|
: const Color.fromARGB(27, 27, 27, 27));
|
||||||
|
|
||||||
// todo: do for windows
|
// todo: do for windows
|
||||||
if (Platform.isMacOS) {
|
if (Platform.isMacOS) {
|
||||||
@ -75,8 +82,12 @@ class NavigationScreenState extends State<NavigationScreen> with WidgetsBindingO
|
|||||||
@override
|
@override
|
||||||
void didChangePlatformBrightness() {
|
void didChangePlatformBrightness() {
|
||||||
if (settings.theme == ThemeMode.system) {
|
if (settings.theme == ThemeMode.system) {
|
||||||
Brightness? brightness = WidgetsBinding.instance.window.platformBrightness;
|
// ignore: deprecated_member_use
|
||||||
Provider.of<ThemeModeObserver>(context, listen: false).changeTheme(brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark);
|
Brightness? brightness =
|
||||||
|
// ignore: deprecated_member_use
|
||||||
|
WidgetsBinding.instance.window.platformBrightness;
|
||||||
|
Provider.of<ThemeModeObserver>(context, listen: false).changeTheme(
|
||||||
|
brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark);
|
||||||
}
|
}
|
||||||
super.didChangePlatformBrightness();
|
super.didChangePlatformBrightness();
|
||||||
}
|
}
|
||||||
@ -103,8 +114,12 @@ class NavigationScreenState extends State<NavigationScreen> with WidgetsBindingO
|
|||||||
if (_navigatorState.currentState != null)
|
if (_navigatorState.currentState != null)
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(.5),
|
color:
|
||||||
border: Border(right: BorderSide(color: AppColors.of(context).shadow.withOpacity(.7), width: 1.0)),
|
Theme.of(context).scaffoldBackgroundColor.withOpacity(.5),
|
||||||
|
border: Border(
|
||||||
|
right: BorderSide(
|
||||||
|
color: AppColors.of(context).shadow.withOpacity(.7),
|
||||||
|
width: 1.0)),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(top: topInset),
|
padding: EdgeInsets.only(top: topInset),
|
||||||
@ -125,7 +140,8 @@ class NavigationScreenState extends State<NavigationScreen> with WidgetsBindingO
|
|||||||
child: Navigator(
|
child: Navigator(
|
||||||
key: _navigatorState,
|
key: _navigatorState,
|
||||||
initialRoute: selected.name,
|
initialRoute: selected.name,
|
||||||
onGenerateRoute: (settings) => navigationRouteHandler(settings),
|
onGenerateRoute: (settings) =>
|
||||||
|
navigationRouteHandler(settings),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -97,7 +97,11 @@ class GradeProvider with ChangeNotifier {
|
|||||||
.i18n;
|
.i18n;
|
||||||
grade.value.shortName = _settings.goodStudent
|
grade.value.shortName = _settings.goodStudent
|
||||||
? "Jeles".i18n
|
? "Jeles".i18n
|
||||||
: '${grade.json!["SzovegesErtekelesRovidNev"]}' != "null" && '${grade.json!["SzovegesErtekelesRovidNev"]}' != "-" && '${grade.json!["SzovegesErtekelesRovidNev"]}'.replaceAll(RegExp(r'[0123456789]+[%]?'), '') != ""
|
: '${grade.json!["SzovegesErtekelesRovidNev"]}' != "null" &&
|
||||||
|
'${grade.json!["SzovegesErtekelesRovidNev"]}' != "-" &&
|
||||||
|
'${grade.json!["SzovegesErtekelesRovidNev"]}'
|
||||||
|
.replaceAll(RegExp(r'[0123456789]+[%]?'), '') !=
|
||||||
|
""
|
||||||
? '${grade.json!["SzovegesErtekelesRovidNev"]}'.i18n
|
? '${grade.json!["SzovegesErtekelesRovidNev"]}'.i18n
|
||||||
: grade.value.valueName;
|
: grade.value.valueName;
|
||||||
}
|
}
|
||||||
@ -118,14 +122,16 @@ class GradeProvider with ChangeNotifier {
|
|||||||
if (grades.isNotEmpty || _grades.isNotEmpty) await store(grades);
|
if (grades.isNotEmpty || _grades.isNotEmpty) await store(grades);
|
||||||
|
|
||||||
List? groupsJson = await _kreta.getAPI(KretaAPI.groups(iss));
|
List? groupsJson = await _kreta.getAPI(KretaAPI.groups(iss));
|
||||||
if (groupsJson == null || groupsJson.isEmpty)
|
if (groupsJson == null || groupsJson.isEmpty) {
|
||||||
throw "Cannot fetch Groups for User ${user.id}";
|
throw "Cannot fetch Groups for User ${user.id}";
|
||||||
|
}
|
||||||
_groups = (groupsJson[0]["OktatasNevelesiFeladat"] ?? {})["Uid"] ?? "";
|
_groups = (groupsJson[0]["OktatasNevelesiFeladat"] ?? {})["Uid"] ?? "";
|
||||||
|
|
||||||
List? groupAvgJson =
|
List? groupAvgJson =
|
||||||
await _kreta.getAPI(KretaAPI.groupAverages(iss, _groups));
|
await _kreta.getAPI(KretaAPI.groupAverages(iss, _groups));
|
||||||
if (groupAvgJson == null)
|
if (groupAvgJson == null) {
|
||||||
throw "Cannot fetch Class Averages for User ${user.id}";
|
throw "Cannot fetch Class Averages for User ${user.id}";
|
||||||
|
}
|
||||||
final groupAvgs =
|
final groupAvgs =
|
||||||
groupAvgJson.map((e) => GroupAverage.fromJson(e)).toList();
|
groupAvgJson.map((e) => GroupAverage.fromJson(e)).toList();
|
||||||
await storeGroupAvg(groupAvgs);
|
await storeGroupAvg(groupAvgs);
|
||||||
|
@ -37,10 +37,14 @@ class TimetableProvider with ChangeNotifier {
|
|||||||
// for renamed subjects
|
// for renamed subjects
|
||||||
Future<void> convertBySettings() async {
|
Future<void> convertBySettings() async {
|
||||||
Map<String, String> renamedSubjects =
|
Map<String, String> renamedSubjects =
|
||||||
(await _database.query.getSettings(_database)).renamedSubjectsEnabled ? await _database.userQuery.renamedSubjects(userId: _user.id!) : {};
|
(await _database.query.getSettings(_database)).renamedSubjectsEnabled
|
||||||
|
? await _database.userQuery.renamedSubjects(userId: _user.id!)
|
||||||
|
: {};
|
||||||
|
|
||||||
for (Lesson lesson in _lessons.values.expand((e) => e)) {
|
for (Lesson lesson in _lessons.values.expand((e) => e)) {
|
||||||
lesson.subject.renamedTo = renamedSubjects.isNotEmpty ? renamedSubjects[lesson.subject.id] : null;
|
lesson.subject.renamedTo = renamedSubjects.isNotEmpty
|
||||||
|
? renamedSubjects[lesson.subject.id]
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@ -54,7 +58,8 @@ class TimetableProvider with ChangeNotifier {
|
|||||||
User? user = _user.user;
|
User? user = _user.user;
|
||||||
if (user == null) throw "Cannot fetch Lessons for User null";
|
if (user == null) throw "Cannot fetch Lessons for User null";
|
||||||
String iss = user.instituteCode;
|
String iss = user.instituteCode;
|
||||||
List? lessonsJson = await _kreta.getAPI(KretaAPI.timetable(iss, start: week.start, end: week.end));
|
List? lessonsJson = await _kreta
|
||||||
|
.getAPI(KretaAPI.timetable(iss, start: week.start, end: week.end));
|
||||||
if (lessonsJson == null) throw "Cannot fetch Lessons for User ${user.id}";
|
if (lessonsJson == null) throw "Cannot fetch Lessons for User ${user.id}";
|
||||||
List<Lesson> lessons = lessonsJson.map((e) => Lesson.fromJson(e)).toList();
|
List<Lesson> lessons = lessonsJson.map((e) => Lesson.fromJson(e)).toList();
|
||||||
|
|
||||||
@ -72,7 +77,7 @@ class TimetableProvider with ChangeNotifier {
|
|||||||
if (user == null) throw "Cannot store Lessons for User null";
|
if (user == null) throw "Cannot store Lessons for User null";
|
||||||
String userId = user.id;
|
String userId = user.id;
|
||||||
|
|
||||||
// TODO: clear indexes with weeks outside of the current school year
|
// -TODO: clear indexes with weeks outside of the current school year
|
||||||
await _database.userStore.storeLessons(_lessons, userId: userId);
|
await _database.userStore.storeLessons(_lessons, userId: userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,16 +22,21 @@ class MessageViewTile extends StatelessWidget {
|
|||||||
UserProvider user = Provider.of<UserProvider>(context, listen: false);
|
UserProvider user = Provider.of<UserProvider>(context, listen: false);
|
||||||
String recipientLabel = "";
|
String recipientLabel = "";
|
||||||
|
|
||||||
if (message.recipients.any((r) => r.name == user.student?.name)) recipientLabel = "me".i18n;
|
if (message.recipients.any((r) => r.name == user.student?.name))
|
||||||
|
recipientLabel = "me".i18n;
|
||||||
|
|
||||||
if (recipientLabel != "" && message.recipients.length > 1) {
|
if (recipientLabel != "" && message.recipients.length > 1) {
|
||||||
recipientLabel += " +";
|
recipientLabel += " +";
|
||||||
recipientLabel += message.recipients.where((r) => r.name != user.student?.name).length.toString();
|
recipientLabel += message.recipients
|
||||||
|
.where((r) => r.name != user.student?.name)
|
||||||
|
.length
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipientLabel == "") {
|
if (recipientLabel == "") {
|
||||||
// note: convertint to set to remove duplicates
|
// note: convertint to set to remove duplicates
|
||||||
recipientLabel += message.recipients.map((r) => r.name).toSet().join(", ");
|
recipientLabel +=
|
||||||
|
message.recipients.map((r) => r.name).toSet().join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> attachments = [];
|
List<Widget> attachments = [];
|
||||||
@ -75,9 +80,9 @@ class MessageViewTile extends StatelessWidget {
|
|||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
),
|
),
|
||||||
trailing: Row(
|
trailing: const Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: const [
|
children: [
|
||||||
// IconButton(
|
// IconButton(
|
||||||
// onPressed: () {},
|
// onPressed: () {},
|
||||||
// icon: Icon(FeatherIcons.cornerUpLeft, color: AppColors.of(context).text),
|
// icon: Icon(FeatherIcons.cornerUpLeft, color: AppColors.of(context).text),
|
||||||
|
@ -55,7 +55,9 @@ class _LiveCardState extends State<LiveCard> {
|
|||||||
case LiveCardState.morning:
|
case LiveCardState.morning:
|
||||||
child = LiveCardWidget(
|
child = LiveCardWidget(
|
||||||
key: const Key('livecard.morning'),
|
key: const Key('livecard.morning'),
|
||||||
title: DateFormat("EEEE", I18n.of(context).locale.toString()).format(DateTime.now()).capital(),
|
title: DateFormat("EEEE", I18n.of(context).locale.toString())
|
||||||
|
.format(DateTime.now())
|
||||||
|
.capital(),
|
||||||
icon: FeatherIcons.sun,
|
icon: FeatherIcons.sun,
|
||||||
description: liveCard.nextLesson != null
|
description: liveCard.nextLesson != null
|
||||||
? Text.rich(
|
? Text.rich(
|
||||||
@ -63,26 +65,40 @@ class _LiveCardState extends State<LiveCard> {
|
|||||||
children: [
|
children: [
|
||||||
TextSpan(text: "first_lesson_1".i18n),
|
TextSpan(text: "first_lesson_1".i18n),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: liveCard.nextLesson!.subject.renamedTo ?? liveCard.nextLesson!.subject.name.capital(),
|
text: liveCard.nextLesson!.subject.renamedTo ??
|
||||||
|
liveCard.nextLesson!.subject.name.capital(),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).colorScheme.secondary.withOpacity(.85),
|
color: Theme.of(context)
|
||||||
fontStyle: liveCard.nextLesson!.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.85),
|
||||||
|
fontStyle: liveCard.nextLesson!.subject.isRenamed &&
|
||||||
|
settingsProvider.renamedSubjectsItalics
|
||||||
|
? FontStyle.italic
|
||||||
|
: null),
|
||||||
),
|
),
|
||||||
TextSpan(text: "first_lesson_2".i18n),
|
TextSpan(text: "first_lesson_2".i18n),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: liveCard.nextLesson!.room.capital(),
|
text: liveCard.nextLesson!.room.capital(),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).colorScheme.secondary.withOpacity(.85),
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.85),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(text: "first_lesson_3".i18n),
|
TextSpan(text: "first_lesson_3".i18n),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: DateFormat('H:mm').format(liveCard.nextLesson!.start),
|
text: DateFormat('H:mm')
|
||||||
|
.format(liveCard.nextLesson!.start),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).colorScheme.secondary.withOpacity(.85),
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.85),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(text: "first_lesson_4".i18n),
|
TextSpan(text: "first_lesson_4".i18n),
|
||||||
@ -93,30 +109,48 @@ class _LiveCardState extends State<LiveCard> {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case LiveCardState.duringLesson:
|
case LiveCardState.duringLesson:
|
||||||
final elapsedTime = DateTime.now().difference(liveCard.currentLesson!.start).inSeconds.toDouble() + bellDelay.inSeconds;
|
final elapsedTime = DateTime.now()
|
||||||
final maxTime = liveCard.currentLesson!.end.difference(liveCard.currentLesson!.start).inSeconds.toDouble();
|
.difference(liveCard.currentLesson!.start)
|
||||||
|
.inSeconds
|
||||||
|
.toDouble() +
|
||||||
|
bellDelay.inSeconds;
|
||||||
|
final maxTime = liveCard.currentLesson!.end
|
||||||
|
.difference(liveCard.currentLesson!.start)
|
||||||
|
.inSeconds
|
||||||
|
.toDouble();
|
||||||
|
|
||||||
final showMinutes = maxTime - elapsedTime > 60;
|
final showMinutes = maxTime - elapsedTime > 60;
|
||||||
|
|
||||||
child = LiveCardWidget(
|
child = LiveCardWidget(
|
||||||
key: const Key('livecard.duringLesson'),
|
key: const Key('livecard.duringLesson'),
|
||||||
leading: liveCard.currentLesson!.lessonIndex + (RegExp(r'\d').hasMatch(liveCard.currentLesson!.lessonIndex) ? "." : ""),
|
leading: liveCard.currentLesson!.lessonIndex +
|
||||||
title: liveCard.currentLesson!.subject.renamedTo ?? liveCard.currentLesson!.subject.name.capital(),
|
(RegExp(r'\d').hasMatch(liveCard.currentLesson!.lessonIndex)
|
||||||
|
? "."
|
||||||
|
: ""),
|
||||||
|
title: liveCard.currentLesson!.subject.renamedTo ??
|
||||||
|
liveCard.currentLesson!.subject.name.capital(),
|
||||||
titleItalic: liveCard.currentLesson!.subject.isRenamed,
|
titleItalic: liveCard.currentLesson!.subject.isRenamed,
|
||||||
subtitle: liveCard.currentLesson!.room,
|
subtitle: liveCard.currentLesson!.room,
|
||||||
icon: SubjectIcon.resolveVariant(subject: liveCard.currentLesson!.subject, context: context),
|
icon: SubjectIcon.resolveVariant(
|
||||||
description: liveCard.currentLesson!.description != "" ? Text(liveCard.currentLesson!.description) : null,
|
subject: liveCard.currentLesson!.subject, context: context),
|
||||||
nextSubject: liveCard.nextLesson?.subject.renamedTo ?? liveCard.nextLesson?.subject.name.capital(),
|
description: liveCard.currentLesson!.description != ""
|
||||||
nextSubjectItalic: liveCard.nextLesson?.subject.isRenamed == true && settingsProvider.renamedSubjectsItalics ?? false,
|
? Text(liveCard.currentLesson!.description)
|
||||||
|
: null,
|
||||||
|
nextSubject: liveCard.nextLesson?.subject.renamedTo ??
|
||||||
|
liveCard.nextLesson?.subject.name.capital(),
|
||||||
|
nextSubjectItalic: liveCard.nextLesson?.subject.isRenamed == true &&
|
||||||
|
settingsProvider.renamedSubjectsItalics,
|
||||||
nextRoom: liveCard.nextLesson?.room,
|
nextRoom: liveCard.nextLesson?.room,
|
||||||
progressMax: showMinutes ? maxTime / 60 : maxTime,
|
progressMax: showMinutes ? maxTime / 60 : maxTime,
|
||||||
progressCurrent: showMinutes ? elapsedTime / 60 : elapsedTime,
|
progressCurrent: showMinutes ? elapsedTime / 60 : elapsedTime,
|
||||||
progressAccuracy: showMinutes ? ProgressAccuracy.minutes : ProgressAccuracy.seconds,
|
progressAccuracy:
|
||||||
|
showMinutes ? ProgressAccuracy.minutes : ProgressAccuracy.seconds,
|
||||||
onProgressTap: () {
|
onProgressTap: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
barrierColor: Colors.black,
|
barrierColor: Colors.black,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => HeadsUpCountdown(maxTime: maxTime, elapsedTime: elapsedTime),
|
builder: (context) =>
|
||||||
|
HeadsUpCountdown(maxTime: maxTime, elapsedTime: elapsedTime),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -131,8 +165,15 @@ class _LiveCardState extends State<LiveCard> {
|
|||||||
|
|
||||||
final diff = liveCard.getFloorDifference();
|
final diff = liveCard.getFloorDifference();
|
||||||
|
|
||||||
final maxTime = liveCard.nextLesson!.start.difference(liveCard.prevLesson!.end).inSeconds.toDouble();
|
final maxTime = liveCard.nextLesson!.start
|
||||||
final elapsedTime = DateTime.now().difference(liveCard.prevLesson!.end).inSeconds.toDouble() + bellDelay.inSeconds.toDouble();
|
.difference(liveCard.prevLesson!.end)
|
||||||
|
.inSeconds
|
||||||
|
.toDouble();
|
||||||
|
final elapsedTime = DateTime.now()
|
||||||
|
.difference(liveCard.prevLesson!.end)
|
||||||
|
.inSeconds
|
||||||
|
.toDouble() +
|
||||||
|
bellDelay.inSeconds.toDouble();
|
||||||
|
|
||||||
final showMinutes = maxTime - elapsedTime > 60;
|
final showMinutes = maxTime - elapsedTime > 60;
|
||||||
|
|
||||||
@ -141,14 +182,21 @@ class _LiveCardState extends State<LiveCard> {
|
|||||||
title: "break".i18n,
|
title: "break".i18n,
|
||||||
icon: iconFloorMap[diff],
|
icon: iconFloorMap[diff],
|
||||||
description: liveCard.nextLesson!.room != liveCard.prevLesson!.room
|
description: liveCard.nextLesson!.room != liveCard.prevLesson!.room
|
||||||
? Text("go $diff".i18n.fill([diff != "to room" ? (liveCard.nextLesson!.getFloor() ?? 0) : liveCard.nextLesson!.room]))
|
? Text("go $diff".i18n.fill([
|
||||||
|
diff != "to room"
|
||||||
|
? (liveCard.nextLesson!.getFloor() ?? 0)
|
||||||
|
: liveCard.nextLesson!.room
|
||||||
|
]))
|
||||||
: Text("stay".i18n),
|
: Text("stay".i18n),
|
||||||
nextSubject: liveCard.nextLesson?.subject.renamedTo ?? liveCard.nextLesson?.subject.name.capital(),
|
nextSubject: liveCard.nextLesson?.subject.renamedTo ??
|
||||||
nextSubjectItalic: liveCard.nextLesson?.subject.isRenamed == true && settingsProvider.renamedSubjectsItalics ?? false,
|
liveCard.nextLesson?.subject.name.capital(),
|
||||||
|
nextSubjectItalic: liveCard.nextLesson?.subject.isRenamed == true &&
|
||||||
|
settingsProvider.renamedSubjectsItalics,
|
||||||
nextRoom: diff != "to room" ? liveCard.nextLesson?.room : null,
|
nextRoom: diff != "to room" ? liveCard.nextLesson?.room : null,
|
||||||
progressMax: showMinutes ? maxTime / 60 : maxTime,
|
progressMax: showMinutes ? maxTime / 60 : maxTime,
|
||||||
progressCurrent: showMinutes ? elapsedTime / 60 : elapsedTime,
|
progressCurrent: showMinutes ? elapsedTime / 60 : elapsedTime,
|
||||||
progressAccuracy: showMinutes ? ProgressAccuracy.minutes : ProgressAccuracy.seconds,
|
progressAccuracy:
|
||||||
|
showMinutes ? ProgressAccuracy.minutes : ProgressAccuracy.seconds,
|
||||||
onProgressTap: () {
|
onProgressTap: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
barrierColor: Colors.black,
|
barrierColor: Colors.black,
|
||||||
@ -164,14 +212,18 @@ class _LiveCardState extends State<LiveCard> {
|
|||||||
case LiveCardState.afternoon:
|
case LiveCardState.afternoon:
|
||||||
child = LiveCardWidget(
|
child = LiveCardWidget(
|
||||||
key: const Key('livecard.afternoon'),
|
key: const Key('livecard.afternoon'),
|
||||||
title: DateFormat("EEEE", I18n.of(context).locale.toString()).format(DateTime.now()).capital(),
|
title: DateFormat("EEEE", I18n.of(context).locale.toString())
|
||||||
|
.format(DateTime.now())
|
||||||
|
.capital(),
|
||||||
icon: FeatherIcons.coffee,
|
icon: FeatherIcons.coffee,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case LiveCardState.night:
|
case LiveCardState.night:
|
||||||
child = LiveCardWidget(
|
child = LiveCardWidget(
|
||||||
key: const Key('livecard.night'),
|
key: const Key('livecard.night'),
|
||||||
title: DateFormat("EEEE", I18n.of(context).locale.toString()).format(DateTime.now()).capital(),
|
title: DateFormat("EEEE", I18n.of(context).locale.toString())
|
||||||
|
.format(DateTime.now())
|
||||||
|
.capital(),
|
||||||
icon: FeatherIcons.moon,
|
icon: FeatherIcons.moon,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -12,14 +12,16 @@ class PremiumButton extends StatefulWidget {
|
|||||||
State<PremiumButton> createState() => _PremiumButtonState();
|
State<PremiumButton> createState() => _PremiumButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PremiumButtonState extends State<PremiumButton> with TickerProviderStateMixin {
|
class _PremiumButtonState extends State<PremiumButton>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
late final AnimationController _animation;
|
late final AnimationController _animation;
|
||||||
bool _heldDown = false;
|
bool _heldDown = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_animation = AnimationController(vsync: this, duration: const Duration(seconds: 3));
|
_animation =
|
||||||
|
AnimationController(vsync: this, duration: const Duration(seconds: 3));
|
||||||
_animation.repeat();
|
_animation.repeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +40,8 @@ class _PremiumButtonState extends State<PremiumButton> with TickerProviderStateM
|
|||||||
transitionType: ContainerTransitionType.fadeThrough,
|
transitionType: ContainerTransitionType.fadeThrough,
|
||||||
openElevation: 0,
|
openElevation: 0,
|
||||||
closedElevation: 0,
|
closedElevation: 0,
|
||||||
closedShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
closedShape:
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
||||||
openBuilder: (context, _) => const PremiumScreen(),
|
openBuilder: (context, _) => const PremiumScreen(),
|
||||||
closedBuilder: (context, action) => GestureDetector(
|
closedBuilder: (context, action) => GestureDetector(
|
||||||
onTapDown: (_) => setState(() => _heldDown = true),
|
onTapDown: (_) => setState(() => _heldDown = true),
|
||||||
@ -57,16 +60,20 @@ class _PremiumButtonState extends State<PremiumButton> with TickerProviderStateM
|
|||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(14.0),
|
borderRadius: BorderRadius.circular(14.0),
|
||||||
child: ImageFiltered(
|
child: ImageFiltered(
|
||||||
imageFilter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
|
imageFilter:
|
||||||
|
ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 70,
|
height: 70,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: SweepGradient(colors: const [
|
gradient: SweepGradient(
|
||||||
Colors.blue,
|
colors: const [
|
||||||
Colors.orange,
|
Colors.blue,
|
||||||
Colors.purple,
|
Colors.orange,
|
||||||
Colors.blue,
|
Colors.purple,
|
||||||
], transform: GradientRotation(_animation.value * 6.283185)),
|
Colors.blue,
|
||||||
|
],
|
||||||
|
transform: GradientRotation(
|
||||||
|
_animation.value * 6.283185)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -92,9 +99,9 @@ class _PremiumButtonState extends State<PremiumButton> with TickerProviderStateM
|
|||||||
Color(0xff1EA18F),
|
Color(0xff1EA18F),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: const Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: const [
|
children: [
|
||||||
Icon(FilcIcons.premium, color: Colors.white),
|
Icon(FilcIcons.premium, color: Colors.white),
|
||||||
SizedBox(width: 12.0),
|
SizedBox(width: 12.0),
|
||||||
Text(
|
Text(
|
||||||
|
@ -21,8 +21,9 @@ class PremiumScreen extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final middleColor =
|
final middleColor = Theme.of(context).brightness == Brightness.dark
|
||||||
Theme.of(context).brightness == Brightness.dark ? const Color.fromARGB(255, 20, 57, 46) : const Color.fromARGB(255, 10, 140, 123);
|
? const Color.fromARGB(255, 20, 57, 46)
|
||||||
|
: const Color.fromARGB(255, 10, 140, 123);
|
||||||
|
|
||||||
final future = FilcAPI.getSupporters();
|
final future = FilcAPI.getSupporters();
|
||||||
|
|
||||||
@ -78,7 +79,8 @@ class PremiumScreen extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 24.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -87,16 +89,25 @@ class PremiumScreen extends StatelessWidget {
|
|||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
const Text(
|
const Text(
|
||||||
"Még több filc.",
|
"Még több filc.",
|
||||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 25.0, color: Colors.white),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 25.0,
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
const Text(
|
const Text(
|
||||||
"reFilc Premium.",
|
"reFilc Premium.",
|
||||||
style: TextStyle(fontWeight: FontWeight.w800, fontSize: 35.0, color: Colors.white),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
fontSize: 35.0,
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 15.0),
|
const SizedBox(height: 15.0),
|
||||||
Text(
|
Text(
|
||||||
"Támogasd a filcet, és szerezz cserébe pár kényelmes jutalmat!",
|
"Támogasd a filcet, és szerezz cserébe pár kényelmes jutalmat!",
|
||||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: Colors.white.withOpacity(.8)),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 20,
|
||||||
|
color: Colors.white.withOpacity(.8)),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 25.0),
|
const SizedBox(height: 25.0),
|
||||||
SupportersButton(supporters: future),
|
SupportersButton(supporters: future),
|
||||||
@ -110,43 +121,61 @@ class PremiumScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24.0).add(const EdgeInsets.only(bottom: 100)),
|
padding: const EdgeInsets.symmetric(horizontal: 24.0)
|
||||||
|
.add(const EdgeInsets.only(bottom: 100)),
|
||||||
sliver: SliverToBoxAdapter(
|
sliver: SliverToBoxAdapter(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
PremiumPlanCard(
|
PremiumPlanCard(
|
||||||
icon: const Icon(FilcIcons.kupak),
|
icon: const Icon(FilcIcons.kupak),
|
||||||
title: Text("Kupak", style: TextStyle(foreground: GradientStyles.kupakPaint)),
|
title: Text("Kupak",
|
||||||
|
style: TextStyle(
|
||||||
|
foreground: GradientStyles.kupakPaint)),
|
||||||
gradient: GradientStyles.kupak,
|
gradient: GradientStyles.kupak,
|
||||||
price: 2,
|
price: 2,
|
||||||
description: const Text("Szabd személyre a filcet és láss részletesebb statisztikákat."),
|
description: const Text(
|
||||||
url: "https://github.com/sponsors/filc/sponsorships?tier_id=238453&preview=true",
|
"Szabd személyre a filcet és láss részletesebb statisztikákat."),
|
||||||
active: ActiveSponsorCard.estimateLevel(context.watch<PremiumProvider>().scopes) == PremiumFeatureLevel.kupak,
|
url:
|
||||||
|
"https://github.com/sponsors/filc/sponsorships?tier_id=238453&preview=true",
|
||||||
|
active: ActiveSponsorCard.estimateLevel(
|
||||||
|
context.watch<PremiumProvider>().scopes) ==
|
||||||
|
PremiumFeatureLevel.kupak,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8.0),
|
const SizedBox(height: 8.0),
|
||||||
PremiumPlanCard(
|
PremiumPlanCard(
|
||||||
icon: const Icon(FilcIcons.tinta),
|
icon: const Icon(FilcIcons.tinta),
|
||||||
title: Text("Tinta", style: TextStyle(foreground: GradientStyles.tintaPaint)),
|
title: Text("Tinta",
|
||||||
|
style: TextStyle(
|
||||||
|
foreground: GradientStyles.tintaPaint)),
|
||||||
gradient: GradientStyles.tinta,
|
gradient: GradientStyles.tinta,
|
||||||
price: 5,
|
price: 5,
|
||||||
description: const Text("Kényelmesebb órarend, asztali alkalmazás és célok kitűzése."),
|
description: const Text(
|
||||||
url: "https://github.com/sponsors/filc/sponsorships?tier_id=238454&preview=true",
|
"Kényelmesebb órarend, asztali alkalmazás és célok kitűzése."),
|
||||||
active: ActiveSponsorCard.estimateLevel(context.watch<PremiumProvider>().scopes) == PremiumFeatureLevel.tinta,
|
url:
|
||||||
|
"https://github.com/sponsors/filc/sponsorships?tier_id=238454&preview=true",
|
||||||
|
active: ActiveSponsorCard.estimateLevel(
|
||||||
|
context.watch<PremiumProvider>().scopes) ==
|
||||||
|
PremiumFeatureLevel.tinta,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
PremiumGoalCard(progress: snapshot.data?.progress ?? 0, target: snapshot.data?.max ?? 1),
|
PremiumGoalCard(
|
||||||
|
progress: snapshot.data?.progress ?? 0,
|
||||||
|
target: snapshot.data?.max ?? 1),
|
||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
const GithubConnectButton(),
|
const GithubConnectButton(),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 14.0).add(const EdgeInsets.only(top: 12.0)),
|
padding: const EdgeInsets.symmetric(vertical: 14.0)
|
||||||
child: Row(
|
.add(const EdgeInsets.only(top: 12.0)),
|
||||||
children: const [
|
child: const Row(
|
||||||
|
children: [
|
||||||
Icon(FilcIcons.kupak),
|
Icon(FilcIcons.kupak),
|
||||||
SizedBox(width: 12.0),
|
SizedBox(width: 12.0),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"Kupak jutalmak",
|
"Kupak jutalmak",
|
||||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -154,40 +183,50 @@ class PremiumScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
PremiumRewardCard(
|
PremiumRewardCard(
|
||||||
imageKey: "premium_nickname_showcase",
|
imageKey: "premium_nickname_showcase",
|
||||||
icon: SvgPicture.asset("assets/images/nickname_icon.svg", color: Theme.of(context).iconTheme.color),
|
icon: SvgPicture.asset(
|
||||||
|
"assets/images/nickname_icon.svg",
|
||||||
|
color: Theme.of(context).iconTheme.color),
|
||||||
title: const Text("Profil személyre szabás"),
|
title: const Text("Profil személyre szabás"),
|
||||||
description: const Text("Állíts be egy saját becenevet és egy profilképet (akár animáltat is!)"),
|
description: const Text(
|
||||||
|
"Állíts be egy saját becenevet és egy profilképet (akár animáltat is!)"),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 14.0),
|
const SizedBox(height: 14.0),
|
||||||
PremiumRewardCard(
|
PremiumRewardCard(
|
||||||
imageKey: "premium_theme_showcase",
|
imageKey: "premium_theme_showcase",
|
||||||
icon: SvgPicture.asset("assets/images/theme_icon.svg", color: Theme.of(context).iconTheme.color),
|
icon: SvgPicture.asset("assets/images/theme_icon.svg",
|
||||||
|
color: Theme.of(context).iconTheme.color),
|
||||||
title: const Text("Téma+"),
|
title: const Text("Téma+"),
|
||||||
description: const Text("Válassz saját háttérszínt és kártyaszínt is, akár saját HEX-kóddal!"),
|
description: const Text(
|
||||||
|
"Válassz saját háttérszínt és kártyaszínt is, akár saját HEX-kóddal!"),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 14.0),
|
const SizedBox(height: 14.0),
|
||||||
PremiumRewardCard(
|
PremiumRewardCard(
|
||||||
imageKey: "premium_stats_showcase",
|
imageKey: "premium_stats_showcase",
|
||||||
icon: SvgPicture.asset("assets/images/stats_icon.svg", color: Theme.of(context).iconTheme.color),
|
icon: SvgPicture.asset("assets/images/stats_icon.svg",
|
||||||
|
color: Theme.of(context).iconTheme.color),
|
||||||
title: const Text("Részletes jegy statisztika"),
|
title: const Text("Részletes jegy statisztika"),
|
||||||
description: const Text("Válassz heti, havi és háromhavi időtartam közül, és pontosan lásd, mennyi jegyed van."),
|
description: const Text(
|
||||||
|
"Válassz heti, havi és háromhavi időtartam közül, és pontosan lásd, mennyi jegyed van."),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 14.0),
|
const SizedBox(height: 14.0),
|
||||||
const PremiumRewardCard(
|
const PremiumRewardCard(
|
||||||
title: Text("Még pár dolog..."),
|
title: Text("Még pár dolog..."),
|
||||||
description:
|
description: Text(
|
||||||
Text("🔣\tVálassz ikon témát\n✨\tPrémium rang és csevegő a discord szerverünkön\n📬\tElsőbbségi segítségnyújtás"),
|
"🔣\tVálassz ikon témát\n✨\tPrémium rang és csevegő a discord szerverünkön\n📬\tElsőbbségi segítségnyújtás"),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 14.0).add(const EdgeInsets.only(top: 12.0)),
|
padding: const EdgeInsets.symmetric(vertical: 14.0)
|
||||||
child: Row(
|
.add(const EdgeInsets.only(top: 12.0)),
|
||||||
children: const [
|
child: const Row(
|
||||||
|
children: [
|
||||||
Icon(FilcIcons.tinta),
|
Icon(FilcIcons.tinta),
|
||||||
SizedBox(width: 12.0),
|
SizedBox(width: 12.0),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"Tinta jutalmak",
|
"Tinta jutalmak",
|
||||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -195,48 +234,62 @@ class PremiumScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
PremiumRewardCard(
|
PremiumRewardCard(
|
||||||
imageKey: "premium_timetable_showcase",
|
imageKey: "premium_timetable_showcase",
|
||||||
icon: SvgPicture.asset("assets/images/timetable_icon.svg", color: Theme.of(context).iconTheme.color),
|
icon: SvgPicture.asset(
|
||||||
|
"assets/images/timetable_icon.svg",
|
||||||
|
color: Theme.of(context).iconTheme.color),
|
||||||
title: const Text("Heti órarend nézet"),
|
title: const Text("Heti órarend nézet"),
|
||||||
description:
|
description: const Text(
|
||||||
const Text("Egy órarend, ami a teljes képernyődet kihasználja, csak nem olyan idegesítő, mint az eKRÉTA féle."),
|
"Egy órarend, ami a teljes képernyődet kihasználja, csak nem olyan idegesítő, mint az eKRÉTA féle."),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 14.0),
|
const SizedBox(height: 14.0),
|
||||||
PremiumRewardCard(
|
PremiumRewardCard(
|
||||||
imageKey: "premium_widget_showcase",
|
imageKey: "premium_widget_showcase",
|
||||||
icon: SvgPicture.asset("assets/images/widget_icon.svg", color: Theme.of(context).iconTheme.color),
|
icon: SvgPicture.asset(
|
||||||
|
"assets/images/widget_icon.svg",
|
||||||
|
color: Theme.of(context).iconTheme.color),
|
||||||
title: const Text("Widget"),
|
title: const Text("Widget"),
|
||||||
description: const Text("Mindig lásd, milyen órád lesz, a kezdőképernyőd kényelméből."),
|
description: const Text(
|
||||||
|
"Mindig lásd, milyen órád lesz, a kezdőképernyőd kényelméből."),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 14.0),
|
const SizedBox(height: 14.0),
|
||||||
PremiumRewardCard(
|
PremiumRewardCard(
|
||||||
soon: true,
|
soon: true,
|
||||||
imageKey: "premium_goal_showcase",
|
imageKey: "premium_goal_showcase",
|
||||||
icon: SvgPicture.asset("assets/images/goal_icon.svg", color: Theme.of(context).iconTheme.color),
|
icon: SvgPicture.asset("assets/images/goal_icon.svg",
|
||||||
|
color: Theme.of(context).iconTheme.color),
|
||||||
title: const Text("Cél követés"),
|
title: const Text("Cél követés"),
|
||||||
description: const Text("Add meg, mi a célod, és mi majd kiszámoljuk, hogyan juthatsz oda!"),
|
description: const Text(
|
||||||
|
"Add meg, mi a célod, és mi majd kiszámoljuk, hogyan juthatsz oda!"),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 14.0),
|
const SizedBox(height: 14.0),
|
||||||
PremiumRewardCard(
|
PremiumRewardCard(
|
||||||
soon: true,
|
soon: true,
|
||||||
imageKey: "premium_desktop_showcase",
|
imageKey: "premium_desktop_showcase",
|
||||||
icon: SvgPicture.asset("assets/images/desktop_icon.svg", color: Theme.of(context).iconTheme.color),
|
icon: SvgPicture.asset(
|
||||||
|
"assets/images/desktop_icon.svg",
|
||||||
|
color: Theme.of(context).iconTheme.color),
|
||||||
title: const Text("Asztali verzió"),
|
title: const Text("Asztali verzió"),
|
||||||
description: const Text("Érd el a reFilcet a gépeden is, és menekülj meg a csúnya felhasználói felületektől!"),
|
description: const Text(
|
||||||
|
"Érd el a reFilcet a gépeden is, és menekülj meg a csúnya felhasználói felületektől!"),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 14.0),
|
const SizedBox(height: 14.0),
|
||||||
const PremiumRewardCard(
|
const PremiumRewardCard(
|
||||||
title: Text("Még pár dolog..."),
|
title: Text("Még pár dolog..."),
|
||||||
description: Text("🖋️\tMinden kupak jutalom\n✨\tKorai hozzáférés új verziókhoz"),
|
description: Text(
|
||||||
|
"🖋️\tMinden kupak jutalom\n✨\tKorai hozzáférés új verziókhoz"),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 14.0).add(const EdgeInsets.only(top: 12.0)),
|
padding: const EdgeInsets.symmetric(vertical: 14.0)
|
||||||
child: Row(
|
.add(const EdgeInsets.only(top: 12.0)),
|
||||||
children: const [
|
child: const Row(
|
||||||
|
children: [
|
||||||
SizedBox(width: 12.0),
|
SizedBox(width: 12.0),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"Mire vársz még?",
|
"Mire vársz még?",
|
||||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -244,20 +297,24 @@ class PremiumScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
GithubCard(
|
GithubCard(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
|
Navigator.of(context)
|
||||||
|
.push(MaterialPageRoute(builder: (context) {
|
||||||
return const PremiumActivationView();
|
return const PremiumActivationView();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 14.0).add(const EdgeInsets.only(top: 12.0)),
|
padding: const EdgeInsets.symmetric(vertical: 14.0)
|
||||||
child: Row(
|
.add(const EdgeInsets.only(top: 12.0)),
|
||||||
children: const [
|
child: const Row(
|
||||||
|
children: [
|
||||||
SizedBox(width: 12.0),
|
SizedBox(width: 12.0),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"Gyakori kérdések",
|
"Gyakori kérdések",
|
||||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -95,6 +95,46 @@ class NavigationScreenState extends State<NavigationScreen>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Platform messages are asynchronous, so we initialize in an async method.
|
||||||
|
Future<void> initPlatformState() async {
|
||||||
|
// Configure BackgroundFetch.
|
||||||
|
int status = await BackgroundFetch.configure(
|
||||||
|
BackgroundFetchConfig(
|
||||||
|
minimumFetchInterval: 15,
|
||||||
|
stopOnTerminate: false,
|
||||||
|
enableHeadless: true,
|
||||||
|
requiresBatteryNotLow: false,
|
||||||
|
requiresCharging: false,
|
||||||
|
requiresStorageNotLow: false,
|
||||||
|
requiresDeviceIdle: false,
|
||||||
|
requiredNetworkType: NetworkType.ANY), (String taskId) async {
|
||||||
|
// <-- Event handler
|
||||||
|
// This is the fetch-event callback.
|
||||||
|
if (kDebugMode) {
|
||||||
|
print("[BackgroundFetch] Event received $taskId");
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMPORTANT: You must signal completion of your task or the OS can punish your app
|
||||||
|
// for taking too long in the background.
|
||||||
|
BackgroundFetch.finish(taskId);
|
||||||
|
}, (String taskId) async {
|
||||||
|
// <-- Task timeout handler.
|
||||||
|
// This task has exceeded its allowed running-time. You must stop what you're doing and immediately .finish(taskId)
|
||||||
|
if (kDebugMode) {
|
||||||
|
print("[BackgroundFetch] TASK TIMEOUT taskId: $taskId");
|
||||||
|
}
|
||||||
|
BackgroundFetch.finish(taskId);
|
||||||
|
});
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('[BackgroundFetch] configure success: $status');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the widget was removed from the tree while the asynchronous platform
|
||||||
|
// message was in flight, we want to discard the reply rather than calling
|
||||||
|
// setState to update our non-existent appearance.
|
||||||
|
if (!mounted) return;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -138,7 +178,10 @@ class NavigationScreenState extends State<NavigationScreen>
|
|||||||
@override
|
@override
|
||||||
void didChangePlatformBrightness() {
|
void didChangePlatformBrightness() {
|
||||||
if (settings.theme == ThemeMode.system) {
|
if (settings.theme == ThemeMode.system) {
|
||||||
Brightness? brightness = WidgetsBinding.instance.window.platformBrightness;
|
// ignore: deprecated_member_use
|
||||||
|
Brightness? brightness =
|
||||||
|
// ignore: deprecated_member_use
|
||||||
|
WidgetsBinding.instance.window.platformBrightness;
|
||||||
Provider.of<ThemeModeObserver>(context, listen: false).changeTheme(
|
Provider.of<ThemeModeObserver>(context, listen: false).changeTheme(
|
||||||
brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark);
|
brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark);
|
||||||
}
|
}
|
||||||
|
@ -484,8 +484,9 @@ class _BellDelaySettingState extends State<BellDelaySetting>
|
|||||||
Duration sdiff = lesson.start.difference(now);
|
Duration sdiff = lesson.start.difference(now);
|
||||||
Duration ediff = lesson.end.difference(now);
|
Duration ediff = lesson.end.difference(now);
|
||||||
|
|
||||||
if (closest == null || sdiff.abs() < closest.abs())
|
if (closest == null || sdiff.abs() < closest.abs()) {
|
||||||
closest = sdiff;
|
closest = sdiff;
|
||||||
|
}
|
||||||
if (ediff.abs() < closest.abs()) closest = ediff;
|
if (ediff.abs() < closest.abs()) closest = ediff;
|
||||||
}
|
}
|
||||||
if (closest != null) {
|
if (closest != null) {
|
||||||
|
@ -84,34 +84,37 @@ class _SettingsScreenState extends State<SettingsScreen>
|
|||||||
|
|
||||||
String _firstName;
|
String _firstName;
|
||||||
|
|
||||||
List<String> _nameParts = user.displayName?.split(" ") ?? ["?"];
|
List<String> _nameParts = account.displayName.split(" ");
|
||||||
if (!settings.presentationMode) {
|
if (!settings.presentationMode) {
|
||||||
_firstName = _nameParts.length > 1 ? _nameParts[1] : _nameParts[0];
|
_firstName = _nameParts.length > 1 ? _nameParts[1] : _nameParts[0];
|
||||||
} else {
|
} else {
|
||||||
_firstName = "János";
|
_firstName = "János";
|
||||||
}
|
}
|
||||||
|
|
||||||
accountTiles.add(AccountTile(
|
accountTiles.add(
|
||||||
name: Text(!settings.presentationMode ? account.name : "János",
|
AccountTile(
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500)),
|
name: Text(!settings.presentationMode ? account.name : "János",
|
||||||
username:
|
style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||||
Text(!settings.presentationMode ? account.username : "01234567890"),
|
username: Text(
|
||||||
profileImage: ProfileImage(
|
!settings.presentationMode ? account.username : "01234567890"),
|
||||||
name: _firstName,
|
profileImage: ProfileImage(
|
||||||
backgroundColor: Theme.of(context)
|
name: _firstName,
|
||||||
.colorScheme
|
role: account.role,
|
||||||
.primary, //!settings.presentationMode
|
profilePictureString: account.picture,
|
||||||
//? ColorUtils.stringToColor(account.name)
|
backgroundColor: Theme.of(context)
|
||||||
//: Theme.of(context).colorScheme.secondary,
|
.colorScheme
|
||||||
role: account.role,
|
.primary, //!settings.presentationMode
|
||||||
|
//? ColorUtils.stringToColor(account.name)
|
||||||
|
//: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
user.setUser(account.id);
|
||||||
|
restore().then((_) => user.setUser(account.id));
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
onTapMenu: () => _showBottomSheet(account),
|
||||||
),
|
),
|
||||||
onTap: () {
|
);
|
||||||
user.setUser(account.id);
|
|
||||||
restore().then((_) => user.setUser(account.id));
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
onTapMenu: () => _showBottomSheet(account),
|
|
||||||
));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,7 +976,9 @@ class _SettingsScreenState extends State<SettingsScreen>
|
|||||||
child: Text("v${release.data!['version']}"),
|
child: Text("v${release.data!['version']}"),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
String envAppVer = const String.fromEnvironment("APPVER", defaultValue: "?");
|
String envAppVer = const String.fromEnvironment(
|
||||||
|
"APPVER",
|
||||||
|
defaultValue: "?");
|
||||||
return DefaultTextStyle(
|
return DefaultTextStyle(
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
|
@ -5,6 +5,6 @@ class GradesBody extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column();
|
return const Column();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,6 @@ class PersonalityBody extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column();
|
return const Column();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ class _ActivationDashboardState extends State<ActivationDashboard> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
manualActivationLoading = true;
|
manualActivationLoading = true;
|
||||||
});
|
});
|
||||||
final result = await context.read<PremiumProvider>().auth.finishAuth(data.text!);
|
final result =
|
||||||
|
await context.read<PremiumProvider>().auth.finishAuth(data.text!);
|
||||||
setState(() {
|
setState(() {
|
||||||
manualActivationLoading = false;
|
manualActivationLoading = false;
|
||||||
});
|
});
|
||||||
@ -63,24 +64,27 @@ class _ActivationDashboardState extends State<ActivationDashboard> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
Card(
|
Card(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
shape: RoundedRectangleBorder(
|
||||||
child: Padding(
|
borderRadius: BorderRadius.circular(14.0)),
|
||||||
padding: const EdgeInsets.all(20.0),
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.all(20.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: const [
|
children: [
|
||||||
Icon(FeatherIcons.alertTriangle, size: 20.0, color: Colors.orange),
|
Icon(FeatherIcons.alertTriangle,
|
||||||
|
size: 20.0, color: Colors.orange),
|
||||||
SizedBox(width: 12.0),
|
SizedBox(width: 12.0),
|
||||||
Text(
|
Text(
|
||||||
"Figyelem!",
|
"Figyelem!",
|
||||||
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
|
style: TextStyle(
|
||||||
|
fontSize: 18.0, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6.0),
|
SizedBox(height: 6.0),
|
||||||
const Text(
|
Text(
|
||||||
"Csak akkor érzékeli a Filc a támogatói státuszod, ha nem állítod privátra!",
|
"Csak akkor érzékeli a Filc a támogatói státuszod, ha nem állítod privátra!",
|
||||||
style: TextStyle(fontSize: 16.0),
|
style: TextStyle(fontSize: 16.0),
|
||||||
),
|
),
|
||||||
@ -90,24 +94,27 @@ class _ActivationDashboardState extends State<ActivationDashboard> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
Card(
|
Card(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
shape: RoundedRectangleBorder(
|
||||||
child: Padding(
|
borderRadius: BorderRadius.circular(14.0)),
|
||||||
padding: const EdgeInsets.all(20.0),
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.all(20.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: const [
|
children: [
|
||||||
Icon(FeatherIcons.alertTriangle, size: 20.0, color: Colors.orange),
|
Icon(FeatherIcons.alertTriangle,
|
||||||
|
size: 20.0, color: Colors.orange),
|
||||||
SizedBox(width: 12.0),
|
SizedBox(width: 12.0),
|
||||||
Text(
|
Text(
|
||||||
"Figyelem!",
|
"Figyelem!",
|
||||||
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
|
style: TextStyle(
|
||||||
|
fontSize: 18.0, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6.0),
|
SizedBox(height: 6.0),
|
||||||
const Text(
|
Text(
|
||||||
"Ha friss támogató vagy, 5-10 percbe telhet az aktiválás. Kérlek gyere vissza később, és próbáld újra!",
|
"Ha friss támogató vagy, 5-10 percbe telhet az aktiválás. Kérlek gyere vissza később, és próbáld újra!",
|
||||||
style: TextStyle(fontSize: 16.0),
|
style: TextStyle(fontSize: 16.0),
|
||||||
),
|
),
|
||||||
@ -117,7 +124,8 @@ class _ActivationDashboardState extends State<ActivationDashboard> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
Card(
|
Card(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(14.0)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -125,15 +133,20 @@ class _ActivationDashboardState extends State<ActivationDashboard> {
|
|||||||
children: [
|
children: [
|
||||||
const Text(
|
const Text(
|
||||||
"Ha bejelentkezés után nem lép vissza az alkalmazásba automatikusan, aktiváld a támogatásod manuálisan",
|
"Ha bejelentkezés után nem lép vissza az alkalmazásba automatikusan, aktiváld a támogatásod manuálisan",
|
||||||
style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
TextStyle(fontSize: 15.0, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6.0),
|
const SizedBox(height: 6.0),
|
||||||
Center(
|
Center(
|
||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
onPressed: onManualActivation,
|
onPressed: onManualActivation,
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
foregroundColor: MaterialStatePropertyAll(Theme.of(context).colorScheme.secondary),
|
foregroundColor: MaterialStatePropertyAll(
|
||||||
overlayColor: MaterialStatePropertyAll(Theme.of(context).colorScheme.secondary.withOpacity(.1)),
|
Theme.of(context).colorScheme.secondary),
|
||||||
|
overlayColor: MaterialStatePropertyAll(Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.1)),
|
||||||
),
|
),
|
||||||
icon: manualActivationLoading
|
icon: manualActivationLoading
|
||||||
? const SizedBox(
|
? const SizedBox(
|
||||||
@ -164,8 +177,10 @@ class _ActivationDashboardState extends State<ActivationDashboard> {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
foregroundColor: MaterialStatePropertyAll(AppColors.of(context).text),
|
foregroundColor:
|
||||||
overlayColor: MaterialStatePropertyAll(AppColors.of(context).text.withOpacity(.1)),
|
MaterialStatePropertyAll(AppColors.of(context).text),
|
||||||
|
overlayColor: MaterialStatePropertyAll(
|
||||||
|
AppColors.of(context).text.withOpacity(.1)),
|
||||||
),
|
),
|
||||||
icon: const Icon(FeatherIcons.arrowLeft, size: 20.0),
|
icon: const Icon(FeatherIcons.arrowLeft, size: 20.0),
|
||||||
label: const Text(
|
label: const Text(
|
||||||
|
@ -22,7 +22,8 @@ import 'package:provider/provider.dart';
|
|||||||
import 'modify_subject_names.i18n.dart';
|
import 'modify_subject_names.i18n.dart';
|
||||||
|
|
||||||
class MenuRenamedSubjects extends StatelessWidget {
|
class MenuRenamedSubjects extends StatelessWidget {
|
||||||
const MenuRenamedSubjects({Key? key, required this.settings}) : super(key: key);
|
const MenuRenamedSubjects({Key? key, required this.settings})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
final SettingsProvider settings;
|
final SettingsProvider settings;
|
||||||
|
|
||||||
@ -31,8 +32,10 @@ class MenuRenamedSubjects extends StatelessWidget {
|
|||||||
return PanelButton(
|
return PanelButton(
|
||||||
padding: const EdgeInsets.only(left: 14.0),
|
padding: const EdgeInsets.only(left: 14.0),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (!Provider.of<PremiumProvider>(context, listen: false).hasScope(PremiumScopes.renameSubjects)) {
|
if (!Provider.of<PremiumProvider>(context, listen: false)
|
||||||
PremiumLockedFeatureUpsell.show(context: context, feature: PremiumFeature.subjectrename);
|
.hasScope(PremiumScopes.renameSubjects)) {
|
||||||
|
PremiumLockedFeatureUpsell.show(
|
||||||
|
context: context, feature: PremiumFeature.subjectrename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,23 +45,32 @@ class MenuRenamedSubjects extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
title: Text(
|
title: Text(
|
||||||
"rename_subjects".i18n,
|
"rename_subjects".i18n,
|
||||||
style: TextStyle(color: AppColors.of(context).text.withOpacity(settings.renamedSubjectsEnabled ? 1.0 : .5)),
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context)
|
||||||
|
.text
|
||||||
|
.withOpacity(settings.renamedSubjectsEnabled ? 1.0 : .5)),
|
||||||
),
|
),
|
||||||
leading: settings.renamedSubjectsEnabled
|
leading: settings.renamedSubjectsEnabled
|
||||||
? const Icon(FeatherIcons.penTool)
|
? const Icon(FeatherIcons.penTool)
|
||||||
: Icon(FeatherIcons.penTool, color: AppColors.of(context).text.withOpacity(.25)),
|
: Icon(FeatherIcons.penTool,
|
||||||
|
color: AppColors.of(context).text.withOpacity(.25)),
|
||||||
trailingDivider: true,
|
trailingDivider: true,
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
onChanged: (v) async {
|
onChanged: (v) async {
|
||||||
if (!Provider.of<PremiumProvider>(context, listen: false).hasScope(PremiumScopes.renameSubjects)) {
|
if (!Provider.of<PremiumProvider>(context, listen: false)
|
||||||
PremiumLockedFeatureUpsell.show(context: context, feature: PremiumFeature.subjectrename);
|
.hasScope(PremiumScopes.renameSubjects)) {
|
||||||
|
PremiumLockedFeatureUpsell.show(
|
||||||
|
context: context, feature: PremiumFeature.subjectrename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.update(renamedSubjectsEnabled: v);
|
settings.update(renamedSubjectsEnabled: v);
|
||||||
await Provider.of<GradeProvider>(context, listen: false).convertBySettings();
|
await Provider.of<GradeProvider>(context, listen: false)
|
||||||
await Provider.of<TimetableProvider>(context, listen: false).convertBySettings();
|
.convertBySettings();
|
||||||
await Provider.of<AbsenceProvider>(context, listen: false).convertBySettings();
|
await Provider.of<TimetableProvider>(context, listen: false)
|
||||||
|
.convertBySettings();
|
||||||
|
await Provider.of<AbsenceProvider>(context, listen: false)
|
||||||
|
.convertBySettings();
|
||||||
},
|
},
|
||||||
value: settings.renamedSubjectsEnabled,
|
value: settings.renamedSubjectsEnabled,
|
||||||
activeColor: Theme.of(context).colorScheme.secondary,
|
activeColor: Theme.of(context).colorScheme.secondary,
|
||||||
@ -87,7 +99,11 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
subjects = Provider.of<GradeProvider>(context, listen: false).grades.map((e) => e.subject).toSet().toList()
|
subjects = Provider.of<GradeProvider>(context, listen: false)
|
||||||
|
.grades
|
||||||
|
.map((e) => e.subject)
|
||||||
|
.toSet()
|
||||||
|
.toList()
|
||||||
..sort((a, b) => a.name.compareTo(b.name));
|
..sort((a, b) => a.name.compareTo(b.name));
|
||||||
user = Provider.of<UserProvider>(context, listen: false);
|
user = Provider.of<UserProvider>(context, listen: false);
|
||||||
dbProvider = Provider.of<DatabaseProvider>(context, listen: false);
|
dbProvider = Provider.of<DatabaseProvider>(context, listen: false);
|
||||||
@ -102,7 +118,8 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) => StatefulBuilder(builder: (context, setS) {
|
builder: (context) => StatefulBuilder(builder: (context, setS) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
||||||
title: Text("rename_subject".i18n),
|
title: Text("rename_subject".i18n),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@ -162,13 +179,18 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
border: Border.all(color: Colors.grey, width: 2),
|
border: Border.all(color: Colors.grey, width: 2),
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 12.0, horizontal: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedSubjectId == null ? "select_subject".i18n : subjects.firstWhere((element) => element.id == selectedSubjectId).name,
|
selectedSubjectId == null
|
||||||
style: Theme.of(context)
|
? "select_subject".i18n
|
||||||
.textTheme
|
: subjects
|
||||||
.titleSmall!
|
.firstWhere(
|
||||||
.copyWith(fontWeight: FontWeight.w700, color: AppColors.of(context).text.withOpacity(0.75)),
|
(element) => element.id == selectedSubjectId)
|
||||||
|
.name,
|
||||||
|
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.75)),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
@ -183,11 +205,13 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
controller: _subjectName,
|
controller: _subjectName,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderSide: const BorderSide(color: Colors.grey, width: 1.5),
|
borderSide:
|
||||||
|
const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: const BorderSide(color: Colors.grey, width: 1.5),
|
borderSide:
|
||||||
|
const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
@ -227,10 +251,14 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
final renamedSubs = await fetchRenamedSubjects();
|
final renamedSubs = await fetchRenamedSubjects();
|
||||||
|
|
||||||
renamedSubs[selectedSubjectId!] = _subjectName.text;
|
renamedSubs[selectedSubjectId!] = _subjectName.text;
|
||||||
await dbProvider.userStore.storeRenamedSubjects(renamedSubs, userId: user.id!);
|
await dbProvider.userStore
|
||||||
await Provider.of<GradeProvider>(context, listen: false).convertBySettings();
|
.storeRenamedSubjects(renamedSubs, userId: user.id!);
|
||||||
await Provider.of<TimetableProvider>(context, listen: false).convertBySettings();
|
await Provider.of<GradeProvider>(context, listen: false)
|
||||||
await Provider.of<AbsenceProvider>(context, listen: false).convertBySettings();
|
.convertBySettings();
|
||||||
|
await Provider.of<TimetableProvider>(context, listen: false)
|
||||||
|
.convertBySettings();
|
||||||
|
await Provider.of<AbsenceProvider>(context, listen: false)
|
||||||
|
.convertBySettings();
|
||||||
}
|
}
|
||||||
Navigator.of(context).pop(true);
|
Navigator.of(context).pop(true);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -265,9 +293,17 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Panel(
|
Panel(
|
||||||
child: PanelButton(title: Text("italics_toggle".i18n), trailing: Switch(value: settings.renamedSubjectsItalics, onChanged: (value) => settings.update(renamedSubjectsItalics: value),)
|
child: PanelButton(
|
||||||
),),
|
title: Text("italics_toggle".i18n),
|
||||||
SizedBox(height: 20,),
|
trailing: Switch(
|
||||||
|
value: settings.renamedSubjectsItalics,
|
||||||
|
onChanged: (value) =>
|
||||||
|
settings.update(renamedSubjectsItalics: value),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: showRenameDialog,
|
onTap: showRenameDialog,
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
@ -277,7 +313,8 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
border: Border.all(color: Colors.grey, width: 2),
|
border: Border.all(color: Colors.grey, width: 2),
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 18.0, horizontal: 12.0),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 18.0, horizontal: 12.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"rename_new_subject".i18n,
|
"rename_new_subject".i18n,
|
||||||
@ -296,14 +333,17 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
FutureBuilder<Map<String, String>>(
|
FutureBuilder<Map<String, String>>(
|
||||||
future: fetchRenamedSubjects(),
|
future: fetchRenamedSubjects(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (!snapshot.hasData || snapshot.data!.isEmpty) return Container();
|
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
|
||||||
return Panel(
|
return Panel(
|
||||||
title: Text("renamed_subjects".i18n),
|
title: Text("renamed_subjects".i18n),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: snapshot.data!.keys.map(
|
children: snapshot.data!.keys.map(
|
||||||
(key) {
|
(key) {
|
||||||
Subject? subject = subjects.firstWhere((element) => key == element.id);
|
Subject? subject = subjects
|
||||||
|
.firstWhere((element) => key == element.id);
|
||||||
String renameTo = snapshot.data![key]!;
|
String renameTo = snapshot.data![key]!;
|
||||||
return RenamedSubjectItem(
|
return RenamedSubjectItem(
|
||||||
subject: subject,
|
subject: subject,
|
||||||
@ -317,9 +357,12 @@ class _ModifySubjectNamesState extends State<ModifySubjectNames> {
|
|||||||
},
|
},
|
||||||
removeCallback: () {
|
removeCallback: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
Map<String, String> subs = Map.from(snapshot.data!);
|
Map<String, String> subs =
|
||||||
|
Map.from(snapshot.data!);
|
||||||
subs.remove(key);
|
subs.remove(key);
|
||||||
dbProvider.userStore.storeRenamedSubjects(subs, userId: user.id!);
|
dbProvider.userStore.storeRenamedSubjects(
|
||||||
|
subs,
|
||||||
|
userId: user.id!);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -355,11 +398,14 @@ class RenamedSubjectItem extends StatelessWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
minLeadingWidth: 32.0,
|
minLeadingWidth: 32.0,
|
||||||
dense: true,
|
dense: true,
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 6.0),
|
contentPadding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 6.0),
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
leading: Icon(SubjectIcon.resolveVariant(subject: subject, context: context), color: AppColors.of(context).text.withOpacity(.75)),
|
leading: Icon(
|
||||||
|
SubjectIcon.resolveVariant(subject: subject, context: context),
|
||||||
|
color: AppColors.of(context).text.withOpacity(.75)),
|
||||||
title: InkWell(
|
title: InkWell(
|
||||||
onTap: modifyCallback,
|
onTap: modifyCallback,
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -367,7 +413,10 @@ class RenamedSubjectItem extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
subject.name.capital(),
|
subject.name.capital(),
|
||||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 14, color: AppColors.of(context).text.withOpacity(.75)),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 14,
|
||||||
|
color: AppColors.of(context).text.withOpacity(.75)),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
@ -382,7 +431,8 @@ class RenamedSubjectItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
trailing: InkWell(
|
trailing: InkWell(
|
||||||
onTap: removeCallback,
|
onTap: removeCallback,
|
||||||
child: Icon(FeatherIcons.trash, color: AppColors.of(context).red.withOpacity(.75)),
|
child: Icon(FeatherIcons.trash,
|
||||||
|
color: AppColors.of(context).red.withOpacity(.75)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user