diff --git a/refilc/android/app/build.gradle b/refilc/android/app/build.gradle index 42f71d7..4437dee 100644 --- a/refilc/android/app/build.gradle +++ b/refilc/android/app/build.gradle @@ -58,7 +58,7 @@ android { defaultConfig { applicationId "hu.refilc.naplo" - minSdkVersion 21 + minSdkVersion 24 targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/refilc/lib/api/client.dart b/refilc/lib/api/client.dart index 83fe55a..0387e84 100644 --- a/refilc/lib/api/client.dart +++ b/refilc/lib/api/client.dart @@ -55,7 +55,7 @@ class FilcAPI { static const stripeSheet = "$payment/stripe-sheet"; static Future checkConnectivity() async => - (await Connectivity().checkConnectivity()) != ConnectivityResult.none; + (await Connectivity().checkConnectivity())[0] != ConnectivityResult.none; static Future?> getSchools() async { try { diff --git a/refilc/lib/api/providers/status_provider.dart b/refilc/lib/api/providers/status_provider.dart index 9004cb2..458c145 100644 --- a/refilc/lib/api/providers/status_provider.dart +++ b/refilc/lib/api/providers/status_provider.dart @@ -15,7 +15,7 @@ class StatusProvider extends ChangeNotifier { StatusProvider() { _handleNetworkChanges(); _handleDNSFailure(); - Connectivity().checkConnectivity().then((value) => _networkType = value); + Connectivity().checkConnectivity().then((value) => _networkType = value[0]); } Status? getStatus() => _stack.isNotEmpty ? _stack[0] : null; @@ -24,8 +24,8 @@ class StatusProvider extends ChangeNotifier { void _handleNetworkChanges() { Connectivity().onConnectivityChanged.listen((event) { - _networkType = event; - if (event == ConnectivityResult.none) { + _networkType = event[0]; + if (event[0] == ConnectivityResult.none) { if (!_stack.contains(Status.network)) { _stack.remove(Status.apiError); _stack.insert(0, Status.network); diff --git a/refilc/lib/database/init.dart b/refilc/lib/database/init.dart index a8c820d..84d4444 100644 --- a/refilc/lib/database/init.dart +++ b/refilc/lib/database/init.dart @@ -54,6 +54,7 @@ const settingsDB = DatabaseStruct("settings", { "new_colors": int, "uwu_mode": int, "new_popups": int, + "unseen_new_features": String, // quick settings "q_timetable_lesson_num": int, "q_timetable_sub_tiles": int, "q_subjects_sub_tiles": int, diff --git a/refilc/lib/database/struct.dart b/refilc/lib/database/struct.dart index bb33de6..d5947c6 100644 --- a/refilc/lib/database/struct.dart +++ b/refilc/lib/database/struct.dart @@ -8,10 +8,10 @@ class DatabaseStruct { String typeName = ""; switch (type.runtimeType) { - case int: + case const (int): typeName = "integer"; break; - case String: + case const (String): typeName = "text"; break; } diff --git a/refilc/lib/helpers/notification_helper.dart b/refilc/lib/helpers/notification_helper.dart index 9ee1a49..1959866 100644 --- a/refilc/lib/helpers/notification_helper.dart +++ b/refilc/lib/helpers/notification_helper.dart @@ -22,7 +22,7 @@ import 'package:intl/intl.dart'; import 'package:refilc_kreta_api/models/message.dart'; // if you want to add a new category, also add it to the DB or else the app will probably crash -enum LastSeenCategory { +enum LastSeenCategory { grade, surprisegrade, absence, @@ -655,7 +655,7 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k lesson.lessonIndex, lesson.name, dayTitle(lesson.date), - lesson.substituteTeacher!.isRenamed + (lesson.substituteTeacher?.isRenamed ?? false) ? lesson.substituteTeacher!.renamedTo! : lesson.substituteTeacher!.name ], diff --git a/refilc/lib/helpers/share_helper.dart b/refilc/lib/helpers/share_helper.dart index 3454465..81151e7 100644 --- a/refilc/lib/helpers/share_helper.dart +++ b/refilc/lib/helpers/share_helper.dart @@ -6,10 +6,9 @@ import 'package:share_plus/share_plus.dart'; class ShareHelper { static Future shareText(String text, {String? subject}) => Share.share(text, subject: subject); - // ignore: deprecated_member_use + static Future shareFile(String path, {String? text, String? subject}) => - // ignore: deprecated_member_use - Share.shareFiles([path], text: text, subject: subject); + Share.shareXFiles([XFile(path)], text: text, subject: subject); static Future shareAttachment(Attachment attachment, {required BuildContext context}) async { diff --git a/refilc/lib/main.dart b/refilc/lib/main.dart index 7b58d0f..5b0a3f4 100644 --- a/refilc/lib/main.dart +++ b/refilc/lib/main.dart @@ -15,6 +15,8 @@ import 'package:refilc/utils/service_locator.dart'; import 'package:refilc_mobile_ui/screens/error_screen.dart'; import 'package:refilc_mobile_ui/screens/error_report_screen.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:shake_flutter/models/shake_report_configuration.dart'; +import 'package:shake_flutter/shake_flutter.dart'; import 'helpers/live_activity_helper.dart'; @@ -38,6 +40,28 @@ void main() async { BackgroundFetch.registerHeadlessTask(backgroundHeadlessTask); + // setting up things for shakebugs + // List pickerItems = [ + // ShakePickerItem('Bug', 'Hiba', tag: 'bug'), + // ShakePickerItem('Suggestion', 'Fejlesztési javaslat', tag: 'suggestion'), + // ShakePickerItem('Question', 'Kérdés', tag: 'question') + // ]; + // ShakePicker picker = + // ShakePicker('Feedback type', 'Visszajelzés típusa', pickerItems); + // ShakeTitle title = ShakeTitle('Title', 'Leírás', required: true); + + // ShakeInspectButton inspect = ShakeInspectButton(); + // ShakeAttachments attachments = ShakeAttachments(); + + // List components = [picker, title, inspect, attachments]; + // ShakeForm form = ShakeForm(components); + + // Shake.setShakeForm(form); + + // shakebugs initialization + // Shake.setInvokeShakeOnScreenshot(true); + Shake.start('Y44AwzfY6091xO2Nr0w59RHSpNxJhhiSFGs4enmoJwelN82ZRzTLE5X'); + // pre-cache required icons const todaySvg = SvgAssetLoader('assets/svg/menu_icons/today_selected.svg'); const gradesSvg = SvgAssetLoader('assets/svg/menu_icons/grades_selected.svg'); @@ -170,6 +194,18 @@ Widget errorBuilder(FlutterErrorDetails details) { Navigator.of(context, rootNavigator: true) .push(MaterialPageRoute(builder: (context) { if (kReleaseMode) { + // silent report to shakebugs + ShakeReportConfiguration configuration = ShakeReportConfiguration(); + configuration.blackBoxData = true; + configuration.activityHistoryData = true; + configuration.screenshot = true; + configuration.video = false; + Shake.silentReport( + configuration: configuration, + description: + 'Silent Report #${DateTime.now().year}${DateTime.now().month}${DateTime.now().day}', + ); + // show error report screen return ErrorReportScreen(details); } else { return ErrorScreen(details); @@ -244,7 +280,8 @@ void backgroundHeadlessTask(HeadlessTask task) { LiveActivityHelper().backgroundJob(); } else { NotificationsHelper().backgroundJob(); - } BackgroundFetch.finish(task.taskId); + } + BackgroundFetch.finish(task.taskId); } Future initAdditionalBackgroundFetch() async { diff --git a/refilc/lib/models/self_note.dart b/refilc/lib/models/self_note.dart index cbaf42b..281a264 100644 --- a/refilc/lib/models/self_note.dart +++ b/refilc/lib/models/self_note.dart @@ -60,7 +60,7 @@ class TodoItem { ); } - get toJson => { + Map get toJson => { 'id': id, 'title': title, 'content': content, diff --git a/refilc/lib/models/settings.dart b/refilc/lib/models/settings.dart index 298e704..6bde6b2 100644 --- a/refilc/lib/models/settings.dart +++ b/refilc/lib/models/settings.dart @@ -107,6 +107,7 @@ class SettingsProvider extends ChangeNotifier { bool _newColors; bool _uwuMode; bool _newPopups; + List _unseenNewFeatures; // quick settings bool _qTimetableLessonNum; bool _qTimetableSubTiles; @@ -180,6 +181,7 @@ class SettingsProvider extends ChangeNotifier { required bool newColors, required bool uwuMode, required bool newPopups, + required List unseenNewFeatures, required bool qTimetableLessonNum, required bool qTimetableSubTiles, required bool qSubjectsSubTiles, @@ -250,6 +252,7 @@ class SettingsProvider extends ChangeNotifier { _newColors = newColors, _uwuMode = uwuMode, _newPopups = newPopups, + _unseenNewFeatures = unseenNewFeatures, _qTimetableLessonNum = qTimetableLessonNum, _qTimetableSubTiles = qTimetableSubTiles, _qSubjectsSubTiles = qSubjectsSubTiles; @@ -339,6 +342,7 @@ class SettingsProvider extends ChangeNotifier { newColors: map['new_colors'] == 1, uwuMode: map['uwu_mode'] == 1, newPopups: map['new_popups'] == 1, + unseenNewFeatures: jsonDecode(map["unseen_new_features"]).cast(), qTimetableLessonNum: map['q_timetable_lesson_num'] == 1, qTimetableSubTiles: map['q_timetable_sub_tiles'] == 1, qSubjectsSubTiles: map['q_subjects_sub_tiles'] == 1, @@ -416,6 +420,7 @@ class SettingsProvider extends ChangeNotifier { "new_colors": _newColors ? 1 : 0, "uwu_mode": _uwuMode ? 1 : 0, "new_popups": _newPopups ? 1 : 0, + "unseen_new_features": jsonEncode(_unseenNewFeatures), "q_timetable_lesson_num": _qTimetableLessonNum ? 1 : 0, "q_timetable_sub_tiles": _qTimetableSubTiles ? 1 : 0, "q_subjects_sub_tiles": _qSubjectsSubTiles ? 1 : 0, @@ -497,6 +502,7 @@ class SettingsProvider extends ChangeNotifier { newColors: true, uwuMode: false, newPopups: true, + unseenNewFeatures: ['grade_exporting'], qTimetableLessonNum: true, qTimetableSubTiles: true, qSubjectsSubTiles: true, @@ -569,6 +575,7 @@ class SettingsProvider extends ChangeNotifier { bool get newColors => _newColors; bool get uwuMode => _uwuMode; bool get newPopups => _newPopups; + List get unseenNewFeatures => _unseenNewFeatures; bool get qTimetableLessonNum => _qTimetableLessonNum; bool get qTimetableSubTiles => _qTimetableSubTiles; bool get qSubjectsSubTiles => _qSubjectsSubTiles; @@ -637,6 +644,7 @@ class SettingsProvider extends ChangeNotifier { bool? newColors, bool? uwuMode, bool? newPopups, + List? unseenNewFeatures, bool? qTimetableLessonNum, bool? qTimetableSubTiles, bool? qSubjectsSubTiles, @@ -828,6 +836,9 @@ class SettingsProvider extends ChangeNotifier { if (newPopups != null && newPopups != _newPopups) { _newPopups = newPopups; } + if (unseenNewFeatures != null && unseenNewFeatures != _unseenNewFeatures) { + _unseenNewFeatures = unseenNewFeatures; + } if (qTimetableLessonNum != null && qTimetableLessonNum != _qTimetableLessonNum) { _qTimetableLessonNum = qTimetableLessonNum; diff --git a/refilc/lib/theme/observer.dart b/refilc/lib/theme/observer.dart index c8824a6..08c075e 100644 --- a/refilc/lib/theme/observer.dart +++ b/refilc/lib/theme/observer.dart @@ -4,6 +4,8 @@ import 'package:flutter/material.dart'; import 'package:home_widget/home_widget.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:shake_flutter/models/shake_theme.dart'; +import 'package:shake_flutter/shake_flutter.dart'; Future updateWidget() async { try { @@ -22,7 +24,9 @@ class ThemeModeObserver extends ChangeNotifier { ThemeMode get themeMode => _themeMode; bool get updateNavbarColor => _updateNavbarColor; - ThemeModeObserver({ThemeMode initialTheme = ThemeMode.system, bool updateNavbarColor = true}) + ThemeModeObserver( + {ThemeMode initialTheme = ThemeMode.system, + bool updateNavbarColor = true}) : _themeMode = initialTheme, _updateNavbarColor = updateNavbarColor; @@ -31,5 +35,12 @@ class ThemeModeObserver extends ChangeNotifier { _updateNavbarColor = updateNavbarColor; if (Platform.isAndroid) updateWidget(); notifyListeners(); + + // change shake theme as well + ShakeTheme darkTheme = ShakeTheme(); + darkTheme.accentColor = "#FFFFFF"; + ShakeTheme lightTheme = ShakeTheme(); + lightTheme.accentColor = "#000000"; + Shake.setShakeTheme(mode == ThemeMode.dark ? darkTheme : lightTheme); } } diff --git a/refilc/lib/theme/theme.dart b/refilc/lib/theme/theme.dart index 1ddd93e..405ac95 100644 --- a/refilc/lib/theme/theme.dart +++ b/refilc/lib/theme/theme.dart @@ -125,8 +125,6 @@ class AppTheme { onTertiary: (newTertiary.computeLuminance() > 0.5 ? Colors.black : Colors.white) .withOpacity(.9), - background: highlightColor, - onBackground: Colors.black.withOpacity(.9), brightness: Brightness.light, error: lightColors.red, onError: Colors.white.withOpacity(.9), @@ -141,9 +139,9 @@ class AppTheme { indicatorColor: accent.withOpacity(accentColor == AccentColor.adaptive ? 0.4 : 0.8), iconTheme: - MaterialStateProperty.all(IconThemeData(color: lightColors.text)), + WidgetStateProperty.all(IconThemeData(color: lightColors.text)), backgroundColor: highlightColor, - labelTextStyle: MaterialStateProperty.all(TextStyle( + labelTextStyle: WidgetStateProperty.all(TextStyle( fontSize: 13.0, fontWeight: FontWeight.w500, color: lightColors.text.withOpacity(0.8), @@ -250,8 +248,6 @@ class AppTheme { onTertiary: (newTertiary.computeLuminance() > 0.5 ? Colors.black : Colors.white) .withOpacity(.9), - background: highlightColor, - onBackground: Colors.white.withOpacity(.9), brightness: Brightness.dark, error: darkColors.red, onError: Colors.black.withOpacity(.9), @@ -266,9 +262,9 @@ class AppTheme { indicatorColor: accent.withOpacity(accentColor == AccentColor.adaptive ? 0.4 : 0.8), iconTheme: - MaterialStateProperty.all(IconThemeData(color: darkColors.text)), + WidgetStateProperty.all(IconThemeData(color: darkColors.text)), backgroundColor: highlightColor, - labelTextStyle: MaterialStateProperty.all(TextStyle( + labelTextStyle: WidgetStateProperty.all(TextStyle( fontSize: 13.0, fontWeight: FontWeight.w500, color: darkColors.text.withOpacity(0.8), diff --git a/refilc/lib/ui/filter/widgets.dart b/refilc/lib/ui/filter/widgets.dart index b3683db..5142a88 100644 --- a/refilc/lib/ui/filter/widgets.dart +++ b/refilc/lib/ui/filter/widgets.dart @@ -259,7 +259,7 @@ Widget filterItemBuilder( ? const EdgeInsets.symmetric(vertical: 8.0) : const EdgeInsets.symmetric(vertical: 4.0), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.vertical( top: separated || isAfterSeparated ? const Radius.circular(16.0) diff --git a/refilc/lib/ui/flutter_colorpicker/palette.dart b/refilc/lib/ui/flutter_colorpicker/palette.dart index 3571a86..b569b2b 100644 --- a/refilc/lib/ui/flutter_colorpicker/palette.dart +++ b/refilc/lib/ui/flutter_colorpicker/palette.dart @@ -364,7 +364,7 @@ class ColorPickerInputState extends State { controller: textEditingController, style: TextStyle( fontSize: 18, - color: Theme.of(context).colorScheme.onBackground, + color: Theme.of(context).colorScheme.onSurface, ), inputFormatters: [ UpperCaseTextFormatter(), diff --git a/refilc/pubspec.yaml b/refilc/pubspec.yaml index 064f4bc..895c0a9 100644 --- a/refilc/pubspec.yaml +++ b/refilc/pubspec.yaml @@ -3,10 +3,10 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak." homepage: https://refilc.hu publish_to: "none" -version: 5.0.2+266 +version: 5.0.3+269 environment: - sdk: ">=2.17.0 <=3.3.2" + sdk: ">=3.3.2 <=3.4.3" dependencies: flutter: @@ -25,9 +25,9 @@ dependencies: flutter_localizations: sdk: flutter - i18n_extension: ^11.0.11 + i18n_extension: ^12.0.1 sqflite: ^2.2.0+2 - intl: ^0.18.1 + intl: ^0.19.0 provider: ^6.1.1 http: ^1.1.2 uuid: ^4.2.1 @@ -39,40 +39,46 @@ dependencies: # ref: master path_provider: ^2.0.2 permission_handler: ^11.0.1 - share_plus: ^7.0.2 - connectivity_plus: ^5.0.2 + share_plus: ^9.0.0 + connectivity_plus: ^6.0.3 flutter_displaymode: ^0.6.0 quick_actions: ^1.0.1 animated_list_plus: ^0.5.0 dynamic_color: ^1.2.2 material_color_utilities: ^0.8.0 crypto: ^3.0.2 - elegant_notification: ^1.6.1 + elegant_notification: ^2.2.0 flutter_feather_icons: ^2.0.0+1 live_activities: ^1.7.4 - animated_flip_counter: ^0.2.5 + animated_flip_counter: ^0.3.4 lottie: ^3.1.0 rive: ^0.12.4 animated_background: ^2.0.0 dropdown_button2: ^2.3.9 - home_widget: ^0.4.1 + home_widget: + git: + url: https://github.com/refilc/home_widget.git + ref: flutter-beta flutter_expandable_fab: ^2.0.0 uni_links: ^0.5.1 url_launcher: ^6.1.6 - workmanager: ^0.5.1 + workmanager: + git: + url: https://github.com/refilc/flutter_workmanager.git + ref: v0.5.1 flutter_svg: ^2.0.10+1 image_picker: ^1.0.7 animations: ^2.0.1 background_fetch: ^1.1.5 - flutter_local_notifications: ^16.2.0 - package_info_plus: ^5.0.1 - screenshot: ^2.1.0 + flutter_local_notifications: ^17.1.2 + package_info_plus: ^8.0.0 + screenshot: ^3.0.0 flutter_staggered_grid_view: ^0.7.0 sqflite_common_ffi_web: ^0.4.0 image_crop: git: url: https://github.com/kimaah/image_crop.git - googleapis: ^12.0.0 + googleapis: ^13.2.0 google_sign_in: ^6.2.1 extension_google_sign_in_as_googleapis_auth: ^2.0.12 maps_launcher: ^2.2.0 @@ -82,9 +88,10 @@ dependencies: xml: ^6.5.0 carousel_slider: ^4.2.1 flutter_portal: ^1.1.4 + shake_flutter: ^17.0.0 dev_dependencies: - flutter_lints: ^3.0.1 + flutter_lints: ^4.0.0 flutter_launcher_icons: "^0.13.1" flutter_native_splash: "^2.3.10" sqflite_common_ffi: ^2.0.0+3 diff --git a/refilc_desktop_ui/lib/common/filter_bar.dart b/refilc_desktop_ui/lib/common/filter_bar.dart index 7e0b51b..790f9e9 100644 --- a/refilc_desktop_ui/lib/common/filter_bar.dart +++ b/refilc_desktop_ui/lib/common/filter_bar.dart @@ -41,7 +41,7 @@ class FilterBar extends StatelessWidget implements PreferredSizeWidget { color: Theme.of(context).colorScheme.secondary.withOpacity(0.25), borderRadius: BorderRadius.circular(45.0), ), - overlayColor: MaterialStateProperty.all(const Color(0x00000000)), + overlayColor: WidgetStateProperty.all(const Color(0x00000000)), // Tabs padding: EdgeInsets.zero, tabs: items, diff --git a/refilc_desktop_ui/lib/pages/absences/absences_page.dart b/refilc_desktop_ui/lib/pages/absences/absences_page.dart index aff6b4a..33e0906 100644 --- a/refilc_desktop_ui/lib/pages/absences/absences_page.dart +++ b/refilc_desktop_ui/lib/pages/absences/absences_page.dart @@ -287,7 +287,7 @@ class AbsencesPageState extends State return FadeThroughTransition( animation: primaryAnimation, secondaryAnimation: secondaryAnimation, - fillColor: Theme.of(context).colorScheme.background, + fillColor: Theme.of(context).colorScheme.surface, child: child, ); }, diff --git a/refilc_desktop_ui/lib/screens/login/login_screen.dart b/refilc_desktop_ui/lib/screens/login/login_screen.dart index 3541be3..892db46 100644 --- a/refilc_desktop_ui/lib/screens/login/login_screen.dart +++ b/refilc_desktop_ui/lib/screens/login/login_screen.dart @@ -68,7 +68,7 @@ class LoginScreenState extends State { overflow: TextOverflow.ellipsis, style: const TextStyle(color: Colors.red), ), - onActionPressed: () {}, + // onActionPressed: () {}, onCloseButtonPressed: () {}, onDismiss: () {}, onProgressFinished: () {}, @@ -340,7 +340,7 @@ class LoginScreenState extends State { overflow: TextOverflow.ellipsis, style: const TextStyle(color: Colors.black), ), - onActionPressed: () {}, + // onActionPressed: () {}, onCloseButtonPressed: () {}, onDismiss: () {}, onProgressFinished: () {}, diff --git a/refilc_desktop_ui/lib/screens/settings/settings_screen.dart b/refilc_desktop_ui/lib/screens/settings/settings_screen.dart index 16334b1..e8ca7a8 100644 --- a/refilc_desktop_ui/lib/screens/settings/settings_screen.dart +++ b/refilc_desktop_ui/lib/screens/settings/settings_screen.dart @@ -776,7 +776,7 @@ class SettingsScreenState extends State decoration: BoxDecoration( color: Theme.of(context) .colorScheme - .background), + .surface), child: Material( type: MaterialType.transparency, child: SwitchListTile( diff --git a/refilc_desktop_ui/pubspec.yaml b/refilc_desktop_ui/pubspec.yaml index cb8f8e1..06d3bc0 100644 --- a/refilc_desktop_ui/pubspec.yaml +++ b/refilc_desktop_ui/pubspec.yaml @@ -2,7 +2,7 @@ name: refilc_desktop_ui publish_to: "none" environment: - sdk: ">=2.17.0 <=3.3.2" + sdk: ">=3.3.2 <=3.4.3" dependencies: flutter: @@ -26,22 +26,22 @@ dependencies: provider: ^6.1.1 url_launcher: ^6.2.5 flutter_linkify: ^6.0.0 - flutter_markdown: ^0.6.20+1 + flutter_markdown: ^0.7.2+1 animations: ^2.0.11 confetti: ^0.7.0 auto_size_text: ^3.0.0 flutter_acrylic: ^1.1.3 - elegant_notification: ^1.13.0 + elegant_notification: ^2.2.0 flutter_staggered_grid_view: ^0.7.0 - i18n_extension: ^11.0.12 + i18n_extension: ^12.0.1 flutter_expandable_fab: ^2.0.0 collection: ^1.18.0 animated_list_plus: ^0.5.2 - intl: ^0.18.1 + intl: ^0.19.0 flutter_custom_tabs: ^2.0.0+1 dev_dependencies: - flutter_lints: ^3.0.1 + flutter_lints: ^4.0.0 flutter: uses-material-design: true diff --git a/refilc_kreta_api/lib/providers/grade_provider.dart b/refilc_kreta_api/lib/providers/grade_provider.dart index f17203c..210be49 100644 --- a/refilc_kreta_api/lib/providers/grade_provider.dart +++ b/refilc_kreta_api/lib/providers/grade_provider.dart @@ -111,13 +111,16 @@ class GradeProvider with ChangeNotifier { grade.teacher.renamedTo = renamedTeachers.isNotEmpty ? renamedTeachers[grade.teacher.id] : null; - grade.value.value = - _settings.goodStudent ? 5 : grade.json!["SzamErtek"] ?? 0; + grade.value.value = _settings.goodStudent + ? (grade.value.percentage ? 100 : 5) + : grade.json!["SzamErtek"] ?? 0; grade.value.valueName = _settings.goodStudent ? "Jeles".i18n - : '${grade.json!["SzovegesErtek"]}' - .replaceAll(RegExp(r'[(]+[12345]?[)]'), '') - .i18n; + : (grade.value.percentage + ? '${grade.json!["SzovegesErtek"]}' + : '${grade.json!["SzovegesErtek"]}' + .replaceAll(RegExp(r'[(]+[12345]?[)]'), '') + .i18n); grade.value.shortName = _settings.goodStudent ? "Jeles".i18n : '${grade.json!["SzovegesErtekelesRovidNev"]}' != "null" && diff --git a/refilc_kreta_api/lib/providers/grade_provider.i18n.dart b/refilc_kreta_api/lib/providers/grade_provider.i18n.dart index 1a3cfe2..aaddbcb 100644 --- a/refilc_kreta_api/lib/providers/grade_provider.i18n.dart +++ b/refilc_kreta_api/lib/providers/grade_provider.i18n.dart @@ -8,21 +8,27 @@ extension Localization on String { "Elégséges": "Warning but passing", "Közepes": "Passed", "Jó": "Good", - "Jeles": "Excellent" + "Jeles": "Excellent", + "Példás": "Excellent", + "Nem írt": "Did not write", }, "hu_hu": { "Elégtelen": "Elégtelen", "Elégséges": "Elégséges", "Közepes": "Közepes", "Jó": "Jó", - "Jeles": "Jeles" + "Jeles": "Jeles", + "Példás": "Példás", + "Nem írt": "Nem írt", }, "de_de": { "Elégtelen": "Ungenügend", "Elégséges": "Mangelhaft", "Közepes": "Ausreichend", "Jó": "Befriedigend", - "Jeles": "Gut" + "Jeles": "Gut", + "Példás": "Gut", + "Nem írt": "Nicht geschrieben", }, }; diff --git a/refilc_kreta_api/pubspec.yaml b/refilc_kreta_api/pubspec.yaml index f4c9ba8..fd935aa 100644 --- a/refilc_kreta_api/pubspec.yaml +++ b/refilc_kreta_api/pubspec.yaml @@ -2,7 +2,7 @@ name: refilc_kreta_api publish_to: "none" environment: - sdk: ">=2.17.0 <=3.3.2" + sdk: ">=3.3.2 <=3.4.3" dependencies: flutter: @@ -11,10 +11,10 @@ dependencies: path: ../refilc/ http: ^1.1.2 provider: ^6.1.1 - file_picker: ^6.1.1 - intl: ^0.18.1 - i18n_extension: ^11.0.11 + file_picker: ^8.0.5 + intl: ^0.19.0 + i18n_extension: ^12.0.1 uuid: ^4.3.3 dev_dependencies: - flutter_lints: ^3.0.1 + flutter_lints: ^4.0.0 diff --git a/refilc_mobile_ui/lib/common/bottom_card.dart b/refilc_mobile_ui/lib/common/bottom_card.dart index b0d23a3..689b209 100644 --- a/refilc_mobile_ui/lib/common/bottom_card.dart +++ b/refilc_mobile_ui/lib/common/bottom_card.dart @@ -14,7 +14,7 @@ class BottomCard extends StatelessWidget { child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(14.0), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), child: Column( mainAxisSize: MainAxisSize.min, diff --git a/refilc_mobile_ui/lib/common/bottom_sheet_menu/rounded_bottom_sheet.dart b/refilc_mobile_ui/lib/common/bottom_sheet_menu/rounded_bottom_sheet.dart index 9a64aa2..8c60603 100644 --- a/refilc_mobile_ui/lib/common/bottom_sheet_menu/rounded_bottom_sheet.dart +++ b/refilc_mobile_ui/lib/common/bottom_sheet_menu/rounded_bottom_sheet.dart @@ -22,7 +22,7 @@ class RoundedBottomSheet extends StatelessWidget { return AnimatedContainer( duration: const Duration(milliseconds: 500), decoration: BoxDecoration( - color: backgroundColor ?? Theme.of(context).colorScheme.background, + color: backgroundColor ?? Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.only( topLeft: Radius.circular(borderRadius), topRight: Radius.circular(borderRadius), diff --git a/refilc_mobile_ui/lib/common/beta_chip.dart b/refilc_mobile_ui/lib/common/chips/beta_chip.dart similarity index 95% rename from refilc_mobile_ui/lib/common/beta_chip.dart rename to refilc_mobile_ui/lib/common/chips/beta_chip.dart index 0b42185..2967a47 100644 --- a/refilc_mobile_ui/lib/common/beta_chip.dart +++ b/refilc_mobile_ui/lib/common/chips/beta_chip.dart @@ -1,5 +1,6 @@ import 'package:refilc/theme/colors/colors.dart'; import 'package:flutter/material.dart'; +import 'chips.i18n.dart'; class BetaChip extends StatelessWidget { const BetaChip({super.key, this.disabled = false}); @@ -22,7 +23,7 @@ class BetaChip extends StatelessWidget { padding: const EdgeInsets.only(left: 8, right: 8), child: Center( child: Text( - "BETA", + "beta".i18n, softWrap: true, style: TextStyle( fontSize: 10, diff --git a/refilc_mobile_ui/lib/common/chips/chips.i18n.dart b/refilc_mobile_ui/lib/common/chips/chips.i18n.dart new file mode 100644 index 0000000..965c39e --- /dev/null +++ b/refilc_mobile_ui/lib/common/chips/chips.i18n.dart @@ -0,0 +1,24 @@ +import 'package:i18n_extension/i18n_extension.dart'; + +extension ScreensLocalization on String { + static final _t = Translations.byLocale("hu_hu") + + { + "en_en": { + "new": "NEW", + "beta": "BETA", + }, + "hu_hu": { + "new": "ÚJ", + "beta": "BÉTA", + }, + "de_de": { + "new": "NEU", + "beta": "BETA", + }, + }; + + String get i18n => localize(this, _t); + String fill(List params) => localizeFill(this, params); + String plural(int value) => localizePlural(value, this, _t); + String version(Object modifier) => localizeVersion(modifier, this, _t); +} diff --git a/refilc_mobile_ui/lib/common/chips/new_chip.dart b/refilc_mobile_ui/lib/common/chips/new_chip.dart new file mode 100644 index 0000000..a482962 --- /dev/null +++ b/refilc_mobile_ui/lib/common/chips/new_chip.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:refilc/theme/colors/colors.dart'; +import 'chips.i18n.dart'; + +class NewChip extends StatelessWidget { + const NewChip({super.key, this.disabled = false}); + + final bool disabled; + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: + disabled ? AppColors.of(context).text.withOpacity(.25) : Colors.red, + borderRadius: BorderRadius.circular(12.0), + ), + padding: + const EdgeInsets.only(left: 6.0, right: 8.0, top: 4.0, bottom: 4.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.hotel_class_rounded, + color: disabled + ? AppColors.of(context).text.withOpacity(.5) + : Colors.white, + size: 14.0, + ), + const SizedBox(width: 2.0), + Text( + 'new'.i18n, + style: TextStyle( + color: disabled + ? AppColors.of(context).text.withOpacity(.5) + : Colors.white, + fontSize: 12.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ); + } +} diff --git a/refilc_mobile_ui/lib/common/filter_bar.dart b/refilc_mobile_ui/lib/common/filter_bar.dart index 019b4c5..e4e1f04 100644 --- a/refilc_mobile_ui/lib/common/filter_bar.dart +++ b/refilc_mobile_ui/lib/common/filter_bar.dart @@ -49,7 +49,7 @@ class _FilterBarState extends State { controller: widget.controller, isScrollable: widget.scrollable, physics: const BouncingScrollPhysics(), - // Label + // label labelStyle: Theme.of(context).textTheme.titleMedium!.copyWith( fontWeight: FontWeight.w600, fontSize: 15.0, @@ -57,15 +57,17 @@ class _FilterBarState extends State { labelPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3), labelColor: Theme.of(context).colorScheme.secondary, unselectedLabelColor: AppColors.of(context).text.withOpacity(0.65), - // Indicator + // indicator indicatorSize: TabBarIndicatorSize.tab, indicatorPadding: const EdgeInsets.symmetric(vertical: 8.0), indicator: BoxDecoration( color: Theme.of(context).colorScheme.tertiary.withOpacity(.2), borderRadius: BorderRadius.circular(45.0), ), - overlayColor: MaterialStateProperty.all(const Color(0x00000000)), - // Tabs + overlayColor: WidgetStateProperty.all(const Color(0x00000000)), + // underline (bottom border) + dividerColor: Colors.transparent, + // tabs padding: EdgeInsets.zero, tabs: widget.censored ? censoredItemsWidth diff --git a/refilc_mobile_ui/lib/common/outlined_round_button.dart b/refilc_mobile_ui/lib/common/outlined_round_button.dart index 8eedb66..ae3fd5c 100644 --- a/refilc_mobile_ui/lib/common/outlined_round_button.dart +++ b/refilc_mobile_ui/lib/common/outlined_round_button.dart @@ -22,7 +22,7 @@ class OutlinedRoundButton extends StatelessWidget { width: size, height: size, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, border: Border.all( color: Theme.of(context).colorScheme.secondary.withOpacity(0.1), width: 1.1, diff --git a/refilc_mobile_ui/lib/common/panel/panel.dart b/refilc_mobile_ui/lib/common/panel/panel.dart index 7a144a1..3c61396 100644 --- a/refilc_mobile_ui/lib/common/panel/panel.dart +++ b/refilc_mobile_ui/lib/common/panel/panel.dart @@ -35,7 +35,7 @@ class Panel extends StatelessWidget { borderRadius: BorderRadius.circular(16.0), color: isTransparent ? Colors.transparent - : Theme.of(context).colorScheme.background, + : Theme.of(context).colorScheme.surface, boxShadow: [ if ((hasShadow && !isTransparent) && Provider.of(context, listen: false) @@ -87,7 +87,7 @@ class PanelHeader extends StatelessWidget { decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0)), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, boxShadow: [ if (Provider.of(context, listen: false) .shadowEffect) @@ -113,7 +113,7 @@ class PanelBody extends StatelessWidget { return Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, boxShadow: [ if (Provider.of(context, listen: false) .shadowEffect) @@ -144,7 +144,7 @@ class PanelFooter extends StatelessWidget { borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, boxShadow: [ if (Provider.of(context, listen: false) .shadowEffect) diff --git a/refilc_mobile_ui/lib/common/sliding_bottom_sheet.dart b/refilc_mobile_ui/lib/common/sliding_bottom_sheet.dart index daf2302..b156857 100644 --- a/refilc_mobile_ui/lib/common/sliding_bottom_sheet.dart +++ b/refilc_mobile_ui/lib/common/sliding_bottom_sheet.dart @@ -9,7 +9,7 @@ void showSlidingBottomSheet( cornerRadius: 16, cornerRadiusOnFullscreen: 0, avoidStatusBar: true, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, duration: const Duration(milliseconds: 400), snapSpec: const ss.SnapSpec( snap: true, @@ -18,7 +18,7 @@ void showSlidingBottomSheet( ), headerBuilder: (context, state) { return Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -37,7 +37,7 @@ void showSlidingBottomSheet( }, builder: (context, state) { return Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: Padding( padding: const EdgeInsets.fromLTRB(12.0, 0, 12.0, 8.0), child: child), diff --git a/refilc_mobile_ui/lib/common/splitted_panel/splitted_panel.dart b/refilc_mobile_ui/lib/common/splitted_panel/splitted_panel.dart index 4517b48..402e16f 100644 --- a/refilc_mobile_ui/lib/common/splitted_panel/splitted_panel.dart +++ b/refilc_mobile_ui/lib/common/splitted_panel/splitted_panel.dart @@ -46,7 +46,7 @@ class SplittedPanel extends StatelessWidget { decoration: BoxDecoration( color: isTransparent ? Colors.transparent - : Theme.of(context).colorScheme.background, + : Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.vertical( top: Radius.circular(i == 0 ? 16.0 : 8.0), bottom: Radius.circular(children!.length == i + 1 ? 16.0 : 8.0), diff --git a/refilc_mobile_ui/lib/common/viewable.dart b/refilc_mobile_ui/lib/common/viewable.dart index 205a8e4..8cad17b 100644 --- a/refilc_mobile_ui/lib/common/viewable.dart +++ b/refilc_mobile_ui/lib/common/viewable.dart @@ -10,7 +10,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; -double valueFromPercentageInRange({required final double min, max, percentage}) { +double valueFromPercentageInRange( + {required final double min, max, percentage}) { return percentage * (max - min) + min; } @@ -44,7 +45,8 @@ typedef _ViewablePreviewBuilderChildless = Widget Function( Rect _getRect(GlobalKey globalKey) { assert(globalKey.currentContext != null); - final RenderBox renderBoxContainer = globalKey.currentContext!.findRenderObject()! as RenderBox; + final RenderBox renderBoxContainer = + globalKey.currentContext!.findRenderObject()! as RenderBox; final Offset containerOffset = renderBoxContainer.localToGlobal( renderBoxContainer.paintBounds.topLeft, ); @@ -101,7 +103,8 @@ class _ViewableState extends State with TickerProviderStateMixin { final double screenWidth = MediaQuery.of(context).size.width; final double center = screenWidth / 2; - final bool centerDividesChild = childRect.left < center && childRect.right > center; + final bool centerDividesChild = + childRect.left < center && childRect.right > center; final double distanceFromCenter = (center - childRect.center.dx).abs(); if (centerDividesChild && distanceFromCenter <= childRect.width / 4) { return _ViewableLocation.center; @@ -132,7 +135,7 @@ class _ViewableState extends State with TickerProviderStateMixin { return ClipRRect( borderRadius: BorderRadius.circular(16.0), child: Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(16.0), child: Stack( children: [ @@ -270,7 +273,8 @@ class _DecoyChild extends StatefulWidget { _DecoyChildState createState() => _DecoyChildState(); } -class _DecoyChildState extends State<_DecoyChild> with TickerProviderStateMixin { +class _DecoyChildState extends State<_DecoyChild> + with TickerProviderStateMixin { static const Color _lightModeMaskColor = Color(0xFF888888); static const Color _masklessColor = Color(0xFFFFFFFF); @@ -327,7 +331,9 @@ class _DecoyChildState extends State<_DecoyChild> with TickerProviderStateMixin } Widget _buildAnimation(BuildContext context, Widget? child) { - final Color color = widget.controller.status == AnimationStatus.reverse ? _masklessColor : _mask.value; + final Color color = widget.controller.status == AnimationStatus.reverse + ? _masklessColor + : _mask.value; return Positioned.fromRect( rect: _rect.value!, child: ShaderMask( @@ -373,7 +379,8 @@ class _ViewableRoute extends PopupRoute { static const Color _kModalBarrierColor = Color(0x6604040F); - static const Duration _kModalPopupTransitionDuration = Duration(milliseconds: 335); + static const Duration _kModalPopupTransitionDuration = + Duration(milliseconds: 335); final List _actions; final _ViewablePreviewBuilderChildless? _builder; @@ -396,7 +403,8 @@ class _ViewableRoute extends PopupRoute { static final RectTween _rectTween = RectTween(); static final Animatable _rectAnimatable = _rectTween.chain(_curve); static final RectTween _rectTweenReverse = RectTween(); - static final Animatable _rectAnimatableReverse = _rectTweenReverse.chain( + static final Animatable _rectAnimatableReverse = + _rectTweenReverse.chain( _curveReverse, ); static final RectTween _sheetRectTween = RectTween(); @@ -407,10 +415,12 @@ class _ViewableRoute extends PopupRoute { _curveReverse, ); static final Tween _sheetScaleTween = Tween(); - static final Animatable _sheetScaleAnimatable = _sheetScaleTween.chain( + static final Animatable _sheetScaleAnimatable = + _sheetScaleTween.chain( _curve, ); - static final Animatable _sheetScaleAnimatableReverse = _sheetScaleTween.chain( + static final Animatable _sheetScaleAnimatableReverse = + _sheetScaleTween.chain( _curveReverse, ); final Tween _opacityTween = Tween(begin: 0.0, end: 1.0); @@ -441,7 +451,8 @@ class _ViewableRoute extends PopupRoute { return offsetScaled & sizeScaled; } - static AlignmentDirectional getSheetAlignment(_ViewableLocation contextMenuLocation) { + static AlignmentDirectional getSheetAlignment( + _ViewableLocation contextMenuLocation) { switch (contextMenuLocation) { case _ViewableLocation.center: return AlignmentDirectional.topCenter; @@ -452,17 +463,24 @@ class _ViewableRoute extends PopupRoute { } } - static Rect _getSheetRectBegin(Orientation? orientation, _ViewableLocation contextMenuLocation, Rect childRect, Rect sheetRect) { + static Rect _getSheetRectBegin(Orientation? orientation, + _ViewableLocation contextMenuLocation, Rect childRect, Rect sheetRect) { switch (contextMenuLocation) { case _ViewableLocation.center: - final Offset target = orientation == Orientation.portrait ? childRect.bottomCenter : childRect.topCenter; + final Offset target = orientation == Orientation.portrait + ? childRect.bottomCenter + : childRect.topCenter; final Offset centered = target - Offset(sheetRect.width / 2, 0.0); return centered & sheetRect.size; case _ViewableLocation.right: - final Offset target = orientation == Orientation.portrait ? childRect.bottomRight : childRect.topRight; + final Offset target = orientation == Orientation.portrait + ? childRect.bottomRight + : childRect.topRight; return (target - Offset(sheetRect.width, 0.0)) & sheetRect.size; case _ViewableLocation.left: - final Offset target = orientation == Orientation.portrait ? childRect.bottomLeft : childRect.topLeft; + final Offset target = orientation == Orientation.portrait + ? childRect.bottomLeft + : childRect.topLeft; return target & sheetRect.size; } } @@ -478,7 +496,9 @@ class _ViewableRoute extends PopupRoute { } void _updateTweenRects() { - final Rect childRect = _scale == null ? _getRect(_childGlobalKey) : _getScaledRect(_childGlobalKey, _scale!); + final Rect childRect = _scale == null + ? _getRect(_childGlobalKey) + : _getScaledRect(_childGlobalKey, _scale!); _rectTween.begin = _previousChildRect; _rectTween.end = childRect; @@ -546,21 +566,29 @@ class _ViewableRoute extends PopupRoute { } @override - Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { return Container(); } @override - Widget buildTransitions(BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { + Widget buildTransitions(BuildContext context, Animation animation, + Animation secondaryAnimation, Widget child) { return OrientationBuilder( builder: (BuildContext context, Orientation orientation) { _lastOrientation = orientation; if (!animation.isCompleted) { final bool reverse = animation.status == AnimationStatus.reverse; - final Rect rect = reverse ? _rectAnimatableReverse.evaluate(animation)! : _rectAnimatable.evaluate(animation)!; - final Rect sheetRect = reverse ? _sheetRectAnimatableReverse.evaluate(animation)! : _sheetRectAnimatable.evaluate(animation)!; - final double sheetScale = reverse ? _sheetScaleAnimatableReverse.evaluate(animation) : _sheetScaleAnimatable.evaluate(animation); + final Rect rect = reverse + ? _rectAnimatableReverse.evaluate(animation)! + : _rectAnimatable.evaluate(animation)!; + final Rect sheetRect = reverse + ? _sheetRectAnimatableReverse.evaluate(animation)! + : _sheetRectAnimatable.evaluate(animation)!; + final double sheetScale = reverse + ? _sheetScaleAnimatableReverse.evaluate(animation) + : _sheetScaleAnimatable.evaluate(animation); return Stack( children: [ Positioned.fromRect( @@ -623,7 +651,8 @@ class _ContextMenuRouteStatic extends StatefulWidget { _ContextMenuRouteStaticState createState() => _ContextMenuRouteStaticState(); } -class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with TickerProviderStateMixin { +class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> + with TickerProviderStateMixin { static const double _kMinScale = 0.8; static const double _kSheetScaleThreshold = 0.9; @@ -639,7 +668,8 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T late Animation _sheetScaleAnimation; late Animation _sheetOpacityAnimation; - static double _getScale(Orientation orientation, double maxDragDistance, double dy) { + static double _getScale( + Orientation orientation, double maxDragDistance, double dy) { final double dyDirectional = dy <= 0.0 ? dy : -dy; return math.max( _kMinScale, @@ -659,11 +689,13 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T void _onPanEnd(DragEndDetails details) { if (details.velocity.pixelsPerSecond.dy.abs() >= kMinFlingVelocity) { final bool flingIsAway = details.velocity.pixelsPerSecond.dy > 0; - final double finalPosition = flingIsAway ? _moveAnimation.value.dy + 100.0 : 0.0; + final double finalPosition = + flingIsAway ? _moveAnimation.value.dy + 100.0 : 0.0; if (flingIsAway && _sheetController.status != AnimationStatus.forward) { _sheetController.forward(); - } else if (!flingIsAway && _sheetController.status != AnimationStatus.reverse) { + } else if (!flingIsAway && + _sheetController.status != AnimationStatus.reverse) { _sheetController.reverse(); } @@ -713,20 +745,29 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T widget.onDismiss!(context, _lastScale, _sheetOpacityAnimation.value); } - Alignment _getChildAlignment(Orientation orientation, _ViewableLocation contextMenuLocation) { + Alignment _getChildAlignment( + Orientation orientation, _ViewableLocation contextMenuLocation) { switch (contextMenuLocation) { case _ViewableLocation.center: - return orientation == Orientation.portrait ? Alignment.bottomCenter : Alignment.topRight; + return orientation == Orientation.portrait + ? Alignment.bottomCenter + : Alignment.topRight; case _ViewableLocation.right: - return orientation == Orientation.portrait ? Alignment.bottomCenter : Alignment.topLeft; + return orientation == Orientation.portrait + ? Alignment.bottomCenter + : Alignment.topLeft; case _ViewableLocation.left: - return orientation == Orientation.portrait ? Alignment.bottomCenter : Alignment.topRight; + return orientation == Orientation.portrait + ? Alignment.bottomCenter + : Alignment.topRight; } } void _setDragOffset(Offset dragOffset) { final double endX = _kPadding * dragOffset.dx / _kDamping; - final double endY = dragOffset.dy >= 0.0 ? dragOffset.dy : _kPadding * dragOffset.dy / _kDamping; + final double endY = dragOffset.dy >= 0.0 + ? dragOffset.dy + : _kPadding * dragOffset.dy / _kDamping; setState(() { _dragOffset = dragOffset; _moveAnimation = Tween( @@ -742,15 +783,20 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T ), ); - if (_lastScale <= _kSheetScaleThreshold && _sheetController.status != AnimationStatus.forward && _sheetScaleAnimation.value != 0.0) { + if (_lastScale <= _kSheetScaleThreshold && + _sheetController.status != AnimationStatus.forward && + _sheetScaleAnimation.value != 0.0) { _sheetController.forward(); - } else if (_lastScale > _kSheetScaleThreshold && _sheetController.status != AnimationStatus.reverse && _sheetScaleAnimation.value != 1.0) { + } else if (_lastScale > _kSheetScaleThreshold && + _sheetController.status != AnimationStatus.reverse && + _sheetScaleAnimation.value != 1.0) { _sheetController.reverse(); } }); } - List _getChildren(Orientation orientation, _ViewableLocation contextMenuLocation) { + List _getChildren( + Orientation orientation, _ViewableLocation contextMenuLocation) { final Expanded child = Expanded( child: Align( alignment: _getChildAlignment( @@ -781,7 +827,9 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T case _ViewableLocation.center: return [child, spacer, sheet]; case _ViewableLocation.right: - return orientation == Orientation.portrait ? [child, spacer, sheet] : [sheet, spacer, child]; + return orientation == Orientation.portrait + ? [child, spacer, sheet] + : [sheet, spacer, child]; case _ViewableLocation.left: return [child, spacer, sheet]; } @@ -915,7 +963,8 @@ class _ViewableSheet extends StatelessWidget { decoration: BoxDecoration( border: Border( top: BorderSide( - color: CupertinoDynamicColor.resolve(_borderColor, context), + color: + CupertinoDynamicColor.resolve(_borderColor, context), width: 0.5, )), ), diff --git a/refilc_mobile_ui/lib/common/widgets/cretification/certification_tile.dart b/refilc_mobile_ui/lib/common/widgets/cretification/certification_tile.dart index 683f084..5702fbc 100644 --- a/refilc_mobile_ui/lib/common/widgets/cretification/certification_tile.dart +++ b/refilc_mobile_ui/lib/common/widgets/cretification/certification_tile.dart @@ -59,7 +59,7 @@ class CertificationTile extends StatelessWidget { } return Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(8.0), child: Padding( padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0), diff --git a/refilc_mobile_ui/lib/common/widgets/cretification/certification_view.dart b/refilc_mobile_ui/lib/common/widgets/cretification/certification_view.dart index 270c95d..3357f6f 100644 --- a/refilc_mobile_ui/lib/common/widgets/cretification/certification_view.dart +++ b/refilc_mobile_ui/lib/common/widgets/cretification/certification_view.dart @@ -13,31 +13,43 @@ class CertificationView extends StatelessWidget { final List grades; final GradeType gradeType; - static show(List grades, {required BuildContext context, required GradeType gradeType}) => - Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute(builder: (context) => CertificationView(grades, gradeType: gradeType))); + static show(List grades, + {required BuildContext context, required GradeType gradeType}) => + Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute( + builder: (context) => + CertificationView(grades, gradeType: gradeType))); @override Widget build(BuildContext context) { grades.sort((a, b) => a.subject.name.compareTo(b.subject.name)); - List tiles = grades.map((e) => CertificationTile(e)).toList(); + List tiles = grades + .map((e) => CertificationTile( + e, + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 5.0), + )) + .toList(); return Scaffold( - body: HeroScrollView( + body: HeroScrollView( title: getGradeTypeTitle(gradeType), icon: FeatherIcons.award, iconSize: 50, - child: ListView( + child: ListView( shrinkWrap: true, padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0), physics: const BouncingScrollPhysics(), children: [ SafeArea( child: Panel( + padding: + const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0), child: Column( children: tiles, ), ), ) ], - ))); + ), + ), + ); } } diff --git a/refilc_mobile_ui/lib/common/widgets/custom_segmented_control.dart b/refilc_mobile_ui/lib/common/widgets/custom_segmented_control.dart index a9bf40b..86d44f0 100644 --- a/refilc_mobile_ui/lib/common/widgets/custom_segmented_control.dart +++ b/refilc_mobile_ui/lib/common/widgets/custom_segmented_control.dart @@ -38,7 +38,7 @@ class CustomSegmentedControl extends StatelessWidget { borderRadius: BorderRadius.circular(12.0), ), thumbDecoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(10.0), // boxShadow: [ // BoxShadow( diff --git a/refilc_mobile_ui/lib/common/widgets/event/event_tile.dart b/refilc_mobile_ui/lib/common/widgets/event/event_tile.dart index 17c8f7e..6c0dc2a 100644 --- a/refilc_mobile_ui/lib/common/widgets/event/event_tile.dart +++ b/refilc_mobile_ui/lib/common/widgets/event/event_tile.dart @@ -13,7 +13,7 @@ class EventTile extends StatelessWidget { @override Widget build(BuildContext context) { return Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(14.0), child: Padding( padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0), diff --git a/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart b/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart index b8b4c33..129d8ae 100644 --- a/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart @@ -31,8 +31,18 @@ class ExamViewable extends StatelessWidget { @override Widget build(BuildContext context) { if (Provider.of(context).newPopups) { + bool pressed = false; + return GestureDetector( - onTap: () => ExamPopup.show(context: context, exam: exam), + onTap: () { + // prevent double tap things + if (pressed) return; + pressed = true; + ExamPopup.show(context: context, exam: exam); + Future.delayed(const Duration(seconds: 2), () { + pressed = false; + }); + }, child: ExamTile( exam, showSubject: showSubject, @@ -198,7 +208,7 @@ class ExamPopup extends StatelessWidget { Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical( top: Radius.circular(12.0), bottom: Radius.circular(6.0)), @@ -256,7 +266,7 @@ class ExamPopup extends StatelessWidget { Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical( top: Radius.circular(6.0), bottom: Radius.circular(12.0)), @@ -338,7 +348,7 @@ class ExamPopup extends StatelessWidget { // child: Container( // width: double.infinity, // decoration: BoxDecoration( - // color: Theme.of(context).colorScheme.background, + // color: Theme.of(context).colorScheme.surface, // borderRadius: BorderRadius.circular(12.0), // ), // padding: const EdgeInsets.all(16.0), diff --git a/refilc_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart b/refilc_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart index ffcbb25..95c4e68 100644 --- a/refilc_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart +++ b/refilc_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart @@ -34,7 +34,7 @@ class ChangedLessonTile extends StatelessWidget { } return Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(14.0), child: Padding( padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0), diff --git a/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart b/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart index cec6307..90a3402 100644 --- a/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart @@ -417,7 +417,7 @@ class TimetableLessonPopup extends StatelessWidget { Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical( top: Radius.circular(12.0), bottom: Radius.circular(6.0), @@ -521,7 +521,7 @@ class TimetableLessonPopup extends StatelessWidget { Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical( top: Radius.circular(6.0), bottom: Radius.circular(6.0), @@ -549,7 +549,7 @@ class TimetableLessonPopup extends StatelessWidget { Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.vertical( top: const Radius.circular(6.0), bottom: lesson.exam != '' @@ -580,7 +580,7 @@ class TimetableLessonPopup extends StatelessWidget { Container( width: double.infinity, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical( top: Radius.circular(6.0), bottom: Radius.circular(12.0)), @@ -654,7 +654,7 @@ class TimetableLessonPopup extends StatelessWidget { // child: Container( // width: double.infinity, // decoration: BoxDecoration( - // color: Theme.of(context).colorScheme.background, + // color: Theme.of(context).colorScheme.surface, // borderRadius: BorderRadius.circular(12.0), // ), // padding: const EdgeInsets.all(16.0), diff --git a/refilc_mobile_ui/lib/common/widgets/message/message_viewable.dart b/refilc_mobile_ui/lib/common/widgets/message/message_viewable.dart index 3e22685..a46192f 100644 --- a/refilc_mobile_ui/lib/common/widgets/message/message_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/message/message_viewable.dart @@ -23,9 +23,9 @@ class MessageViewable extends StatelessWidget { RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)), closedShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)), - middleColor: Theme.of(context).colorScheme.background, + middleColor: Theme.of(context).colorScheme.surface, openColor: Theme.of(context).scaffoldBackgroundColor, - closedColor: Theme.of(context).colorScheme.background, + closedColor: Theme.of(context).colorScheme.surface, transitionType: ContainerTransitionType.fadeThrough, transitionDuration: const Duration(milliseconds: 400), useRootNavigator: true, diff --git a/refilc_mobile_ui/lib/common/widgets/statistics_tile.dart b/refilc_mobile_ui/lib/common/widgets/statistics_tile.dart index e655aa9..23afdce 100644 --- a/refilc_mobile_ui/lib/common/widgets/statistics_tile.dart +++ b/refilc_mobile_ui/lib/common/widgets/statistics_tile.dart @@ -48,7 +48,7 @@ class StatisticsTile extends StatelessWidget { padding: const EdgeInsets.all(18.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, boxShadow: [ if (Provider.of(context, listen: false) .shadowEffect) diff --git a/refilc_mobile_ui/lib/pages/grades/average_selector.dart b/refilc_mobile_ui/lib/pages/grades/average_selector.dart index e80ef04..854a548 100644 --- a/refilc_mobile_ui/lib/pages/grades/average_selector.dart +++ b/refilc_mobile_ui/lib/pages/grades/average_selector.dart @@ -84,9 +84,9 @@ class AverageSelectorState extends State { elevation: 8, scrollbarTheme: ScrollbarThemeData( radius: const Radius.circular(40), - thickness: MaterialStateProperty.all(6.0), - trackVisibility: MaterialStateProperty.all(true), - thumbVisibility: MaterialStateProperty.all(true), + thickness: WidgetStateProperty.all(6.0), + trackVisibility: WidgetStateProperty.all(true), + thumbVisibility: WidgetStateProperty.all(true), ), offset: const Offset(-10, -10), ), diff --git a/refilc_mobile_ui/lib/pages/grades/grades_page.dart b/refilc_mobile_ui/lib/pages/grades/grades_page.dart index 4e6163d..c81bc2f 100644 --- a/refilc_mobile_ui/lib/pages/grades/grades_page.dart +++ b/refilc_mobile_ui/lib/pages/grades/grades_page.dart @@ -7,6 +7,7 @@ import 'dart:math'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:collection/collection.dart'; import 'package:file_picker/file_picker.dart'; +import 'package:flutter/foundation.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:refilc/api/providers/update_provider.dart'; import 'package:refilc/models/settings.dart'; @@ -83,6 +84,7 @@ class GradesPageState extends State { late GradeCalculatorProvider calculatorProvider; late HomeworkProvider homeworkProvider; late ExamProvider examProvider; + late SettingsProvider settingsProvider; late String firstName; late Widget yearlyGraph; @@ -162,7 +164,14 @@ class GradesPageState extends State { bool hasHomework = homeworkCount > 0; List allExams = examProvider.exams; - allExams.sort((a, b) => a.date.compareTo(b.date)); + try { + allExams.sort((a, b) => a.date.compareTo(b.date)); + } catch (e) { + if (kDebugMode) { + print('failed to sort exams, reason: flutter'); + } + allExams = []; + } Exam? nearestExam = allExams.firstWhereOrNull((e) => e.subject.id == subject.id && e.writeDate.isAfter(DateTime.now())); @@ -196,7 +205,7 @@ class GradesPageState extends State { ? const Radius.circular(8.0) : const Radius.circular(16.0), ), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), child: Padding( padding: const EdgeInsets.symmetric( @@ -247,7 +256,7 @@ class GradesPageState extends State { ? const Radius.circular(8.0) : const Radius.circular(16.0), ), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), child: Padding( padding: const EdgeInsets.only( @@ -298,7 +307,7 @@ class GradesPageState extends State { bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0), ), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), child: ExamViewable( nearestExam, @@ -368,8 +377,14 @@ class GradesPageState extends State { ); } + // print('rounding:'); + // print(settingsProvider.rounding); + double subjectAvg = subjectAvgs.isNotEmpty - ? subjectAvgs.values.fold(0.0, (double a, double b) => a + b) / + ? subjectAvgs.values.fold( + 0.0, + (double a, double b) => + a.round().toDouble() + b.round().toDouble()) / subjectAvgs.length : 0.0; final double classAvg = gradeProvider.groupAverages.isNotEmpty @@ -440,6 +455,7 @@ class GradesPageState extends State { calculatorProvider = Provider.of(context); homeworkProvider = Provider.of(context); examProvider = Provider.of(context); + settingsProvider = Provider.of(context); context.watch(); @@ -673,7 +689,7 @@ class GradesPageState extends State { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: ListTile( title: Row( children: [ @@ -685,12 +701,12 @@ class GradesPageState extends State { ], ), onTap: () { - if (!Provider.of(context, listen: false) - .hasScope(PremiumScopes.totalGradeCalculator)) { - PlusLockedFeaturePopup.show( - context: context, feature: PremiumFeature.gradeCalculation); - return; - } + // if (!Provider.of(context, listen: false) + // .hasScope(PremiumScopes.totalGradeCalculator)) { + // PlusLockedFeaturePopup.show( + // context: context, feature: PremiumFeature.gradeCalculation); + // return; + // } // SoonAlert.show(context: context); gradeCalcTotal(context); @@ -705,7 +721,7 @@ class GradesPageState extends State { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: ListTile( title: Row( children: [ @@ -763,7 +779,7 @@ class GradesPageState extends State { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: SwitchListTile( title: Row( children: [ diff --git a/refilc_mobile_ui/lib/pages/grades/graph.dart b/refilc_mobile_ui/lib/pages/grades/graph.dart index a52720b..c8c382b 100644 --- a/refilc_mobile_ui/lib/pages/grades/graph.dart +++ b/refilc_mobile_ui/lib/pages/grades/graph.dart @@ -179,7 +179,7 @@ class GradeGraphState extends State { ? Alignment.topRight : Alignment.topLeft, style: TextStyle( - backgroundColor: Theme.of(context).colorScheme.background, + backgroundColor: Theme.of(context).colorScheme.surface, color: AppColors.of(context).text, fontSize: 16.0, fontWeight: FontWeight.w600, @@ -217,7 +217,7 @@ class GradeGraphState extends State { height: 158, child: subjectSpots.length > 1 ? Padding( - padding: const EdgeInsets.only(top: 8.0, right: 8.0), + padding: const EdgeInsets.only(top: 6.0, right: 0.0), child: LineChart( LineChartData( extraLinesData: ExtraLinesData( @@ -228,22 +228,32 @@ class GradeGraphState extends State { preventCurveOverShooting: false, spots: subjectSpots, isCurved: true, - colors: averageColors.reversed.toList(), + // colors: averageColors.reversed.toList(), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: averageColors.reversed.toList(), + ), barWidth: 6, curveSmoothness: 0.2, isStrokeCapRound: true, - dotData: FlDotData(show: false), + dotData: const FlDotData(show: false), belowBarData: BarAreaData( show: true, - colors: [ - averageColor.withOpacity(0.7), - averageColor.withOpacity(0.3), - averageColor.withOpacity(0.2), - averageColor.withOpacity(0.1), - ], - gradientColorStops: [0.1, 0.6, 0.8, 1], - gradientFrom: const Offset(0, 0), - gradientTo: const Offset(0, 1), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + averageColor.withOpacity(0.7), + averageColor.withOpacity(0.3), + averageColor.withOpacity(0.2), + averageColor.withOpacity(0.1), + ], + stops: const [0.1, 0.6, 0.8, 1], + ), + // gradientColorStops: [0.1, 0.6, 0.8, 1], + // gradientFrom: const Offset(0, 0), + // gradientTo: const Offset(0, 1), ), ), if (ghostData.isNotEmpty && ghostSpots.isNotEmpty) @@ -251,28 +261,41 @@ class GradeGraphState extends State { preventCurveOverShooting: false, spots: ghostSpots, isCurved: true, - colors: [AppColors.of(context).text], + color: AppColors.of(context).text, barWidth: 6, curveSmoothness: 0.2, isStrokeCapRound: true, - dotData: FlDotData(show: false), + dotData: const FlDotData(show: false), belowBarData: BarAreaData( show: true, - colors: [ - AppColors.of(context).text.withOpacity(0.7), - AppColors.of(context).text.withOpacity(0.3), - AppColors.of(context).text.withOpacity(0.2), - AppColors.of(context).text.withOpacity(0.1), - ], - gradientColorStops: [0.1, 0.6, 0.8, 1], - gradientFrom: const Offset(0, 0), - gradientTo: const Offset(0, 1), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + AppColors.of(context) + .text + .withOpacity(0.7), + AppColors.of(context) + .text + .withOpacity(0.3), + AppColors.of(context) + .text + .withOpacity(0.2), + AppColors.of(context) + .text + .withOpacity(0.1), + ], + stops: const [0.1, 0.6, 0.8, 1], + ), + // gradientColorStops: [0.1, 0.6, 0.8, 1], + // gradientFrom: const Offset(0, 0), + // gradientTo: const Offset(0, 1), ), ), ], minY: 1, maxY: 5, - gridData: FlGridData( + gridData: const FlGridData( show: true, horizontalInterval: 1, // checkToShowVerticalLine: (_) => false, @@ -286,8 +309,8 @@ class GradeGraphState extends State { // ), ), lineTouchData: LineTouchData( - touchTooltipData: LineTouchTooltipData( - tooltipBgColor: Colors.grey.shade800, + touchTooltipData: const LineTouchTooltipData( + // tooltipBgColor: Colors.grey.shade800, fitInsideVertically: true, fitInsideHorizontally: true, ), @@ -321,64 +344,111 @@ class GradeGraphState extends State { ), ), titlesData: FlTitlesData( - bottomTitles: SideTitles( - showTitles: true, - reservedSize: 24, - getTextStyles: (context, value) => TextStyle( - color: - AppColors.of(context).text.withOpacity(.75), - fontWeight: FontWeight.bold, - fontSize: 14.0, - ), - margin: 12.0, - getTitles: (value) { - var format = DateFormat( - "MMM", I18n.of(context).locale.toString()); + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 25, + getTitlesWidget: (value, meta) { + if (value == meta.max || value == meta.min) { + return Container(); + } - String title = format - .format(DateTime(0, value.floor() % 12)) - .replaceAll(".", ""); - title = - title.substring(0, min(title.length, 4)); + var format = DateFormat("MMM", + I18n.of(context).locale.toString()); - return title.toUpperCase(); - }, - interval: () { - List tData = - ghostData.isNotEmpty ? ghostData : data; - tData.sort((a, b) => - a.writeDate.compareTo(b.writeDate)); - return ghostData.isNotEmpty - ? 3.0 - : tData.first.writeDate - .add(const Duration(days: 120)) - .isBefore(tData.last.writeDate) - ? 2.0 - : 2.5; - }(), - checkToShowTitle: (double minValue, - double maxValue, - SideTitles sideTitles, - double appliedInterval, - double value) { - if (value == maxValue || value == minValue) { - return false; - } - return true; - }, - ), - leftTitles: SideTitles( - showTitles: true, - interval: 1.0, - getTextStyles: (context, value) => TextStyle( - color: AppColors.of(context).text, - fontWeight: FontWeight.bold, - fontSize: 18.0, + String title = format + .format(DateTime(0, value.floor() % 12)) + .replaceAll(".", ""); + title = + title.substring(0, min(title.length, 4)); + + return Text( + title.toUpperCase(), + style: TextStyle( + color: AppColors.of(context) + .text + .withOpacity(.75), + fontWeight: FontWeight.bold, + fontSize: 14.0, + ), + ); + }, + // getTextStyles: (context, value) => TextStyle( + // color: AppColors.of(context) + // .text + // .withOpacity(.75), + // fontWeight: FontWeight.bold, + // fontSize: 14.0, + // ), + // margin: 12.0, + // getTitles: (value) { + // var format = DateFormat("MMM", + // I18n.of(context).locale.toString()); + + // String title = format + // .format(DateTime(0, value.floor() % 12)) + // .replaceAll(".", ""); + // title = + // title.substring(0, min(title.length, 4)); + + // return title.toUpperCase(); + // }, + interval: () { + List tData = + ghostData.isNotEmpty ? ghostData : data; + tData.sort((a, b) => + a.writeDate.compareTo(b.writeDate)); + return ghostData.isNotEmpty + ? 3.0 + : tData.first.writeDate + .add(const Duration(days: 120)) + .isBefore(tData.last.writeDate) + ? 2.0 + : 2.5; + }(), + // checkToShowTitle: (double minValue, + // double maxValue, + // SideTitles sideTitles, + // double appliedInterval, + // double value) { + // if (value == maxValue || value == minValue) { + // return false; + // } + // return true; + // }, ), - margin: 16, ), - rightTitles: SideTitles(showTitles: false), - topTitles: SideTitles(showTitles: false), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + interval: 1.0, + reservedSize: 26.0, + getTitlesWidget: (value, meta) => Padding( + padding: const EdgeInsets.only( + left: 6.0, right: 10.0), + child: Text( + value.toInt().toString(), + style: TextStyle( + color: AppColors.of(context).text, + fontWeight: FontWeight.bold, + fontSize: 16.0, + ), + ), + ), + // getTextStyles: (context, value) => TextStyle( + // color: AppColors.of(context).text, + // fontWeight: FontWeight.bold, + // fontSize: 18.0, + // ), + // margin: 16, + ), + ), + rightTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), ), ), ), diff --git a/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart b/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart index 1092e9d..6d8253d 100644 --- a/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart +++ b/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart @@ -1,6 +1,7 @@ // ignore_for_file: unnecessary_null_comparison import 'package:animations/animations.dart'; +import 'package:flutter/services.dart'; import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/helpers/subject.dart'; import 'package:refilc/models/settings.dart'; @@ -43,6 +44,10 @@ class LiveCardStateA extends State { _userProvider = Provider.of(context, listen: false); liveCard = Provider.of(context, listen: false); _userProvider.addListener(liveCard.update); + + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + ]); } @override @@ -419,14 +424,38 @@ class LiveCardStateA extends State { if (progressCurrent != null && progressMax != null) GestureDetector( - onTap: () { - showDialog( + onTap: () async { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + DeviceOrientation.landscapeRight, + DeviceOrientation.landscapeLeft, + ]); + + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: + Brightness.dark, + systemNavigationBarColor: + Colors.transparent, + systemNavigationBarIconBrightness: + Brightness.dark, + )); + + var result = await showDialog( barrierColor: Colors.black, context: context, builder: (context) => HeadsUpCountdown( maxTime: maxTime, elapsedTime: elapsedTime), ); + + if (result != null) { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + ]); + } }, child: Container( color: Colors.transparent, @@ -825,14 +854,38 @@ class LiveCardStateA extends State { if (progressCurrent != null && progressMax != null) GestureDetector( - onTap: () { - showDialog( + onTap: () async { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + DeviceOrientation.landscapeRight, + DeviceOrientation.landscapeLeft, + ]); + + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: + Brightness.dark, + systemNavigationBarColor: + Colors.transparent, + systemNavigationBarIconBrightness: + Brightness.dark, + )); + + var result = await showDialog( barrierColor: Colors.black, context: context, builder: (context) => HeadsUpCountdown( maxTime: maxTime, elapsedTime: elapsedTime), ); + + if (result != null) { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + ]); + } }, child: Container( color: Colors.transparent, diff --git a/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart b/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart index 07f3933..db17acf 100644 --- a/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart +++ b/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart @@ -72,10 +72,10 @@ class _LiveCardWidgetState extends State { ? const EdgeInsets.all(12.0) : EdgeInsets.zero, decoration: BoxDecoration( - // color: Theme.of(context).colorScheme.background, + // color: Theme.of(context).colorScheme.surface, color: widget.children != null ? Colors.transparent - : Theme.of(context).colorScheme.background, + : Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(16.0), boxShadow: [ if (Provider.of(context, listen: false) diff --git a/refilc_mobile_ui/lib/pages/messages/messages_page.dart b/refilc_mobile_ui/lib/pages/messages/messages_page.dart index 117c280..6d7cdbf 100644 --- a/refilc_mobile_ui/lib/pages/messages/messages_page.dart +++ b/refilc_mobile_ui/lib/pages/messages/messages_page.dart @@ -125,7 +125,7 @@ class MessagesPageState extends State BackButton( style: ButtonStyle( splashFactory: NoSplash.splashFactory, - padding: MaterialStateProperty.all( + padding: WidgetStateProperty.all( EdgeInsets.zero), ), ), diff --git a/refilc_mobile_ui/lib/pages/messages/send_message/send_message.dart b/refilc_mobile_ui/lib/pages/messages/send_message/send_message.dart index 869aff2..e3dbe22 100644 --- a/refilc_mobile_ui/lib/pages/messages/send_message/send_message.dart +++ b/refilc_mobile_ui/lib/pages/messages/send_message/send_message.dart @@ -105,9 +105,9 @@ class SendMessageSheetState extends State { elevation: 8, scrollbarTheme: ScrollbarThemeData( radius: const Radius.circular(40), - thickness: MaterialStateProperty.all(6.0), - trackVisibility: MaterialStateProperty.all(true), - thumbVisibility: MaterialStateProperty.all(true), + thickness: WidgetStateProperty.all(6.0), + trackVisibility: WidgetStateProperty.all(true), + thumbVisibility: WidgetStateProperty.all(true), ), offset: const Offset(-10, -10), ), diff --git a/refilc_mobile_ui/lib/pages/notes/notes_page.dart b/refilc_mobile_ui/lib/pages/notes/notes_page.dart index 5921b59..537fe24 100644 --- a/refilc_mobile_ui/lib/pages/notes/notes_page.dart +++ b/refilc_mobile_ui/lib/pages/notes/notes_page.dart @@ -88,6 +88,7 @@ class NotesPageState extends State with TickerProviderStateMixin { // todo tiles List toDoTiles = []; + // TODO: FIX THIS ASAP if (hw.isNotEmpty && Provider.of(context, listen: false) .hasScope(PremiumScopes.unlimitedSelfNotes)) { @@ -98,13 +99,23 @@ class NotesPageState extends State with TickerProviderStateMixin { '${(e.subject.isRenamed ? e.subject.renamedTo : e.subject.name) ?? ''}, ${e.content.escapeHtml()}', isTicked: doneItems[e.id] ?? false, onTap: (p0) async { + // print(p0); + // print(doneItems); if (!doneItems.containsKey(e.id)) { doneItems.addAll({e.id: p0}); } else { doneItems[e.id] = p0; } + // print(doneItems); + // print(doneItems[e.id]); + // print(user.id); await databaseProvider.userStore .storeToDoItem(doneItems, userId: user.id!); + + setState(() {}); + + // print( + // await databaseProvider.userQuery.toDoItems(userId: user.id!)); }, ))); } @@ -116,10 +127,20 @@ class NotesPageState extends State with TickerProviderStateMixin { description: e.content, isTicked: e.done, onTap: (p0) async { - todoItems.firstWhere((element) => element.id == e.id).done = p0; + final todoItemIndex = + todoItems.indexWhere((element) => element.id == e.id); + if (todoItemIndex != -1) { + TodoItem todoItem = todoItems[todoItemIndex]; + Map todoItemJson = todoItem.toJson; + todoItemJson['done'] = p0; + todoItem = TodoItem.fromJson(todoItemJson); + todoItems[todoItemIndex] = todoItem; + await databaseProvider.userStore + .storeSelfTodoItems(todoItems, userId: user.id!); + } - await databaseProvider.userStore - .storeSelfTodoItems(todoItems, userId: user.id!); + // await databaseProvider.userStore + // .storeSelfTodoItems(todoItems, userId: user.id!); }, ))); } @@ -410,7 +431,7 @@ class NotesPageState extends State with TickerProviderStateMixin { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: ListTile( title: Row( children: [ @@ -432,7 +453,7 @@ class NotesPageState extends State with TickerProviderStateMixin { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: ListTile( title: Row( children: [ @@ -456,7 +477,7 @@ class NotesPageState extends State with TickerProviderStateMixin { Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: ListTile( title: Row( children: [ @@ -468,13 +489,13 @@ class NotesPageState extends State with TickerProviderStateMixin { ], ), onTap: () { - if (!Provider.of(context, listen: false) - .hasScope(PremiumScopes.unlimitedSelfNotes)) { - PlusLockedFeaturePopup.show( - context: context, feature: PremiumFeature.selfNotes); + // if (!Provider.of(context, listen: false) + // .hasScope(PremiumScopes.unlimitedSelfNotes)) { + // PlusLockedFeaturePopup.show( + // context: context, feature: PremiumFeature.selfNotes); - return; - } + // return; + // } showTaskCreation(context); }, diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/self_note_tile.dart b/refilc_mobile_ui/lib/pages/notes/submenu/self_note_tile.dart index d1d5095..999c975 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/self_note_tile.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/self_note_tile.dart @@ -22,7 +22,7 @@ class SelfNoteTile extends StatelessWidget { padding: const EdgeInsets.all(10.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, boxShadow: [ if (Provider.of(context, listen: false) .shadowEffect) diff --git a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart index 0610d60..388a9ac 100644 --- a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart +++ b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart @@ -700,7 +700,7 @@ class TimetablePageState extends State ], color: Theme.of(context) .colorScheme - .background, + .surface, borderRadius: BorderRadius.only( topLeft: index == 0 @@ -786,7 +786,7 @@ class TimetablePageState extends State indicatorPadding: const EdgeInsets.symmetric(horizontal: 10.0), indicator: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, // color: Colors.transparent, // border: Border.all( // color: AppColors.of(context) @@ -798,7 +798,7 @@ class TimetablePageState extends State // .withOpacity(0.25), borderRadius: BorderRadius.circular(16.0), ), - overlayColor: MaterialStateProperty.all( + overlayColor: WidgetStateProperty.all( const Color(0x00000000)), // Tabs padding: const EdgeInsets.symmetric( @@ -899,7 +899,7 @@ class TimetablePageState extends State Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: ListTile( contentPadding: const EdgeInsets.only(left: 16.0, right: 10.0), title: Row( @@ -943,7 +943,7 @@ class TimetablePageState extends State Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: SwitchListTile( contentPadding: const EdgeInsets.only(left: 16.0, right: 10.0), title: Row( @@ -990,7 +990,7 @@ class TimetablePageState extends State Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.surface), child: SwitchListTile( contentPadding: const EdgeInsets.only(left: 16.0, right: 10.0), title: Row( diff --git a/refilc_mobile_ui/lib/plus/plus_screen.dart b/refilc_mobile_ui/lib/plus/plus_screen.dart index 9cd7e8a..d6d1bd3 100644 --- a/refilc_mobile_ui/lib/plus/plus_screen.dart +++ b/refilc_mobile_ui/lib/plus/plus_screen.dart @@ -222,10 +222,11 @@ class PlusScreenState extends State { // ['👥', 'rfp_2'.i18n], ['👋', 'rfp_3'.i18n], ['📓', 'rfp_4'.i18n], - ['🎓', 'rfp_6'.i18n], + // ['🎓', 'rfp_6'.i18n], + ['📩', 'rfp_17'.i18n], + ['🪟', 'rfp_18'.i18n], ['👕', 'rfp_14'.i18n], ['👑', 'rfp_15'.i18n], - ['📩', 'rfp_17'.i18n], ['🔜', 'more_soon'.i18n], ], docsAccepted: docsAccepted, @@ -389,6 +390,8 @@ class PlusScreenState extends State { ), ), child: CheckboxListTile( + side: + const BorderSide(color: Colors.black, width: 2.0), contentPadding: const EdgeInsets.only(left: 15.0, right: 10.0), value: docsAccepted, diff --git a/refilc_mobile_ui/lib/plus/plus_screen.i18n.dart b/refilc_mobile_ui/lib/plus/plus_screen.i18n.dart index 4bcfd28..5c9b29b 100644 --- a/refilc_mobile_ui/lib/plus/plus_screen.i18n.dart +++ b/refilc_mobile_ui/lib/plus/plus_screen.i18n.dart @@ -46,6 +46,7 @@ extension SettingsLocalization on String { "rfp_15": "Subscriber role in our Discord community", "rfp_16": "Private leaks and informations about upcoming features", "rfp_17": "Grade exporting", + "rfp_18": "Viewing exported grades", // other "and": " and ", "every": "Every ", @@ -98,6 +99,7 @@ extension SettingsLocalization on String { "rfp_15": "Előfizetői rang a Discord szerverünkön", "rfp_16": "Privát betekintések és információk közelgő újításokról", "rfp_17": "Jegy exportálás", + "rfp_18": "Exportált jegyek megtekintése", // other "and": " és ", "every": "Minden ", @@ -153,6 +155,7 @@ extension SettingsLocalization on String { "rfp_15": "Abonnentenrolle in unserer Discord-Community", "rfp_16": "Private Leaks und Informationen über kommende Funktionen", "rfp_17": "Notenexport", + "rfp_18": "Anzeigen exportierter Noten", // other "and": " und ", "every": "Jeder ", diff --git a/refilc_mobile_ui/lib/screens/error_report_screen.dart b/refilc_mobile_ui/lib/screens/error_report_screen.dart index aed20d1..6313bd5 100644 --- a/refilc_mobile_ui/lib/screens/error_report_screen.dart +++ b/refilc_mobile_ui/lib/screens/error_report_screen.dart @@ -110,10 +110,10 @@ class ErrorReportScreen extends StatelessWidget { height: 48, child: TextButton( style: ButtonStyle( - padding: MaterialStateProperty.all( + padding: WidgetStateProperty.all( const EdgeInsets.symmetric(vertical: 10.0)), - backgroundColor: MaterialStateProperty.all(Colors.black), - shape: MaterialStateProperty.all( + backgroundColor: WidgetStateProperty.all(Colors.black), + shape: WidgetStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0)), ), @@ -135,18 +135,18 @@ class ErrorReportScreen extends StatelessWidget { height: 48, child: OutlinedButton( style: ButtonStyle( - padding: MaterialStateProperty.all( + padding: WidgetStateProperty.all( const EdgeInsets.symmetric(vertical: 14.0), ), - backgroundColor: MaterialStateProperty.all( + backgroundColor: WidgetStateProperty.all( const Color(0xFFF3F7FE), ), - shape: MaterialStateProperty.all( + shape: WidgetStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), ), - side: MaterialStateProperty.all( + side: WidgetStateProperty.all( const BorderSide(width: 1.0, color: Color(0xFFC7D3EB)), ), ), diff --git a/refilc_mobile_ui/lib/screens/error_screen.dart b/refilc_mobile_ui/lib/screens/error_screen.dart index 4439395..cc119d3 100644 --- a/refilc_mobile_ui/lib/screens/error_screen.dart +++ b/refilc_mobile_ui/lib/screens/error_screen.dart @@ -39,7 +39,7 @@ class ErrorScreen extends StatelessWidget { width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(14.0), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), child: CupertinoScrollbar( child: SingleChildScrollView( diff --git a/refilc_mobile_ui/lib/screens/login/login_screen_new.dart b/refilc_mobile_ui/lib/screens/login/login_screen_new.dart index 7c9cab0..d2b3fd0 100644 --- a/refilc_mobile_ui/lib/screens/login/login_screen_new.dart +++ b/refilc_mobile_ui/lib/screens/login/login_screen_new.dart @@ -221,7 +221,7 @@ // horizontal: 16), // child: FilledButton( // style: ButtonStyle( -// shape: MaterialStateProperty.all< +// shape: WidgetStateProperty.all< // RoundedRectangleBorder>( // const RoundedRectangleBorder( // borderRadius: BorderRadius.all( diff --git a/refilc_mobile_ui/lib/screens/login/school_input/school_input_overlay.dart b/refilc_mobile_ui/lib/screens/login/school_input/school_input_overlay.dart index 4279507..2fbc71e 100644 --- a/refilc_mobile_ui/lib/screens/login/school_input/school_input_overlay.dart +++ b/refilc_mobile_ui/lib/screens/login/school_input/school_input_overlay.dart @@ -47,7 +47,7 @@ class SchoolInputOverlayWidget extends StatelessWidget { showWhenUnlinked: false, offset: Offset(0.0, size.height + 5.0), child: Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0)), elevation: 4.0, diff --git a/refilc_mobile_ui/lib/screens/navigation/navigation_route_handler.dart b/refilc_mobile_ui/lib/screens/navigation/navigation_route_handler.dart index 7c06e1f..f741d4c 100644 --- a/refilc_mobile_ui/lib/screens/navigation/navigation_route_handler.dart +++ b/refilc_mobile_ui/lib/screens/navigation/navigation_route_handler.dart @@ -2,6 +2,7 @@ import 'package:refilc_mobile_ui/pages/absences/absences_page.dart'; import 'package:refilc_mobile_ui/pages/grades/grades_page.dart'; import 'package:refilc_mobile_ui/pages/home/home_page.dart'; +import 'package:refilc_mobile_ui/pages/messages/messages_page.dart'; import 'package:refilc_mobile_ui/pages/notes/notes_page.dart'; // import 'package:refilc_mobile_ui/pages/messages/messages_page.dart'; import 'package:refilc_mobile_ui/pages/timetable/timetable_page.dart'; @@ -20,8 +21,8 @@ Route navigationRouteHandler(RouteSettings settings) { return navigationPageRoute((context) => const NotesPage()); case "absences": return navigationPageRoute((context) => const AbsencesPage()); - // case "messages": - // return navigationPageRoute((context) => const MessagesPage()); + case "messages": + return navigationPageRoute((context) => const MessagesPage()); // case "absences": // return navigationPageRoute((context) => const AbsencesPage()); default: diff --git a/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart b/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart index cfef95e..0a43ba8 100644 --- a/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart +++ b/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart @@ -302,7 +302,7 @@ class NavigationScreenState extends State children: [ // Status bar Material( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: const StatusBar(), ), diff --git a/refilc_mobile_ui/lib/screens/settings/desktop_settings.dart b/refilc_mobile_ui/lib/screens/settings/desktop_settings.dart index 54c6fe1..b6fe122 100644 --- a/refilc_mobile_ui/lib/screens/settings/desktop_settings.dart +++ b/refilc_mobile_ui/lib/screens/settings/desktop_settings.dart @@ -13,7 +13,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:provider/provider.dart'; import 'package:refilc_mobile_ui/screens/settings/settings_screen.i18n.dart'; -import 'package:refilc_mobile_ui/common/beta_chip.dart'; +import 'package:refilc_mobile_ui/common/chips/beta_chip.dart'; class MenuDesktopSettings extends StatelessWidget { const MenuDesktopSettings({super.key, required this.settings}); diff --git a/refilc_mobile_ui/lib/screens/settings/modify_subject_names.dart b/refilc_mobile_ui/lib/screens/settings/modify_subject_names.dart index aa1c7be..25e4e61 100644 --- a/refilc_mobile_ui/lib/screens/settings/modify_subject_names.dart +++ b/refilc_mobile_ui/lib/screens/settings/modify_subject_names.dart @@ -178,8 +178,8 @@ class _ModifySubjectNamesState extends State { elevation: 8, scrollbarTheme: ScrollbarThemeData( radius: const Radius.circular(40), - thickness: MaterialStateProperty.all(6.0), - trackVisibility: MaterialStateProperty.all(true), + thickness: WidgetStateProperty.all(6.0), + trackVisibility: WidgetStateProperty.all(true), ), offset: const Offset(-10, -10), ), diff --git a/refilc_mobile_ui/lib/screens/settings/settings_helper.dart b/refilc_mobile_ui/lib/screens/settings/settings_helper.dart index 7ae7920..4cc2e37 100644 --- a/refilc_mobile_ui/lib/screens/settings/settings_helper.dart +++ b/refilc_mobile_ui/lib/screens/settings/settings_helper.dart @@ -128,13 +128,34 @@ class SettingsHelper { // } // } - static void fontFamily(BuildContext context) { + static void fontFamily(BuildContext context, + {required Function() showDialog}) { SettingsProvider settings = Provider.of(context, listen: false); showBottomSheetMenu( context, items: List.generate(fontList.length, (index) { + // if (index == fontList.length) { + // return BottomSheetMenuItem( + // onPressed: showDialog, + // title: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // SettingsLocalization('custom').i18n, + // ), + // if (fontList.contains(settings.fontFamily) == false && + // settings.fontFamily != '') + // Icon( + // Icons.check_circle, + // color: Theme.of(context).colorScheme.secondary, + // ), + // ], + // ), + // ); + // } + String font = fontList[index]; return BottomSheetMenuItem( onPressed: () { diff --git a/refilc_mobile_ui/lib/screens/settings/settings_screen.dart b/refilc_mobile_ui/lib/screens/settings/settings_screen.dart index 7bb157d..b2c8f6e 100644 --- a/refilc_mobile_ui/lib/screens/settings/settings_screen.dart +++ b/refilc_mobile_ui/lib/screens/settings/settings_screen.dart @@ -54,6 +54,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_custom_tabs/flutter_custom_tabs.dart' as tabs; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:provider/provider.dart'; +import 'package:shake_flutter/enums/shake_screen.dart'; +import 'package:shake_flutter/shake_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; import 'debug/subject_icon_gallery.dart'; import 'settings_screen.i18n.dart'; @@ -993,7 +995,7 @@ class SettingsScreenState extends State fontWeight: FontWeight.w500, color: AppColors.of(context).text), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(12.0), boxShadow: [ BoxShadow( @@ -1010,7 +1012,7 @@ class SettingsScreenState extends State shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(4.0), - bottom: Radius.circular(12.0), + bottom: Radius.circular(4.0), ), ), secondary: Icon( @@ -1052,6 +1054,23 @@ class SettingsScreenState extends State ), ), ), + PanelButton( + leading: Icon( + Icons.feedback_outlined, + size: 22.0, + color: AppColors.of(context).text.withOpacity(0.95), + ), + title: Text("feedback".i18n), + onPressed: () => { + Shake.setScreenshotIncluded(false), + Shake.show(ShakeScreen.newTicket), + Shake.setScreenshotIncluded(true), + }, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(4.0), + bottom: Radius.circular(12.0), + ), + ), ], ), @@ -1074,6 +1093,15 @@ class SettingsScreenState extends State title: const Text('pushTimetableToCalendar'), onPressed: () async {}, ), + PanelButton( + title: const Text('resetNewBadges'), + onPressed: () async { + Provider.of(context, listen: false) + .update( + unseenNewFeatures: ['grade_exporting'], + ); + }, + ), ], ), // developer options diff --git a/refilc_mobile_ui/lib/screens/settings/settings_screen.i18n.dart b/refilc_mobile_ui/lib/screens/settings/settings_screen.i18n.dart index dff11ea..855cc43 100644 --- a/refilc_mobile_ui/lib/screens/settings/settings_screen.i18n.dart +++ b/refilc_mobile_ui/lib/screens/settings/settings_screen.i18n.dart @@ -5,7 +5,8 @@ extension SettingsLocalization on String { { "en_en": { "heads_up": "Heads up!", - "export_warning": "Exported grades are currently not yet viewable in reFilc, you'll only be able to view them manually in JSON format. In the future, this functionality will be extended and you will be able to view the tickets in the app interface.", + "export_warning": + "Exported grades are currently not yet viewable in reFilc, you'll only be able to view them manually in JSON format. In the future, this functionality will be extended and you will be able to view the tickets in the app interface.", "personal_details": "Personal Details", "open_dkt": "Open DCS", "edit_nickname": "Edit Nickname", @@ -126,10 +127,13 @@ extension SettingsLocalization on String { "new_popups": "New Popups", "export_method": "Export Method", "grade_exporting": "Grade Exporting", + "custom": "Custom", + "feedback": "Feedback", }, "hu_hu": { "heads_up": "Figyelem!", - "export_warning": "Az exportált jegyek jelenleg még nem megtekinthetők a reFilc-ben, csak te magad tudod átnézni őket JSON formátumban. A jövőben ez a funkció bővülni fog, és a jegyeket meg is tekintheted majd a reFilc felületén.", + "export_warning": + "Az exportált jegyek jelenleg még nem megtekinthetők a reFilc-ben, csak te magad tudod átnézni őket JSON formátumban. A jövőben ez a funkció bővülni fog, és a jegyeket meg is tekintheted majd a reFilc felületén.", "personal_details": "Személyes információk", "open_dkt": "DKT megnyitása", "edit_nickname": "Becenév szerkesztése", @@ -250,10 +254,13 @@ extension SettingsLocalization on String { "new_popups": "Új felugró ablakok", "export_method": "Exportálási mód", "grade_exporting": "Jegy exportálás", + "custom": "Egyedi", + "feedback": "Visszajelzés", }, "de_de": { "heads_up": "Achtung!", - "export_warning": "Exportierte Tickets sind derzeit noch nicht in reFilc einsehbar, Sie können sie nur selbst im JSON- Format überprüfen. In Zukunft wird diese Funktionalität erweitert und Sie werden die Tickets in der reFilc-Oberfläche anzeigen können", + "export_warning": + "Exportierte Tickets sind derzeit noch nicht in reFilc einsehbar, Sie können sie nur selbst im JSON- Format überprüfen. In Zukunft wird diese Funktionalität erweitert und Sie werden die Tickets in der reFilc-Oberfläche anzeigen können", "personal_details": "Persönliche Angaben", "open_dkt": "Öffnen RDZ", "edit_nickname": "Spitznamen bearbeiten", @@ -374,6 +381,8 @@ extension SettingsLocalization on String { "new_popups": "Neue Popups", "export_method": "Exportmethode", "grade_exporting": "Noten exportieren", + "custom": "Benutzerdefiniert", + "feedback": "Feedback", }, }; diff --git a/refilc_mobile_ui/lib/screens/settings/submenu/edit_subject.dart b/refilc_mobile_ui/lib/screens/settings/submenu/edit_subject.dart index f5dcc09..a05cc77 100644 --- a/refilc_mobile_ui/lib/screens/settings/submenu/edit_subject.dart +++ b/refilc_mobile_ui/lib/screens/settings/submenu/edit_subject.dart @@ -202,7 +202,7 @@ class EditSubjectScreenState extends State { children: [ Container( decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12.0))), padding: const EdgeInsets.symmetric(vertical: 10.0), @@ -302,7 +302,7 @@ class EditSubjectScreenState extends State { children: [ Container( decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12.0))), padding: const EdgeInsets.symmetric(vertical: 10.0), diff --git a/refilc_mobile_ui/lib/screens/settings/submenu/extras_screen.dart b/refilc_mobile_ui/lib/screens/settings/submenu/extras_screen.dart index 293a59c..c347a75 100644 --- a/refilc_mobile_ui/lib/screens/settings/submenu/extras_screen.dart +++ b/refilc_mobile_ui/lib/screens/settings/submenu/extras_screen.dart @@ -2,6 +2,7 @@ import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/models/settings.dart'; import 'package:refilc/theme/colors/colors.dart'; +import 'package:refilc_mobile_ui/common/chips/new_chip.dart'; import 'package:refilc_mobile_ui/common/panel/panel_button.dart'; import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart'; import 'package:refilc_mobile_ui/screens/settings/settings_helper.dart'; @@ -39,10 +40,20 @@ class MenuExtrasSettings extends StatelessWidget { size: 22.0, color: AppColors.of(context).text.withOpacity(0.95), ), - trailing: Icon( - FeatherIcons.chevronRight, - size: 22.0, - color: AppColors.of(context).text.withOpacity(0.95), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (Provider.of(context) + .unseenNewFeatures + .toSet() + .intersection({'grade_exporting'}).isNotEmpty) + const NewChip(), + Icon( + FeatherIcons.chevronRight, + size: 22.0, + color: AppColors.of(context).text.withOpacity(0.95), + ) + ], ), borderRadius: borderRadius, ); diff --git a/refilc_mobile_ui/lib/screens/settings/submenu/grade_colors.dart b/refilc_mobile_ui/lib/screens/settings/submenu/grade_colors.dart index 50445b3..ec98d95 100644 --- a/refilc_mobile_ui/lib/screens/settings/submenu/grade_colors.dart +++ b/refilc_mobile_ui/lib/screens/settings/submenu/grade_colors.dart @@ -79,7 +79,7 @@ class GradeColorsSettingsScreenState extends State { children: [ Container( decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(75.0), boxShadow: [ BoxShadow( diff --git a/refilc_mobile_ui/lib/screens/settings/submenu/paint_list.dart b/refilc_mobile_ui/lib/screens/settings/submenu/paint_list.dart index 63a7f95..171b6e6 100644 --- a/refilc_mobile_ui/lib/screens/settings/submenu/paint_list.dart +++ b/refilc_mobile_ui/lib/screens/settings/submenu/paint_list.dart @@ -454,7 +454,7 @@ class PaintListScreenState extends State ), Container( decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12.0))), padding: const EdgeInsets.symmetric(vertical: 10.0), diff --git a/refilc_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart b/refilc_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart index 696fa33..d8ea4d9 100644 --- a/refilc_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart +++ b/refilc_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart @@ -79,6 +79,8 @@ class PersonalizeSettingsScreenState extends State late AnimationController _hideContainersController; + final TextEditingController _customFontFamily = TextEditingController(); + late List editedShit; late List otherShit; @@ -840,11 +842,11 @@ class PersonalizeSettingsScreenState extends State scrollbarTheme: ScrollbarThemeData( radius: const Radius.circular(40), thickness: - MaterialStateProperty.all(6.0), + WidgetStateProperty.all(6.0), trackVisibility: - MaterialStateProperty.all(true), + WidgetStateProperty.all(true), thumbVisibility: - MaterialStateProperty.all(true), + WidgetStateProperty.all(true), ), ), customButton: PanelButton( @@ -927,15 +929,94 @@ class PersonalizeSettingsScreenState extends State children: [ PanelButton( onPressed: () { - if (!Provider.of(context, listen: false) - .hasScope(PremiumScopes.customFont)) { - PlusLockedFeaturePopup.show( - context: context, - feature: PremiumFeature.fontChange); - return; - } + // if (!Provider.of(context, listen: false) + // .hasScope(PremiumScopes.customFont)) { + // PlusLockedFeaturePopup.show( + // context: context, + // feature: PremiumFeature.fontChange); + // return; + // } - SettingsHelper.fontFamily(context); + SettingsHelper.fontFamily( + context, + showDialog: () => showDialog( + context: context, + builder: (context) => AlertDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(14.0))), + contentPadding: + const EdgeInsets.only(top: 10.0), + title: Text("custom".i18n), + content: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 24.0, vertical: 10.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: _customFontFamily, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.grey, width: 1.5), + borderRadius: + BorderRadius.circular(12.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.grey, width: 1.5), + borderRadius: + BorderRadius.circular(12.0), + ), + contentPadding: + const EdgeInsets.symmetric( + horizontal: 12.0), + hintText: "ff_name".i18n, + suffixIcon: IconButton( + icon: const Icon( + FeatherIcons.x, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _customFontFamily.text = ""; + }); + }, + ), + ), + ), + ], + ), + ), + actions: [ + TextButton( + child: Text( + "cancel".i18n, + style: const TextStyle( + fontWeight: FontWeight.w500), + ), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + TextButton( + child: Text( + "next".i18n, + style: const TextStyle( + fontWeight: FontWeight.w500), + ), + onPressed: () async { + settingsProvider.update( + fontFamily: _customFontFamily.text); + + Navigator.of(context).pop(true); + }, + ), + ], + ), + ), + ); setState(() {}); }, title: Text( diff --git a/refilc_mobile_ui/lib/screens/settings/theme_screen.dart b/refilc_mobile_ui/lib/screens/settings/theme_screen.dart index 5068d2b..eb7ec85 100644 --- a/refilc_mobile_ui/lib/screens/settings/theme_screen.dart +++ b/refilc_mobile_ui/lib/screens/settings/theme_screen.dart @@ -234,7 +234,7 @@ class _PremiumCustomAccentColorSettingState // bool hasAccess = Provider.of(context) // .hasScope(PremiumScopes.customColors); bool hasAccess = true; - bool isBackgroundDifferent = Theme.of(context).colorScheme.background != + bool isBackgroundDifferent = Theme.of(context).colorScheme.surface != AppColors.of(context).background; ThemeMode currentTheme = Theme.of(context).brightness == Brightness.light @@ -251,8 +251,8 @@ class _PremiumCustomAccentColorSettingState animation: _openAnimController, builder: (context, child) { final backgroundGradientBottomColor = isBackgroundDifferent - ? Theme.of(context).colorScheme.background - : HSVColor.fromColor(Theme.of(context).colorScheme.background) + ? Theme.of(context).colorScheme.surface + : HSVColor.fromColor(Theme.of(context).colorScheme.surface) .withValue(currentTheme == ThemeMode.dark ? 0.1 * _openAnimController.value : 1.0 - (0.1 * _openAnimController.value)) @@ -271,7 +271,7 @@ class _PremiumCustomAccentColorSettingState stops: const [0.0, 0.75], colors: isBackgroundDifferent ? [ - Theme.of(context).colorScheme.background.withOpacity(1 - + Theme.of(context).colorScheme.surface.withOpacity(1 - ((currentTheme == ThemeMode.dark ? 0.65 : 0.25) * backgroundAnimation.value)), backgroundGradientBottomColor, @@ -383,7 +383,7 @@ class _PremiumCustomAccentColorSettingState ], colors: [ settings.customBackgroundColor ?? - Theme.of(context).colorScheme.background, + Theme.of(context).colorScheme.surface, isBackgroundDifferent ? HSVColor.fromColor(Theme.of(context) .colorScheme diff --git a/refilc_mobile_ui/lib/screens/summary/pages/personality_page.dart b/refilc_mobile_ui/lib/screens/summary/pages/personality_page.dart index 2f78b4f..128e918 100644 --- a/refilc_mobile_ui/lib/screens/summary/pages/personality_page.dart +++ b/refilc_mobile_ui/lib/screens/summary/pages/personality_page.dart @@ -96,7 +96,7 @@ class PersonalityBodyState extends State { size: 30, ), style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( + backgroundColor: WidgetStateProperty.all( Colors.white.withOpacity(0.2)), ), ), @@ -113,7 +113,7 @@ class PersonalityBodyState extends State { size: 30, ), style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( + backgroundColor: WidgetStateProperty.all( Colors.white.withOpacity(0.2)), ), ), diff --git a/refilc_mobile_ui/pubspec.yaml b/refilc_mobile_ui/pubspec.yaml index 109ecc6..53f2629 100644 --- a/refilc_mobile_ui/pubspec.yaml +++ b/refilc_mobile_ui/pubspec.yaml @@ -2,7 +2,7 @@ name: refilc_mobile_ui publish_to: "none" environment: - sdk: ">=2.17.0 <=3.3.2" + sdk: ">=3.3.2 <=3.4.3" dependencies: flutter: @@ -21,41 +21,44 @@ dependencies: flutter_feather_icons: ^2.0.0+1 provider: ^6.1.1 - fl_chart: ^0.45.1 + fl_chart: ^0.68.0 url_launcher: ^6.2.5 flutter_material_color_picker: ^1.1.0+2 - photo_view: ^0.14.0 + photo_view: ^0.15.0 flutter_linkify: ^6.0.0 flutter_custom_tabs: ^2.0.0+1 - flutter_markdown: ^0.6.23 + flutter_markdown: ^0.7.2+1 animations: ^2.0.11 animated_list_plus: ^0.5.0 confetti: ^0.7.0 live_activities: ^1.9.1+1 - animated_flip_counter: ^0.2.5 + animated_flip_counter: ^0.3.4 lottie: ^3.1.0 rive: ^0.12.4 animated_background: ^2.0.0 - home_widget: ^0.4.1 + home_widget: + git: + url: https://github.com/refilc/home_widget.git + ref: flutter-beta dropdown_button2: ^2.3.9 flutter_svg: ^2.0.10+1 background_fetch: ^1.2.2 wtf_sliding_sheet: ^1.0.0 - package_info_plus: ^5.0.1 + package_info_plus: ^8.0.0 dotted_border: ^2.0.0+3 - screenshot: ^2.1.0 + screenshot: ^3.0.0 image_gallery_saver: ^2.0.2 rounded_expansion_tile: git: url: https://github.com/kimaah/rounded_expansion_tile.git - go_router: ^13.2.0 + go_router: ^14.2.0 flutter_expandable_fab: ^2.0.0 - intl: ^0.18.1 - i18n_extension: ^11.0.11 + intl: ^0.19.0 + i18n_extension: ^12.0.1 auto_size_text: ^3.0.0 - connectivity_plus: ^5.0.2 + connectivity_plus: ^6.0.3 collection: ^1.18.0 - share_plus: ^7.2.2 + share_plus: ^9.0.0 image_picker: ^1.0.7 path_provider: ^2.1.2 image_crop: @@ -72,10 +75,11 @@ dependencies: carousel_slider: ^4.2.1 flutter_portal: ^1.1.4 webview_flutter: ^4.8.0 - file_picker: ^6.2.1 + file_picker: ^8.0.5 + shake_flutter: ^17.0.0 dev_dependencies: - flutter_lints: ^3.0.1 + flutter_lints: ^4.0.0 flutter: uses-material-design: true diff --git a/refilc_plus b/refilc_plus index c01a024..3207cdc 160000 --- a/refilc_plus +++ b/refilc_plus @@ -1 +1 @@ -Subproject commit c01a0249b9266346d8e812fe026dc933500ceac7 +Subproject commit 3207cdcf6d7e6cd0d2f17851b3597597c14ea4ff