From 96ed4d0b4673e3931b9d92886d08e6ed7897af36 Mon Sep 17 00:00:00 2001 From: Tihanyi Marcell Date: Fri, 3 May 2024 22:40:12 +0200 Subject: [PATCH 01/23] Some iOS updates and Version Bump --- refilc/.gitignore | 30 +++++++++++++++- refilc/build-ipa.sh | 0 refilc/ios/Runner.xcodeproj/project.pbxproj | 36 +++++++++---------- .../xcschemes/xcschememanagement.plist | 2 +- refilc/ios/Runner/Runner.entitlements | 4 +-- refilc/ios/livecard/livecard.entitlements | 4 +-- refilc/pubspec.yaml | 2 +- 7 files changed, 51 insertions(+), 27 deletions(-) mode change 100644 => 100755 refilc/build-ipa.sh diff --git a/refilc/.gitignore b/refilc/.gitignore index f991fd7..4257c18 100644 --- a/refilc/.gitignore +++ b/refilc/.gitignore @@ -46,4 +46,32 @@ app.*.map.json .symlinks/ Pods Podfile.lock -UserInterfaceState.xcuserstate \ No newline at end of file +UserInterfaceState.xcuserstate +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* diff --git a/refilc/build-ipa.sh b/refilc/build-ipa.sh old mode 100644 new mode 100755 diff --git a/refilc/ios/Runner.xcodeproj/project.pbxproj b/refilc/ios/Runner.xcodeproj/project.pbxproj index e4a26c0..2cc04b9 100644 --- a/refilc/ios/Runner.xcodeproj/project.pbxproj +++ b/refilc/ios/Runner.xcodeproj/project.pbxproj @@ -517,8 +517,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 250; - DEVELOPMENT_TEAM = UT7MSP4GWZ; + CURRENT_PROJECT_VERSION = 255; + DEVELOPMENT_TEAM = 4DKAF249F3; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = reFilc; @@ -528,7 +528,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 5.0.0; - PRODUCT_BUNDLE_IDENTIFIER = com.refilcrel.naplo; + PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -549,8 +549,8 @@ CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 250; - DEVELOPMENT_TEAM = UT7MSP4GWZ; + CURRENT_PROJECT_VERSION = 255; + DEVELOPMENT_TEAM = 4DKAF249F3; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = livecard/Info.plist; @@ -566,7 +566,7 @@ MARKETING_VERSION = 5.0.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.refilcrel.naplo.livecardpro; + PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo.livecardpro; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; @@ -591,8 +591,8 @@ CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 250; - DEVELOPMENT_TEAM = UT7MSP4GWZ; + CURRENT_PROJECT_VERSION = 255; + DEVELOPMENT_TEAM = 4DKAF249F3; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = livecard/Info.plist; @@ -607,7 +607,7 @@ ); MARKETING_VERSION = 5.0.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.refilcrel.naplo.livecardpro; + PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo.livecardpro; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; @@ -631,8 +631,8 @@ CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 250; - DEVELOPMENT_TEAM = UT7MSP4GWZ; + CURRENT_PROJECT_VERSION = 255; + DEVELOPMENT_TEAM = 4DKAF249F3; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = livecard/Info.plist; @@ -647,7 +647,7 @@ ); MARKETING_VERSION = 5.0.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.refilcrel.naplo.livecardpro; + PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo.livecardpro; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; @@ -775,8 +775,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 250; - DEVELOPMENT_TEAM = UT7MSP4GWZ; + CURRENT_PROJECT_VERSION = 255; + DEVELOPMENT_TEAM = 4DKAF249F3; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = reFilc; @@ -786,7 +786,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 5.0.0; - PRODUCT_BUNDLE_IDENTIFIER = com.refilcrel.naplo; + PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -803,8 +803,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 250; - DEVELOPMENT_TEAM = UT7MSP4GWZ; + CURRENT_PROJECT_VERSION = 255; + DEVELOPMENT_TEAM = 4DKAF249F3; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = reFilc; @@ -814,7 +814,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 5.0.0; - PRODUCT_BUNDLE_IDENTIFIER = com.refilcrel.naplo; + PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/refilc/ios/Runner.xcodeproj/xcuserdata/tmarccci.xcuserdatad/xcschemes/xcschememanagement.plist b/refilc/ios/Runner.xcodeproj/xcuserdata/tmarccci.xcuserdatad/xcschemes/xcschememanagement.plist index 1c0c029..1970da8 100644 --- a/refilc/ios/Runner.xcodeproj/xcuserdata/tmarccci.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/refilc/ios/Runner.xcodeproj/xcuserdata/tmarccci.xcuserdatad/xcschemes/xcschememanagement.plist @@ -12,7 +12,7 @@ livecard.xcscheme_^#shared#^_ orderHint - 78 + 83 diff --git a/refilc/ios/Runner/Runner.entitlements b/refilc/ios/Runner/Runner.entitlements index 8e1d462..127fede 100644 --- a/refilc/ios/Runner/Runner.entitlements +++ b/refilc/ios/Runner/Runner.entitlements @@ -5,8 +5,6 @@ aps-environment development com.apple.security.application-groups - - group.refilc2.livecard - + diff --git a/refilc/ios/livecard/livecard.entitlements b/refilc/ios/livecard/livecard.entitlements index 8e1d462..127fede 100644 --- a/refilc/ios/livecard/livecard.entitlements +++ b/refilc/ios/livecard/livecard.entitlements @@ -5,8 +5,6 @@ aps-environment development com.apple.security.application-groups - - group.refilc2.livecard - + diff --git a/refilc/pubspec.yaml b/refilc/pubspec.yaml index 39cc8c6..dfc7c68 100644 --- a/refilc/pubspec.yaml +++ b/refilc/pubspec.yaml @@ -3,7 +3,7 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak." homepage: https://refilc.hu publish_to: "none" -version: 5.0.0+253 +version: 5.0.0+255 environment: sdk: ">=2.17.0 <=3.3.2" From 597c50bbf63aaf6391fdbf8766a43e7e15d8372e Mon Sep 17 00:00:00 2001 From: Tihanyi Marcell Date: Fri, 3 May 2024 22:42:11 +0200 Subject: [PATCH 02/23] Prepare for Production --- refilc_mobile_ui/lib/pages/home/home_page.dart | 2 +- .../lib/pages/home/live_card/live_card.dart | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/refilc_mobile_ui/lib/pages/home/home_page.dart b/refilc_mobile_ui/lib/pages/home/home_page.dart index 8939275..8a7218e 100644 --- a/refilc_mobile_ui/lib/pages/home/home_page.dart +++ b/refilc_mobile_ui/lib/pages/home/home_page.dart @@ -214,7 +214,7 @@ class HomePageState extends State with TickerProviderStateMixin { // TODO: REMOVE IN PRODUCTION BUILD!!! // print(_liveCard.currentState); - _liveCard.currentState = LiveCardState.duringLesson; + // _liveCard.currentState = LiveCardState.duringLesson; return Scaffold( body: Stack( 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 3cf6f4b..1d36bd2 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 @@ -71,19 +71,19 @@ class LiveCardStateA extends State { // test // TODO: REMOVE IN PRODUCTION BUILD!!! - liveCard.currentState = LiveCardState.duringLesson; + /*liveCard.currentState = LiveCardState.duringLesson; liveCard.currentLesson = Lesson( - date: DateTime.now().add(Duration( + date: DateTime.now().add(const Duration( minutes: 30, )), subject: GradeSubject( category: Category(id: 'asd'), id: 'asd', name: 'Matematika'), lessonIndex: '1', teacher: Teacher(id: 'id', name: 'name'), - start: DateTime.now().subtract(Duration( + start: DateTime.now().subtract(const Duration( minutes: 30, )), - end: DateTime.now().add(Duration( + end: DateTime.now().add(const Duration( minutes: 15, )), homeworkId: 'homeworkId', @@ -92,7 +92,7 @@ class LiveCardStateA extends State { room: 'ABC69', groupName: 'groupName', name: 'name', - ); + );*/ liveCard.nextLesson = liveCard.currentLesson; From 14df196f340eb3fbd7768e6aefeb69c138756245 Mon Sep 17 00:00:00 2001 From: Tihanyi Marcell <47987707+TMarccci@users.noreply.github.com> Date: Fri, 3 May 2024 23:26:28 +0200 Subject: [PATCH 03/23] Delete refilc/ios/Runner.xcworkspace directory --- .../Runner.xcworkspace/contents.xcworkspacedata | 10 ---------- .../xcshareddata/IDEWorkspaceChecks.plist | 8 -------- .../xcshareddata/WorkspaceSettings.xcsettings | 8 -------- .../UserInterfaceState.xcuserstate | Bin 19987 -> 0 bytes 4 files changed, 26 deletions(-) delete mode 100644 refilc/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 refilc/ios/Runner.xcworkspace/xcuserdata/tmarccci.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/refilc/ios/Runner.xcworkspace/contents.xcworkspacedata b/refilc/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc1..0000000 --- a/refilc/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c..0000000 --- a/refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/refilc/ios/Runner.xcworkspace/xcuserdata/tmarccci.xcuserdatad/UserInterfaceState.xcuserstate b/refilc/ios/Runner.xcworkspace/xcuserdata/tmarccci.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 45ab2005ad4bcc57c7352580d9f5846172813306..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19987 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 Date: Fri, 3 May 2024 23:40:31 +0200 Subject: [PATCH 04/23] Workspace --- refilc/ios/Runner.xcworkspace/contents.xcworkspacedata | 10 ++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++++++++ 3 files changed, 26 insertions(+) create mode 100644 refilc/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/refilc/ios/Runner.xcworkspace/contents.xcworkspacedata b/refilc/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/refilc/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/refilc/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/refilc/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + From 6b99edca9410f1747e6bfd9e177ecb36c6657c7e Mon Sep 17 00:00:00 2001 From: kima Date: Sat, 4 May 2024 11:44:06 +0200 Subject: [PATCH 05/23] added settings for quick things --- refilc/lib/models/settings.dart | 38 ++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/refilc/lib/models/settings.dart b/refilc/lib/models/settings.dart index 04a8ade..ebe191e 100644 --- a/refilc/lib/models/settings.dart +++ b/refilc/lib/models/settings.dart @@ -102,6 +102,10 @@ class SettingsProvider extends ChangeNotifier { bool _navShadow; bool _newColors; bool _uwuMode; + // quick settings + bool _qTimetableLessonNum; + bool _qTimetableSubTiles; + bool _qSubjectsSubTiles; SettingsProvider({ DatabaseProvider? database, @@ -169,6 +173,9 @@ class SettingsProvider extends ChangeNotifier { required bool navShadow, required bool newColors, required bool uwuMode, + required bool qTimetableLessonNum, + required bool qTimetableSubTiles, + required bool qSubjectsSubTiles, }) : _database = database, _language = language, _startPage = startPage, @@ -233,7 +240,10 @@ class SettingsProvider extends ChangeNotifier { _calendarId = calendarId, _navShadow = navShadow, _newColors = newColors, - _uwuMode = uwuMode; + _uwuMode = uwuMode, + _qTimetableLessonNum = qTimetableLessonNum, + _qTimetableSubTiles = qTimetableSubTiles, + _qSubjectsSubTiles = qSubjectsSubTiles; factory SettingsProvider.fromMap(Map map, {required DatabaseProvider database}) { @@ -318,6 +328,9 @@ class SettingsProvider extends ChangeNotifier { navShadow: map['nav_shadow'] == 1, newColors: map['new_colors'] == 1, uwuMode: map['uwu_mode'] == 1, + qTimetableLessonNum: map['q_timetable_lesson_num'] == 1, + qTimetableSubTiles: map['q_timetable_sub_tiles'] == 1, + qSubjectsSubTiles: map['q_subjects_sub_tiles'] == 1, ); } @@ -390,6 +403,9 @@ class SettingsProvider extends ChangeNotifier { "nav_shadow": _navShadow ? 1 : 0, "new_colors": _newColors ? 1 : 0, "uwu_mode": _uwuMode ? 1 : 0, + "q_timetable_lesson_num": _qTimetableLessonNum ? 1 : 0, + "q_timetable_sub_tiles": _qTimetableSubTiles ? 1 : 0, + "q_subjects_sub_tiles": _qSubjectsSubTiles ? 1 : 0, }; } @@ -466,6 +482,9 @@ class SettingsProvider extends ChangeNotifier { navShadow: true, newColors: true, uwuMode: false, + qTimetableLessonNum: false, + qTimetableSubTiles: false, + qSubjectsSubTiles: false, ); } @@ -533,6 +552,9 @@ class SettingsProvider extends ChangeNotifier { bool get navShadow => _navShadow; bool get newColors => _newColors; bool get uwuMode => _uwuMode; + bool get qTimetableLessonNum => _qTimetableLessonNum; + bool get qTimetableSubTiles => _qTimetableSubTiles; + bool get qSubjectsSubTiles => _qSubjectsSubTiles; Future update({ bool store = true, @@ -596,6 +618,9 @@ class SettingsProvider extends ChangeNotifier { bool? navShadow, bool? newColors, bool? uwuMode, + bool? qTimetableLessonNum, + bool? qTimetableSubTiles, + bool? qSubjectsSubTiles, }) async { if (language != null && language != _language) _language = language; if (startPage != null && startPage != _startPage) _startPage = startPage; @@ -775,6 +800,17 @@ class SettingsProvider extends ChangeNotifier { if (uwuMode != null && uwuMode != _uwuMode) { _uwuMode = uwuMode; } + if (qTimetableLessonNum != null && + qTimetableLessonNum != _qTimetableLessonNum) { + _qTimetableLessonNum = qTimetableLessonNum; + } + if (qTimetableSubTiles != null && + qTimetableSubTiles != _qTimetableSubTiles) { + _qTimetableSubTiles = qTimetableSubTiles; + } + if (qSubjectsSubTiles != null && qSubjectsSubTiles != _qSubjectsSubTiles) { + _qSubjectsSubTiles = qSubjectsSubTiles; + } // store or not if (store) await _database?.store.storeSettings(this); notifyListeners(); From 7edde06c11f33cdb46f44e5c1248b2afae5abeb3 Mon Sep 17 00:00:00 2001 From: Kima Date: Sat, 4 May 2024 17:59:38 +0200 Subject: [PATCH 06/23] wha? --- refilc_plus | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/refilc_plus b/refilc_plus index 574d3ab..0d44954 160000 --- a/refilc_plus +++ b/refilc_plus @@ -1 +1 @@ -Subproject commit 574d3ab0aca1bb68d21607c2b9df1046aa46fc55 +Subproject commit 0d44954164c95333a9d538b0f1b9fefd6e38c842 From 6b8708e1e3ca63d5d8035837a0975190c3296a5f Mon Sep 17 00:00:00 2001 From: Kima Date: Sat, 4 May 2024 18:18:57 +0200 Subject: [PATCH 07/23] progress in quick settings --- refilc/lib/database/init.dart | 3 + .../lib/pages/timetable/timetable_page.dart | 60 ++++++++++++++++++- refilc_plus | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/refilc/lib/database/init.dart b/refilc/lib/database/init.dart index d06a600..23960a9 100644 --- a/refilc/lib/database/init.dart +++ b/refilc/lib/database/init.dart @@ -52,6 +52,9 @@ const settingsDB = DatabaseStruct("settings", { "nav_shadow": int, "new_colors": int, "uwu_mode": int, + // quick settings + "q_timetable_lesson_num": int, "q_timetable_sub_tiles": int, + "q_subjects_sub_tiles": int, }); // DON'T FORGET TO UPDATE DEFAULT VALUES IN `initDB` MIGRATION OR ELSE PARENTS WILL COMPLAIN ABOUT THEIR CHILDREN MISSING // YOU'VE BEEN WARNED!!! diff --git a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart index f4bb86b..da4976b 100644 --- a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart +++ b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart @@ -12,6 +12,8 @@ import 'package:refilc_kreta_api/providers/timetable_provider.dart'; import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu_item.dart'; import 'package:refilc_mobile_ui/common/dot.dart'; import 'package:refilc_mobile_ui/common/empty.dart'; import 'package:refilc_mobile_ui/common/profile_image/profile_button.dart'; @@ -234,7 +236,7 @@ class TimetablePageState extends State surfaceTintColor: Theme.of(context).scaffoldBackgroundColor, actions: [ Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.only(top: 8.0, bottom: 8.0), child: IconButton( splashRadius: 24.0, // tested timetable sync @@ -274,6 +276,30 @@ class TimetablePageState extends State ), ), + Padding( + padding: const EdgeInsets.only( + right: 8.0, + bottom: 8.0, + top: 8.0, + ), + child: IconButton( + splashRadius: 24.0, + // tested timetable sync + // onPressed: () async { + // ThirdPartyProvider tpp = + // Provider.of(context, + // listen: false); + + // await tpp.pushTimetable(context, _controller); + // }, + onPressed: () { + showQuickOptions(context); + }, + icon: Icon(FeatherIcons.menu, + color: AppColors.of(context).text), + ), + ), + // Profile Icon Padding( padding: const EdgeInsets.only(right: 24.0), @@ -817,6 +843,38 @@ class TimetablePageState extends State ), ); } + + void showQuickOptions(BuildContext context) { + showBottomSheetMenu( + context, + items: [ + SwitchListTile( + title: Text( + 'show_lesson_num'.i18n, + ), + value: settingsProvider.qTimetableLessonNum, + onChanged: (v) { + settingsProvider.update(qTimetableLessonNum: v); + setState(() {}); + + Navigator.of(context).maybePop(); + }, + ), + SwitchListTile( + title: Text( + 'show_exams_and_homework'.i18n, + ), + value: settingsProvider.qTimetableSubTiles, + onChanged: (v) { + settingsProvider.update(qTimetableSubTiles: v); + setState(() {}); + + Navigator.of(context).maybePop(); + }, + ), + ], + ); + } } // difference.inDays is not reliable diff --git a/refilc_plus b/refilc_plus index 0d44954..1f5cca7 160000 --- a/refilc_plus +++ b/refilc_plus @@ -1 +1 @@ -Subproject commit 0d44954164c95333a9d538b0f1b9fefd6e38c842 +Subproject commit 1f5cca7b8e2ac896155a6c494e79fb057628379e From 3b1e345f14fc9b794cc5bd27294cf6233ca01167 Mon Sep 17 00:00:00 2001 From: Kima Date: Sat, 4 May 2024 22:11:29 +0200 Subject: [PATCH 08/23] omfg really sok progress --- refilc/lib/models/settings.dart | 8 +- refilc/lib/theme/colors/accent.dart | 63 +++++ refilc/lib/theme/colors/new_colors.dart | 73 +++++ refilc/lib/theme/theme.dart | 29 ++ refilc/lib/ui/widgets/lesson/lesson_tile.dart | 1 + refilc/lib/utils/reverse_search.dart | 23 ++ .../rounded_bottom_sheet.dart | 6 +- .../widgets/grade/grade_subject_tile.dart | 14 +- .../widgets/lesson/lesson_viewable.dart | 235 +++++++++++----- .../lib/pages/grades/grades_page.dart | 123 ++++++++- .../lib/pages/grades/grades_page.i18n.dart | 6 + .../lib/pages/timetable/timetable_page.dart | 256 +++++++++++++----- .../pages/timetable/timetable_page.i18n.dart | 9 + .../lib/screens/settings/settings_helper.dart | 4 +- 14 files changed, 689 insertions(+), 161 deletions(-) create mode 100644 refilc/lib/theme/colors/new_colors.dart diff --git a/refilc/lib/models/settings.dart b/refilc/lib/models/settings.dart index 9cea67f..72d23f1 100644 --- a/refilc/lib/models/settings.dart +++ b/refilc/lib/models/settings.dart @@ -485,9 +485,9 @@ class SettingsProvider extends ChangeNotifier { navShadow: true, newColors: true, uwuMode: false, - qTimetableLessonNum: false, - qTimetableSubTiles: false, - qSubjectsSubTiles: false, + qTimetableLessonNum: true, + qTimetableSubTiles: true, + qSubjectsSubTiles: true, ); } @@ -694,7 +694,7 @@ class SettingsProvider extends ChangeNotifier { if (bellDelay != null && bellDelay != _bellDelay) _bellDelay = bellDelay; if (bellDelayEnabled != null && bellDelayEnabled != _bellDelayEnabled) { _bellDelayEnabled = bellDelayEnabled; - if(Platform.isIOS){ + if (Platform.isIOS) { LiveCardProvider.hasActivitySettingsChanged = true; } } diff --git a/refilc/lib/theme/colors/accent.dart b/refilc/lib/theme/colors/accent.dart index 152046a..df27bc0 100644 --- a/refilc/lib/theme/colors/accent.dart +++ b/refilc/lib/theme/colors/accent.dart @@ -31,3 +31,66 @@ Map accentColorMap = { AccentColor.adaptive: const Color(0xFF3D7BF4), AccentColor.custom: const Color(0xFF3D7BF4), }; + +// new v5 things +Map lightPrimary = { + AccentColor.filc: const Color(0xFF050B15), +}; +Map lightSecondary = { + AccentColor.filc: const Color(0xFF3F444F), +}; +Map lightTeritary = { + AccentColor.filc: const Color(0xFF1C469A), +}; +Map lightIcon = { + AccentColor.filc: const Color(0xFF0A2456), +}; +Map lightAccent = { + AccentColor.filc: const Color(0xFF487DE6), +}; +Map lightBgDarkened = { + AccentColor.filc: const Color(0xFFB9C8E5), +}; +Map lightBtnSecStrk = { + AccentColor.filc: const Color(0xFFCEDBF5), +}; +Map lightBg = { + AccentColor.filc: const Color(0xFFDAE4F7), +}; +Map lightCard = { + AccentColor.filc: const Color(0xFFEDF3FF), +}; +Map lightBtnSec = { + AccentColor.filc: const Color(0xFFFBFCFF), +}; + +Map darkPrimary = { + AccentColor.filc: const Color(0xFFEBF1FD), +}; +Map darkSecondary = { + AccentColor.filc: const Color(0xFFCFD8E9), +}; +Map darkTeritary = { + AccentColor.filc: const Color(0xFFAEC8FC), +}; +Map darkIcon = { + AccentColor.filc: const Color(0xFFBAD1FF), +}; +Map darkAccent = { + AccentColor.filc: const Color(0xFF487DE6), +}; +Map darkBgDarkened = { + AccentColor.filc: const Color(0xFF010205), +}; +Map darkBtnSecStrk = { + AccentColor.filc: const Color(0xFF1C2230), +}; +Map darkBg = { + AccentColor.filc: const Color(0xFF070A0E), +}; +Map darkCard = { + AccentColor.filc: const Color(0xFF0F131B), +}; +Map darkBtnSec = { + AccentColor.filc: const Color(0xFF131822), +}; diff --git a/refilc/lib/theme/colors/new_colors.dart b/refilc/lib/theme/colors/new_colors.dart new file mode 100644 index 0000000..aa7f080 --- /dev/null +++ b/refilc/lib/theme/colors/new_colors.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; + +class NewColors extends ThemeExtension { + const NewColors({ + required this.accent, + required this.primary, + required this.secondary, + required this.teritary, + required this.icon, + required this.darkenBg, + required this.btnSecStrk, + required this.background, + required this.card, + required this.btnSec, + }); + + final Color? accent; + final Color? primary; + final Color? secondary; + final Color? teritary; + final Color? icon; + final Color? darkenBg; + final Color? btnSecStrk; + final Color? background; + final Color? card; + final Color? btnSec; + + @override + NewColors copyWith({ + Color? accent, + Color? primary, + Color? secondary, + Color? teritary, + Color? icon, + Color? darkenBg, + Color? btnSecStrk, + Color? background, + Color? card, + Color? btnSec, + }) { + return NewColors( + accent: accent ?? this.accent, + primary: primary ?? this.primary, + secondary: secondary ?? this.secondary, + teritary: teritary ?? this.teritary, + icon: icon ?? this.icon, + darkenBg: darkenBg ?? this.darkenBg, + btnSecStrk: btnSecStrk ?? this.btnSecStrk, + background: background ?? this.background, + card: card ?? this.card, + btnSec: btnSec ?? this.btnSec, + ); + } + + @override + NewColors lerp(NewColors? other, double t) { + if (other is! NewColors) { + return this; + } + return NewColors( + accent: Color.lerp(accent, other.accent, t), + primary: Color.lerp(primary, other.primary, t), + secondary: Color.lerp(secondary, other.secondary, t), + teritary: Color.lerp(teritary, other.teritary, t), + icon: Color.lerp(icon, other.icon, t), + darkenBg: Color.lerp(darkenBg, other.darkenBg, t), + btnSecStrk: Color.lerp(btnSecStrk, other.btnSecStrk, t), + background: Color.lerp(background, other.background, t), + card: Color.lerp(card, other.card, t), + btnSec: Color.lerp(btnSec, other.btnSec, t), + ); + } +} diff --git a/refilc/lib/theme/theme.dart b/refilc/lib/theme/theme.dart index 1acae12..8b4594b 100644 --- a/refilc/lib/theme/theme.dart +++ b/refilc/lib/theme/theme.dart @@ -1,6 +1,7 @@ import 'package:refilc/models/settings.dart'; import 'package:refilc/theme/colors/accent.dart'; import 'package:refilc/theme/colors/colors.dart'; +import 'package:refilc/theme/colors/new_colors.dart'; import 'package:refilc/theme/colors/utils.dart'; import 'package:refilc/theme/observer.dart'; import 'package:flutter/material.dart'; @@ -87,6 +88,20 @@ class AppTheme { amount: 0.4); // white mode: same tertiary as secondary return ThemeData( + // extensions: [ + // NewColors( + // accent: lightAccent[accentColor]!, + // primary: lightPrimary[accentColor]!, + // secondary: lightSecondary[accentColor]!, + // teritary: lightTeritary[accentColor]!, + // icon: lightIcon[accentColor]!, + // darkenBg: lightBgDarkened[accentColor]!, + // btnSecStrk: lightBtnSecStrk[accentColor]!, + // background: lightBg[accentColor]!, + // card: lightCard[accentColor]!, + // btnSec: lightBtnSec[accentColor]!, + // ), + // ], brightness: Brightness.light, useMaterial3: true, fontFamily: _defaultFontFamily, @@ -198,6 +213,20 @@ class AppTheme { amount: 0.1); // dark mode: tertiary is way darker than secondary return ThemeData( + // extensions: [ + // NewColors( + // accent: darkAccent[accentColor]!, + // primary: darkPrimary[accentColor]!, + // secondary: darkSecondary[accentColor]!, + // teritary: darkTeritary[accentColor]!, + // icon: darkIcon[accentColor]!, + // darkenBg: darkBgDarkened[accentColor]!, + // btnSecStrk: darkBtnSecStrk[accentColor]!, + // background: darkBg[accentColor]!, + // card: darkCard[accentColor]!, + // btnSec: darkBtnSec[accentColor]!, + // ), + // ], brightness: Brightness.dark, useMaterial3: true, fontFamily: _defaultFontFamily, diff --git a/refilc/lib/ui/widgets/lesson/lesson_tile.dart b/refilc/lib/ui/widgets/lesson/lesson_tile.dart index f2041da..de1cde1 100644 --- a/refilc/lib/ui/widgets/lesson/lesson_tile.dart +++ b/refilc/lib/ui/widgets/lesson/lesson_tile.dart @@ -1,4 +1,5 @@ import 'package:refilc/models/settings.dart'; +import 'package:refilc/theme/colors/new_colors.dart'; import 'package:refilc_kreta_api/providers/exam_provider.dart'; import 'package:refilc_kreta_api/providers/homework_provider.dart'; import 'package:refilc/theme/colors/colors.dart'; diff --git a/refilc/lib/utils/reverse_search.dart b/refilc/lib/utils/reverse_search.dart index 35e3425..f2b3301 100644 --- a/refilc/lib/utils/reverse_search.dart +++ b/refilc/lib/utils/reverse_search.dart @@ -1,8 +1,12 @@ import 'dart:developer'; +import 'package:googleapis/privateca/v1.dart'; import 'package:refilc_kreta_api/models/absence.dart'; +import 'package:refilc_kreta_api/models/category.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; +import 'package:refilc_kreta_api/models/subject.dart'; import 'package:refilc_kreta_api/models/week.dart'; +import 'package:refilc_kreta_api/providers/grade_provider.dart'; import 'package:refilc_kreta_api/providers/timetable_provider.dart'; import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; @@ -41,4 +45,23 @@ class ReverseSearch { // difference.inDays is not reliable static bool _sameDate(DateTime a, DateTime b) => (a.year == b.year && a.month == b.month && a.day == b.day); + + static Future getSubjectByLesson( + Lesson lesson, BuildContext context) async { + final gradeProvider = Provider.of(context, listen: false); + + try { + await gradeProvider.fetch(); + } catch (e) { + log("[ERROR] getSubjectByLesson: $e"); + } + + try { + return gradeProvider.grades.map((e) => e.subject).firstWhere( + (s) => s.id == lesson.subject.id, + ); + } catch (e) { + return null; + } + } } 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 7bb4977..9a64aa2 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 @@ -8,19 +8,21 @@ class RoundedBottomSheet extends StatelessWidget { this.borderRadius = 16.0, this.shrink = true, this.showHandle = true, + this.backgroundColor, }); final Widget? child; final double borderRadius; final bool shrink; final bool showHandle; + final Color? backgroundColor; @override Widget build(BuildContext context) { return AnimatedContainer( duration: const Duration(milliseconds: 500), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: backgroundColor ?? Theme.of(context).colorScheme.background, borderRadius: BorderRadius.only( topLeft: Radius.circular(borderRadius), topRight: Radius.circular(borderRadius), @@ -52,6 +54,7 @@ Future showRoundedModalBottomSheet( required Widget child, bool rootNavigator = true, bool showHandle = true, + Color? backgroundColor, }) async { return await showModalBottomSheet( useSafeArea: false, @@ -62,6 +65,7 @@ Future showRoundedModalBottomSheet( useRootNavigator: rootNavigator, isScrollControlled: true, builder: (context) => RoundedBottomSheet( + backgroundColor: backgroundColor, showHandle: showHandle, child: child, ), diff --git a/refilc_mobile_ui/lib/common/widgets/grade/grade_subject_tile.dart b/refilc_mobile_ui/lib/common/widgets/grade/grade_subject_tile.dart index 17e624c..894ac41 100644 --- a/refilc_mobile_ui/lib/common/widgets/grade/grade_subject_tile.dart +++ b/refilc_mobile_ui/lib/common/widgets/grade/grade_subject_tile.dart @@ -9,12 +9,14 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class GradeSubjectTile extends StatelessWidget { - const GradeSubjectTile(this.subject, - {super.key, - this.average = 0.0, - this.groupAverage = 0.0, - this.onTap, - this.averageBefore = 0.0}); + const GradeSubjectTile( + this.subject, { + super.key, + this.average = 0.0, + this.groupAverage = 0.0, + this.onTap, + this.averageBefore = 0.0, + }); final GradeSubject subject; final void Function()? onTap; 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 1cca668..8b4f391 100644 --- a/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart @@ -1,13 +1,16 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:refilc/api/providers/database_provider.dart'; import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/helpers/subject.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc/theme/colors/utils.dart'; +import 'package:refilc/utils/reverse_search.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; +import 'package:refilc_mobile_ui/common/custom_snack_bar.dart'; import 'package:refilc_mobile_ui/common/panel/panel_button.dart'; import 'package:refilc_mobile_ui/common/round_border_icon.dart'; import 'package:refilc_mobile_ui/common/viewable.dart'; @@ -15,18 +18,25 @@ import 'package:refilc_mobile_ui/common/widgets/card_handle.dart'; import 'package:refilc/ui/widgets/lesson/lesson_tile.dart'; import 'package:refilc_mobile_ui/common/widgets/lesson/lesson_view.dart'; import 'package:flutter/material.dart'; +import 'package:refilc_mobile_ui/pages/grades/grades_page.dart'; import 'package:refilc_plus/models/premium_scopes.dart'; import 'package:refilc_plus/providers/plus_provider.dart'; import 'package:refilc_plus/ui/mobile/plus/upsell.dart'; import 'lesson_view.i18n.dart'; class LessonViewable extends StatefulWidget { - const LessonViewable(this.lesson, - {super.key, this.swapDesc = false, required this.customDesc}); + const LessonViewable( + this.lesson, { + super.key, + this.swapDesc = false, + required this.customDesc, + this.showSubTiles = true, + }); final Lesson lesson; final bool swapDesc; final String customDesc; + final bool showSubTiles; @override State createState() => LessonViewableState(); @@ -51,14 +61,28 @@ class LessonViewableState extends State { Lesson lsn = widget.lesson; lsn.description = widget.customDesc; - final tile = LessonTile(lsn, swapDesc: widget.swapDesc); + final tile = LessonTile( + lsn, + swapDesc: widget.swapDesc, + showSubTiles: widget.showSubTiles, + ); if (lsn.subject.id == '' || tile.lesson.isEmpty) return tile; - return LessonTile( - lsn, - swapDesc: widget.swapDesc, - onTap: () => TimetableLessonPopup.show(context: context, lesson: lsn), + return GestureDetector( + onTap: () => TimetableLessonPopup.show( + context: context, + lesson: lsn, + ), + child: LessonTile( + lsn, + swapDesc: widget.swapDesc, + showSubTiles: widget.showSubTiles, + // onTap: () => TimetableLessonPopup.show( + // context: context, + // lesson: lsn, + // ), + ), ); // return Viewable( @@ -232,9 +256,14 @@ class LessonViewableState extends State { } class TimetableLessonPopup extends StatelessWidget { - const TimetableLessonPopup({super.key, required this.lesson}); + const TimetableLessonPopup({ + super.key, + required this.lesson, + required this.outsideContext, + }); final Lesson lesson; + final BuildContext outsideContext; static void show({ required BuildContext context, @@ -244,6 +273,7 @@ class TimetableLessonPopup extends StatelessWidget { context, child: TimetableLessonPopup( lesson: lesson, + outsideContext: context, ), showHandle: false, ); @@ -272,13 +302,42 @@ class TimetableLessonPopup extends StatelessWidget { ), child: Stack( children: [ - SvgPicture.asset( - "assets/svg/mesh_bg.svg", - // ignore: deprecated_member_use - color: ColorsUtils().fade( - context, Theme.of(context).scaffoldBackgroundColor, - darkenAmount: 0.1, lightenAmount: 0.1), - width: MediaQuery.of(context).size.width, + Stack( + children: [ + SvgPicture.asset( + "assets/svg/mesh_bg.svg", + // ignore: deprecated_member_use + color: ColorsUtils() + .fade(context, Theme.of(context).colorScheme.secondary, + darkenAmount: 0.1, lightenAmount: 0.1) + .withOpacity(0.33), + width: MediaQuery.of(context).size.width, + ), + Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12.0), + ), + gradient: LinearGradient( + colors: [ + Theme.of(context).scaffoldBackgroundColor, + Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.1), + Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.1), + Theme.of(context).scaffoldBackgroundColor, + ], + stops: const [0.1, 0.5, 0.7, 1.0], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + width: MediaQuery.of(context).size.width, + height: 175.0, + ), + ], ), SizedBox( width: MediaQuery.of(context).size.width, @@ -291,9 +350,11 @@ class TimetableLessonPopup extends StatelessWidget { width: 40, height: 4, decoration: BoxDecoration( - color: ColorsUtils().fade( - context, Theme.of(context).scaffoldBackgroundColor, - darkenAmount: 0.2, lightenAmount: 0.2), + color: ColorsUtils() + .fade( + context, Theme.of(context).colorScheme.secondary, + darkenAmount: 0.1, lightenAmount: 0.1) + .withOpacity(0.33), borderRadius: BorderRadius.circular( 2.0, ), @@ -302,10 +363,31 @@ class TimetableLessonPopup extends StatelessWidget { const SizedBox( height: 38.0, ), - RoundBorderIcon( - icon: Icon( - SubjectIcon.resolveVariant( - context: context, subject: lesson.subject), + Container( + decoration: BoxDecoration( + color: Theme.of(context).scaffoldBackgroundColor, + borderRadius: BorderRadius.circular(50.0), + ), + child: RoundBorderIcon( + color: ColorsUtils() + .darken( + Theme.of(context).colorScheme.secondary, + amount: 0.1, + ) + .withOpacity(0.9), + width: 1.5, + padding: 10.0, + icon: Icon( + SubjectIcon.resolveVariant( + context: context, subject: lesson.subject), + size: 32.0, + color: ColorsUtils() + .darken( + Theme.of(context).colorScheme.secondary, + amount: 0.1, + ) + .withOpacity(0.8), + ), ), ), const SizedBox( @@ -315,9 +397,11 @@ class TimetableLessonPopup extends StatelessWidget { width: double.infinity, decoration: BoxDecoration( color: Theme.of(context).colorScheme.background, - borderRadius: const BorderRadius.vertical( - top: Radius.circular(12.0), - bottom: Radius.circular(6.0), + borderRadius: BorderRadius.vertical( + top: const Radius.circular(12.0), + bottom: (lesson.description.replaceAll(' ', '') != '') + ? const Radius.circular(6.0) + : const Radius.circular(12.0), ), ), padding: const EdgeInsets.all(14.0), @@ -325,7 +409,7 @@ class TimetableLessonPopup extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '6:09 - 4:20', + '${DateFormat('H:mm').format(lesson.start)} - ${DateFormat('H:mm').format(lesson.end)}', style: TextStyle( color: AppColors.of(context).text.withOpacity(0.85), fontSize: 14.0, @@ -357,64 +441,79 @@ class TimetableLessonPopup extends StatelessWidget { ], ), ), - const SizedBox( - height: 6.0, - ), - Container( - width: double.infinity, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, - borderRadius: const BorderRadius.vertical( - top: Radius.circular(6.0), - bottom: Radius.circular(12.0), - ), + if (lesson.description.replaceAll(' ', '') != '') + const SizedBox( + height: 6.0, ), - padding: const EdgeInsets.all(14.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - lesson.description, - style: TextStyle( - color: AppColors.of(context).text.withOpacity(0.9), - fontSize: 14.0, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ), - const SizedBox( - height: 24.0, - ), - GestureDetector( - onTap: () { - Navigator.of(context, rootNavigator: true) - .pushReplacementNamed('/'); - }, - child: Container( + if (lesson.description.replaceAll(' ', '') != '') + Container( width: double.infinity, decoration: BoxDecoration( color: Theme.of(context).colorScheme.background, - borderRadius: BorderRadius.circular(12.0), + borderRadius: const BorderRadius.vertical( + top: Radius.circular(6.0), + bottom: Radius.circular(12.0), + ), ), - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.all(14.0), child: Column( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'view_subject'.i18n, + lesson.description, style: TextStyle( color: AppColors.of(context).text.withOpacity(0.9), - fontSize: 18.0, - fontWeight: FontWeight.w500, + fontSize: 14.0, + fontWeight: FontWeight.w600, ), ), ], ), ), - ), + // const SizedBox( + // height: 24.0, + // ), + // GestureDetector( + // onTap: () async { + // ReverseSearch.getSubjectByLesson(lesson, context) + // .then((subject) { + // if (subject != null) { + // GradesPage.jump(outsideContext, subject: subject); + // } else { + // ScaffoldMessenger.of(context) + // .showSnackBar(CustomSnackBar( + // content: Text("Cannot find subject".i18n, + // style: const TextStyle(color: Colors.white)), + // backgroundColor: AppColors.of(context).red, + // context: context, + // )); + // } + // }); + // }, + // child: Container( + // width: double.infinity, + // decoration: BoxDecoration( + // color: Theme.of(context).colorScheme.background, + // borderRadius: BorderRadius.circular(12.0), + // ), + // padding: const EdgeInsets.all(16.0), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Text( + // 'view_subject'.i18n, + // style: TextStyle( + // color: + // AppColors.of(context).text.withOpacity(0.9), + // fontSize: 18.0, + // fontWeight: FontWeight.w500, + // ), + // ), + // ], + // ), + // ), + // ), ], ), ), diff --git a/refilc_mobile_ui/lib/pages/grades/grades_page.dart b/refilc_mobile_ui/lib/pages/grades/grades_page.dart index 88f1030..3d18708 100644 --- a/refilc_mobile_ui/lib/pages/grades/grades_page.dart +++ b/refilc_mobile_ui/lib/pages/grades/grades_page.dart @@ -19,6 +19,7 @@ import 'package:refilc_kreta_api/models/subject.dart'; import 'package:refilc_kreta_api/models/group_average.dart'; import 'package:refilc_kreta_api/providers/homework_provider.dart'; import 'package:refilc_mobile_ui/common/average_display.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; import 'package:refilc_mobile_ui/common/empty.dart'; import 'package:refilc_mobile_ui/common/panel/panel.dart'; @@ -32,6 +33,9 @@ import 'package:refilc_mobile_ui/pages/grades/fail_warning.dart'; import 'package:refilc_mobile_ui/pages/grades/grades_count.dart'; import 'package:refilc_mobile_ui/pages/grades/graph.dart'; import 'package:refilc_mobile_ui/pages/grades/grade_subject_view.dart'; +import 'package:refilc_mobile_ui/pages/timetable/timetable_page.dart'; +import 'package:refilc_mobile_ui/screens/navigation/navigation_route_handler.dart'; +import 'package:refilc_mobile_ui/screens/navigation/navigation_screen.dart'; import 'package:refilc_plus/models/premium_scopes.dart'; import 'package:refilc_plus/providers/plus_provider.dart'; import 'package:flutter/material.dart'; @@ -48,6 +52,19 @@ import 'grades_page.i18n.dart'; class GradesPage extends StatefulWidget { const GradesPage({super.key}); + static void jump(BuildContext context, {GradeSubject? subject}) { + // Go to timetable page with arguments + NavigationScreen.of(context) + ?.customRoute(navigationPageRoute((context) => const GradesPage())); + + NavigationScreen.of(context)?.setPage("grades"); + + // Show initial Lesson + if (subject != null) { + GradeSubjectView(subject, groupAverage: 0.0).push(context, root: true); + } + } + @override GradesPageState createState() => GradesPageState(); } @@ -147,7 +164,8 @@ class GradesPageState extends State { Exam? nearestExam = allExams.firstWhereOrNull((e) => e.subject.id == subject.id && e.writeDate.isAfter(DateTime.now())); - bool hasUnder = hasHomework || nearestExam != null; + bool hasUnder = (hasHomework || nearestExam != null) && + Provider.of(context).qSubjectsSubTiles; return Padding( padding: i > 1 ? const EdgeInsets.only(top: 9.0) : EdgeInsets.zero, @@ -201,7 +219,8 @@ class GradesPageState extends State { const SizedBox( height: 6.0, ), - if (hasHomework) + if (hasHomework && + Provider.of(context).qSubjectsSubTiles) Container( decoration: BoxDecoration( boxShadow: [ @@ -249,7 +268,8 @@ class GradesPageState extends State { ), ), ), - if (nearestExam != null) + if (nearestExam != null && + Provider.of(context).qSubjectsSubTiles) Container( decoration: BoxDecoration( boxShadow: [ @@ -519,19 +539,10 @@ class GradesPageState extends State { child: IconButton( splashRadius: 24.0, onPressed: () { - if (!Provider.of(context, listen: false) - .hasScope(PremiumScopes.totalGradeCalculator)) { - PlusLockedFeaturePopup.show( - context: context, - feature: PremiumFeature.gradeCalculation); - return; - } - - // SoonAlert.show(context: context); - gradeCalcTotal(context); + showQuickSettings(context); }, icon: Icon( - FeatherIcons.plus, + FeatherIcons.moreHorizontal, color: AppColors.of(context).text, ), ), @@ -627,4 +638,88 @@ class GradesPageState extends State { } }); } + + void showQuickSettings(BuildContext context) { + // _sheetController = _scaffoldKey.currentState?.showBottomSheet( + // (context) => RoundedBottomSheet( + // borderRadius: 14.0, + // child: BottomSheetMenu(items: [ + // SwitchListTile( + // title: Text('show_lesson_num'.i18n), + // value: + // Provider.of(context).qTimetableLessonNum, + // onChanged: (v) { + // Provider.of(context, listen: false) + // .update(qTimetableLessonNum: v); + // }) + // ])), + // backgroundColor: const Color(0x00000000), + // elevation: 12.0, + // ); + + // _sheetController!.closed.then((value) { + // // Show fab and grades + // if (mounted) {} + // }); + showRoundedModalBottomSheet( + context, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + child: BottomSheetMenu(items: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: ListTile( + title: Row( + children: [ + const Icon(FeatherIcons.plusCircle), + const SizedBox( + width: 10.0, + ), + Text('grade_calc'.i18n), + ], + ), + onTap: () { + if (!Provider.of(context, listen: false) + .hasScope(PremiumScopes.totalGradeCalculator)) { + PlusLockedFeaturePopup.show( + context: context, feature: PremiumFeature.gradeCalculation); + return; + } + + // SoonAlert.show(context: context); + gradeCalcTotal(context); + }, + ), + ), + const SizedBox( + height: 10.0, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: SwitchListTile( + title: Row( + children: [ + const Icon(Icons.edit_document), + const SizedBox( + width: 10.0, + ), + Text('show_exams_homework'.i18n), + ], + ), + value: Provider.of(context, listen: false) + .qSubjectsSubTiles, + onChanged: (v) { + Provider.of(context, listen: false) + .update(qSubjectsSubTiles: v); + + Navigator.of(context, rootNavigator: true).pop(); + }, + ), + ), + ]), + ); + } } diff --git a/refilc_mobile_ui/lib/pages/grades/grades_page.i18n.dart b/refilc_mobile_ui/lib/pages/grades/grades_page.i18n.dart index 1985e34..59eee56 100644 --- a/refilc_mobile_ui/lib/pages/grades/grades_page.i18n.dart +++ b/refilc_mobile_ui/lib/pages/grades/grades_page.i18n.dart @@ -27,6 +27,8 @@ extension Localization on String { "exams": "Exams", "timetable": "Timetable", "grades": "Grades", + "show_exams_homework": "Exams and Homework", + "grade_calc": "Grade Calculator", }, "hu_hu": { "Grades": "Tantárgyak", @@ -51,6 +53,8 @@ extension Localization on String { "exams": "Számonkérések", "timetable": "Órarend", "grades": "Jegyek", + "show_exams_homework": "Dolgozatok és házik", + "grade_calc": "Jegy kalkulátor", }, "de_de": { "Grades": "Fächer", @@ -75,6 +79,8 @@ extension Localization on String { "exams": "Prüfungen", "timetable": "Stundenplan", "grades": "Noten", + "show_exams_homework": "Referate und Hausaufgaben", + "grade_calc": "Noten-Rechner", }, }; diff --git a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart index da4976b..f31fbb4 100644 --- a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart +++ b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart @@ -1,5 +1,6 @@ import 'dart:math'; import 'package:animations/animations.dart'; +import 'package:flutter/widgets.dart'; import 'package:i18n_extension/i18n_extension.dart'; import 'package:refilc/api/providers/database_provider.dart'; import 'package:refilc/api/providers/update_provider.dart'; @@ -14,6 +15,7 @@ import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu_item.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; import 'package:refilc_mobile_ui/common/dot.dart'; import 'package:refilc_mobile_ui/common/empty.dart'; import 'package:refilc_mobile_ui/common/profile_image/profile_button.dart'; @@ -69,6 +71,10 @@ class TimetablePage extends StatefulWidget { class TimetablePageState extends State with TickerProviderStateMixin, WidgetsBindingObserver { + final GlobalKey _scaffoldKey = GlobalKey(); + + PersistentBottomSheetController? _sheetController; + late UserProvider user; late TimetableProvider timetableProvider; late UpdateProvider updateProvider; @@ -215,6 +221,7 @@ class TimetablePageState extends State firstName = nameParts.length > 1 ? nameParts[1] : nameParts[0]; return Scaffold( + key: _scaffoldKey, body: Padding( padding: const EdgeInsets.only(top: 9.0), child: RefreshIndicator( @@ -235,50 +242,50 @@ class TimetablePageState extends State snap: false, surfaceTintColor: Theme.of(context).scaffoldBackgroundColor, actions: [ - Padding( - padding: const EdgeInsets.only(top: 8.0, bottom: 8.0), - child: IconButton( - splashRadius: 24.0, - // tested timetable sync - // onPressed: () async { - // ThirdPartyProvider tpp = - // Provider.of(context, - // listen: false); + // Padding( + // padding: const EdgeInsets.only(top: 8.0, bottom: 8.0), + // child: IconButton( + // splashRadius: 24.0, + // // tested timetable sync + // // onPressed: () async { + // // ThirdPartyProvider tpp = + // // Provider.of(context, + // // listen: false); - // await tpp.pushTimetable(context, _controller); - // }, - onPressed: () { - // If timetable empty, show empty - if (_tabController.length == 0) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text("empty_timetable".i18n), - duration: const Duration(seconds: 2), - )); - return; - } + // // await tpp.pushTimetable(context, _controller); + // // }, + // onPressed: () { + // // If timetable empty, show empty + // if (_tabController.length == 0) { + // ScaffoldMessenger.of(context).showSnackBar(SnackBar( + // content: Text("empty_timetable".i18n), + // duration: const Duration(seconds: 2), + // )); + // return; + // } - Navigator.of(context, rootNavigator: true) - .push(PageRouteBuilder( - pageBuilder: - (context, animation, secondaryAnimation) => - FSTimetable( - controller: _controller, - ), - )) - .then((_) { - SystemChrome.setPreferredOrientations( - [DeviceOrientation.portraitUp]); - setSystemChrome(context); - }); - }, - icon: Icon(FeatherIcons.trello, - color: AppColors.of(context).text), - ), - ), + // Navigator.of(context, rootNavigator: true) + // .push(PageRouteBuilder( + // pageBuilder: + // (context, animation, secondaryAnimation) => + // FSTimetable( + // controller: _controller, + // ), + // )) + // .then((_) { + // SystemChrome.setPreferredOrientations( + // [DeviceOrientation.portraitUp]); + // setSystemChrome(context); + // }); + // }, + // icon: Icon(FeatherIcons.trello, + // color: AppColors.of(context).text), + // ), + // ), Padding( padding: const EdgeInsets.only( - right: 8.0, + right: 5.0, bottom: 8.0, top: 8.0, ), @@ -293,9 +300,9 @@ class TimetablePageState extends State // await tpp.pushTimetable(context, _controller); // }, onPressed: () { - showQuickOptions(context); + showQuickSettings(context); }, - icon: Icon(FeatherIcons.menu, + icon: Icon(FeatherIcons.moreHorizontal, color: AppColors.of(context).text), ), ), @@ -711,6 +718,9 @@ class TimetablePageState extends State customLessonDesc[ lesson.id] ?? lesson.description, + showSubTiles: + settingsProvider + .qTimetableSubTiles, ), ), ), @@ -844,35 +854,149 @@ class TimetablePageState extends State ); } - void showQuickOptions(BuildContext context) { - showBottomSheetMenu( + void showQuickSettings(BuildContext context) { + // _sheetController = _scaffoldKey.currentState?.showBottomSheet( + // (context) => RoundedBottomSheet( + // borderRadius: 14.0, + // child: BottomSheetMenu(items: [ + // SwitchListTile( + // title: Text('show_lesson_num'.i18n), + // value: + // Provider.of(context).qTimetableLessonNum, + // onChanged: (v) { + // Provider.of(context, listen: false) + // .update(qTimetableLessonNum: v); + // }) + // ])), + // backgroundColor: const Color(0x00000000), + // elevation: 12.0, + // ); + + // _sheetController!.closed.then((value) { + // // Show fab and grades + // if (mounted) {} + // }); + showRoundedModalBottomSheet( context, - items: [ - SwitchListTile( - title: Text( - 'show_lesson_num'.i18n, - ), - value: settingsProvider.qTimetableLessonNum, - onChanged: (v) { - settingsProvider.update(qTimetableLessonNum: v); - setState(() {}); + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + child: BottomSheetMenu(items: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: ListTile( + contentPadding: const EdgeInsets.only(left: 16.0, right: 10.0), + title: Row( + children: [ + const Icon(FeatherIcons.trello), + const SizedBox( + width: 10.0, + ), + Text('full_screen_timetable'.i18n), + ], + ), + onTap: () { + if (_tabController.length == 0) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text("empty_timetable".i18n), + duration: const Duration(seconds: 2), + )); + return; + } - Navigator.of(context).maybePop(); - }, - ), - SwitchListTile( - title: Text( - 'show_exams_and_homework'.i18n, - ), - value: settingsProvider.qTimetableSubTiles, - onChanged: (v) { - settingsProvider.update(qTimetableSubTiles: v); - setState(() {}); + Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).maybePop(); - }, + Navigator.of(context, rootNavigator: true) + .push(PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => + FSTimetable( + controller: _controller, + ), + )) + .then((_) { + SystemChrome.setPreferredOrientations( + [DeviceOrientation.portraitUp]); + setSystemChrome(context); + }); + }, + ), ), - ], + const SizedBox( + height: 10.0, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: SwitchListTile( + contentPadding: const EdgeInsets.only(left: 16.0, right: 10.0), + title: Row( + children: [ + const Icon(Icons.local_cafe_rounded), + const SizedBox( + width: 10.0, + ), + Text('show_breaks'.i18n), + ], + ), + value: Provider.of(context, listen: false) + .showBreaks, + onChanged: (v) { + Provider.of(context, listen: false) + .update(showBreaks: v); + + Navigator.of(context, rootNavigator: true).pop(); + }, + ), + ), + // SwitchListTile( + // title: Row( + // children: [ + // const Icon(FeatherIcons.clock), + // const SizedBox( + // width: 10.0, + // ), + // Text('show_lesson_num'.i18n), + // ], + // ), + // value: Provider.of(context, listen: false) + // .qTimetableLessonNum, + // onChanged: (v) { + // Provider.of(context, listen: false) + // .update(qTimetableLessonNum: v); + + // Navigator.of(context, rootNavigator: true).pop(); + // }, + // ), + const SizedBox( + height: 10.0, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: SwitchListTile( + contentPadding: const EdgeInsets.only(left: 16.0, right: 10.0), + title: Row( + children: [ + const Icon(Icons.edit_document), + const SizedBox( + width: 10.0, + ), + Text('show_exams_homework'.i18n), + ], + ), + value: Provider.of(context, listen: false) + .qTimetableSubTiles, + onChanged: (v) { + Provider.of(context, listen: false) + .update(qTimetableSubTiles: v); + + Navigator.of(context, rootNavigator: true).pop(); + }, + ), + ), + ]), ); } } diff --git a/refilc_mobile_ui/lib/pages/timetable/timetable_page.i18n.dart b/refilc_mobile_ui/lib/pages/timetable/timetable_page.i18n.dart index c2d9f31..843090d 100644 --- a/refilc_mobile_ui/lib/pages/timetable/timetable_page.i18n.dart +++ b/refilc_mobile_ui/lib/pages/timetable/timetable_page.i18n.dart @@ -10,6 +10,9 @@ extension Localization on String { "error": "Failed to fetch timetable!", "empty_timetable": "Timetable is empty!", "break": "Break", + "full_screen_timetable": "Full Screen Timetable", + "show_breaks": "Show Breaks", + "show_exams_homework": "Exams and Homework", }, "hu_hu": { "timetable": "Órarend", @@ -18,6 +21,9 @@ extension Localization on String { "error": "Nem sikerült lekérni az órarendet!", "empty_timetable": "Az órarend üres!", "break": "Szünet", + "full_screen_timetable": "Teljes képernyős órarend", + "show_breaks": "Szünetek megjelenítése", + "show_exams_homework": "Dolgozatok és házik", }, "de_de": { "timetable": "Zeitplan", @@ -26,6 +32,9 @@ extension Localization on String { "error": "Der Fahrplan konnte nicht abgerufen werden!", "empty_timetable": "Der Zeitplan ist blank!", "break": "Pause", + "full_screen_timetable": "Vollbildfahrplan", + "show_breaks": "Pausen anzeigen", + "show_exams_homework": "Referate und Hausaufgaben", }, }; diff --git a/refilc_mobile_ui/lib/screens/settings/settings_helper.dart b/refilc_mobile_ui/lib/screens/settings/settings_helper.dart index e566eea..75959e2 100644 --- a/refilc_mobile_ui/lib/screens/settings/settings_helper.dart +++ b/refilc_mobile_ui/lib/screens/settings/settings_helper.dart @@ -751,7 +751,7 @@ class _BellDelaySettingState extends State Provider.of(context, listen: false) .update(bellDelay: currentDelay.inSeconds); _tabController.index = currentDelay.inSeconds > 0 ? 1 : 0; - if(Platform.isIOS){ + if (Platform.isIOS) { LiveCardProvider.hasActivitySettingsChanged = true; } setState(() {}); @@ -764,7 +764,7 @@ class _BellDelaySettingState extends State //Provider.of(context, listen: false).update(context, rounding: (r * 10).toInt()); Provider.of(context, listen: false) .update(bellDelay: currentDelay.inSeconds); - if(Platform.isIOS){ + if (Platform.isIOS) { LiveCardProvider.hasActivitySettingsChanged = true; } Navigator.of(context).maybePop(); From 6d8d11cd87343770028fa9d1b8fea879d74af2f3 Mon Sep 17 00:00:00 2001 From: Kima Date: Sat, 4 May 2024 23:31:07 +0200 Subject: [PATCH 09/23] version bump --- refilc/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/refilc/pubspec.yaml b/refilc/pubspec.yaml index dfc7c68..1ac99e5 100644 --- a/refilc/pubspec.yaml +++ b/refilc/pubspec.yaml @@ -3,7 +3,7 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak." homepage: https://refilc.hu publish_to: "none" -version: 5.0.0+255 +version: 5.0.0+256 environment: sdk: ">=2.17.0 <=3.3.2" From 25a72da3a8d09d29e258d1776f50da3fdb8a1cfa Mon Sep 17 00:00:00 2001 From: Kima Date: Sat, 4 May 2024 23:31:15 +0200 Subject: [PATCH 10/23] did everything, like really --- .../lib/api/providers/live_card_provider.dart | 130 ++++++----- .../lib/api/providers/self_note_provider.dart | 4 + refilc/lib/models/self_note.dart | 7 + refilc/lib/theme/theme.dart | 1 - refilc/lib/ui/widgets/lesson/lesson_tile.dart | 1 - refilc/lib/utils/reverse_search.dart | 2 - .../widgets/lesson/lesson_viewable.dart | 12 - .../lib/pages/grades/grades_page.dart | 22 -- refilc_mobile_ui/lib/pages/grades/graph.dart | 26 ++- .../lib/pages/home/live_card/live_card.dart | 10 +- .../lib/pages/notes/notes_page.dart | 121 +++++++++- .../lib/pages/notes/notes_page.i18n.dart | 3 + .../pages/notes/submenu/add_note_screen.dart | 4 +- .../notes/submenu/create_image_note.dart | 214 ++++++++++++++++++ .../notes/submenu/notes_screen.i18n.dart | 15 ++ .../lib/pages/timetable/timetable_page.dart | 3 - 16 files changed, 450 insertions(+), 125 deletions(-) create mode 100644 refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart diff --git a/refilc/lib/api/providers/live_card_provider.dart b/refilc/lib/api/providers/live_card_provider.dart index 7ace094..6cf5c6e 100644 --- a/refilc/lib/api/providers/live_card_provider.dart +++ b/refilc/lib/api/providers/live_card_provider.dart @@ -1,8 +1,5 @@ // ignore_for_file: no_leading_underscores_for_local_identifiers -import 'dart:async'; -import 'dart:io'; - import 'package:refilc/api/providers/liveactivity/platform_channel.dart'; import 'package:refilc/helpers/subject.dart'; import 'package:refilc/models/settings.dart'; @@ -39,13 +36,11 @@ class LiveCardProvider extends ChangeNotifier { // LiveCardState currentState = LiveCardState.empty; - late Timer _timer; late final TimetableProvider _timetable; late final SettingsProvider _settings; late Duration _delay; - bool _hasCheckedTimetable = false; LiveCardProvider({ @@ -53,7 +48,6 @@ class LiveCardProvider extends ChangeNotifier { required SettingsProvider settings, }) : _timetable = timetable, _settings = settings { - _timer = Timer.periodic(const Duration(seconds: 1), (timer) => update()); _delay = settings.bellDelayEnabled ? Duration(seconds: settings.bellDelay) : Duration.zero; @@ -87,19 +81,24 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.morning: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", "title": "Első órádig:", "subtitle": "", "description": "", - "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", + "startDate": storeFirstRunDate != null + ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - + (_delay.inMilliseconds)) + .toString() + : "", "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -107,19 +106,24 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.afternoon: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", "title": "Első órádig:", "subtitle": "", "description": "", - "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", + "startDate": storeFirstRunDate != null + ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - + (_delay.inMilliseconds)) + .toString() + : "", "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -127,19 +131,24 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.night: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": nextLesson != null ? SubjectIcon.resolveName(subject: nextLesson?.subject) : "book", "title": "Első órádig:", "subtitle": "", "description": "", - "startDate": storeFirstRunDate != null ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - (_delay.inMilliseconds)).toString(): "", + "startDate": storeFirstRunDate != null + ? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) - + (_delay.inMilliseconds)) + .toString() + : "", "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -147,25 +156,28 @@ class LiveCardProvider extends ChangeNotifier { case LiveCardState.duringLesson: return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": currentLesson != null ? SubjectIcon.resolveName(subject: currentLesson?.subject) : "book", "index": - currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "", + currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "", "title": currentLesson != null - ? currentLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: currentLesson?.subject).capital() + ? currentLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: currentLesson?.subject) + .capital() : "", "subtitle": currentLesson?.room.replaceAll("_", " ") ?? "", "description": currentLesson?.description ?? "", "startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject).capital() : "", "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", }; @@ -181,21 +193,23 @@ class LiveCardProvider extends ChangeNotifier { return { "color": - '#${_settings.liveActivityColor.toString().substring(10, 16)}', + '#${_settings.liveActivityColor.toString().substring(10, 16)}', "icon": iconFloorMap[diff] ?? "cup.and.saucer", "title": "Szünet", "description": "go $diff".i18n.fill([ diff != "to room" ? (nextLesson!.getFloor() ?? 0) : nextLesson!.room ]), "startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - - _delay.inMilliseconds) + _delay.inMilliseconds) .toString(), "nextSubject": (nextLesson != null - ? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital() - : "") + ? nextLesson?.subject.renamedTo ?? + ShortSubject.resolve(subject: nextLesson?.subject) + .capital() + : "") .capital(), "nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "", "index": "", @@ -219,12 +233,12 @@ class LiveCardProvider extends ChangeNotifier { ? Duration(seconds: _settings.bellDelay) : Duration.zero; - DateTime now = _now().add(_delay); if ((currentState == LiveCardState.morning || - currentState == LiveCardState.afternoon || - currentState == LiveCardState.night) && storeFirstRunDate == null) { + currentState == LiveCardState.afternoon || + currentState == LiveCardState.night) && + storeFirstRunDate == null) { storeFirstRunDate = now; } @@ -232,9 +246,9 @@ class LiveCardProvider extends ChangeNotifier { // Filter label lessons #128 today = today .where((lesson) => - lesson.status?.name != "Elmaradt" && - lesson.subject.id != '' && - !lesson.isEmpty) + lesson.status?.name != "Elmaradt" && + lesson.subject.id != '' && + !lesson.isEmpty) .toList(); if (today.isNotEmpty) { @@ -242,7 +256,7 @@ class LiveCardProvider extends ChangeNotifier { today.sort((a, b) => a.start.compareTo(b.start)); final _lesson = today.firstWhere( - (l) => l.start.isBefore(now) && l.end.isAfter(now), + (l) => l.start.isBefore(now) && l.end.isAfter(now), orElse: () => Lesson.fromJson({})); if (_lesson.start.year != 0) { @@ -291,22 +305,21 @@ class LiveCardProvider extends ChangeNotifier { //LIVE ACTIVITIES //CREATE - if (!hasActivityStarted && nextLesson != null && nextLesson! - .start - .difference(now) - .inMinutes <= 60 && (currentState == LiveCardState.morning || - currentState == LiveCardState.afternoon || - currentState == LiveCardState.night)) { + if (!hasActivityStarted && + nextLesson != null && + nextLesson!.start.difference(now).inMinutes <= 60 && + (currentState == LiveCardState.morning || + currentState == LiveCardState.afternoon || + currentState == LiveCardState.night)) { debugPrint( "Az első óra előtt állunk, kevesebb mint egy órával. Létrehozás..."); PlatformChannel.createLiveActivity(toMap()); hasActivityStarted = true; - } - else if (!hasActivityStarted && ((currentState == LiveCardState.duringLesson && - currentLesson != null) || - currentState == LiveCardState.duringBreak)) { - debugPrint( - "Óra van, vagy szünet, de nincs LiveActivity. létrehozás..."); + } else if (!hasActivityStarted && + ((currentState == LiveCardState.duringLesson && + currentLesson != null) || + currentState == LiveCardState.duringBreak)) { + debugPrint("Óra van, vagy szünet, de nincs LiveActivity. létrehozás..."); PlatformChannel.createLiveActivity(toMap()); hasActivityStarted = true; } @@ -317,15 +330,18 @@ class LiveCardProvider extends ChangeNotifier { debugPrint("Valamelyik beállítás megváltozott. Frissítés..."); PlatformChannel.updateLiveActivity(toMap()); hasActivitySettingsChanged = false; - } - else if (nextLesson != null || currentLesson != null) { + } else if (nextLesson != null || currentLesson != null) { bool afterPrevLessonEnd = prevLesson != null && - now.subtract(const Duration(seconds: 1)).isBefore( - prevLesson!.end) && now.isAfter(prevLesson!.end); + now + .subtract(const Duration(seconds: 1)) + .isBefore(prevLesson!.end) && + now.isAfter(prevLesson!.end); bool afterCurrentLessonStart = currentLesson != null && - now.subtract(const Duration(seconds: 1)).isBefore( - currentLesson!.start) && now.isAfter(currentLesson!.start); + now + .subtract(const Duration(seconds: 1)) + .isBefore(currentLesson!.start) && + now.isAfter(currentLesson!.start); if (afterPrevLessonEnd || afterCurrentLessonStart) { debugPrint( "Óra kezdete/vége után 1 másodperccel vagyunk. Frissítés..."); @@ -335,7 +351,9 @@ class LiveCardProvider extends ChangeNotifier { } //END - if (hasActivityStarted && !hasDayEnd && nextLesson == null && + if (hasActivityStarted && + !hasDayEnd && + nextLesson == null && now.isAfter(prevLesson!.end)) { debugPrint("Az utolsó óra véget ért. Befejezés..."); PlatformChannel.endLiveActivity(); @@ -355,4 +373,4 @@ class LiveCardProvider extends ChangeNotifier { List _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? []) .where((l) => _sameDate(l.date, _now())) .toList(); -} \ No newline at end of file +} diff --git a/refilc/lib/api/providers/self_note_provider.dart b/refilc/lib/api/providers/self_note_provider.dart index b19816c..3a095b7 100644 --- a/refilc/lib/api/providers/self_note_provider.dart +++ b/refilc/lib/api/providers/self_note_provider.dart @@ -24,6 +24,10 @@ class SelfNoteProvider with ChangeNotifier { Future restore() async { String? userId = Provider.of(_context, listen: false).id; + // await Provider.of(_context, listen: false) + // .userStore + // .storeSelfNotes([], userId: userId!); + // load self notes from db if (userId != null) { var dbNotes = await Provider.of(_context, listen: false) diff --git a/refilc/lib/models/self_note.dart b/refilc/lib/models/self_note.dart index 609f6ff..bd86a1d 100644 --- a/refilc/lib/models/self_note.dart +++ b/refilc/lib/models/self_note.dart @@ -1,13 +1,18 @@ +enum NoteType { text, image } + class SelfNote { String id; String? title; String content; + NoteType noteType; + Map? json; SelfNote({ required this.id, this.title, required this.content, + required this.noteType, this.json, }); @@ -16,6 +21,7 @@ class SelfNote { id: json['id'], title: json['title'], content: json['content'], + noteType: json['note_type'] == 'image' ? NoteType.image : NoteType.text, json: json, ); } @@ -24,5 +30,6 @@ class SelfNote { 'id': id, 'title': title, 'content': content, + 'note_type': noteType == NoteType.image ? 'image' : 'text', }; } diff --git a/refilc/lib/theme/theme.dart b/refilc/lib/theme/theme.dart index 8b4594b..e1a9215 100644 --- a/refilc/lib/theme/theme.dart +++ b/refilc/lib/theme/theme.dart @@ -1,7 +1,6 @@ import 'package:refilc/models/settings.dart'; import 'package:refilc/theme/colors/accent.dart'; import 'package:refilc/theme/colors/colors.dart'; -import 'package:refilc/theme/colors/new_colors.dart'; import 'package:refilc/theme/colors/utils.dart'; import 'package:refilc/theme/observer.dart'; import 'package:flutter/material.dart'; diff --git a/refilc/lib/ui/widgets/lesson/lesson_tile.dart b/refilc/lib/ui/widgets/lesson/lesson_tile.dart index de1cde1..f2041da 100644 --- a/refilc/lib/ui/widgets/lesson/lesson_tile.dart +++ b/refilc/lib/ui/widgets/lesson/lesson_tile.dart @@ -1,5 +1,4 @@ import 'package:refilc/models/settings.dart'; -import 'package:refilc/theme/colors/new_colors.dart'; import 'package:refilc_kreta_api/providers/exam_provider.dart'; import 'package:refilc_kreta_api/providers/homework_provider.dart'; import 'package:refilc/theme/colors/colors.dart'; diff --git a/refilc/lib/utils/reverse_search.dart b/refilc/lib/utils/reverse_search.dart index f2b3301..3dcae9a 100644 --- a/refilc/lib/utils/reverse_search.dart +++ b/refilc/lib/utils/reverse_search.dart @@ -1,8 +1,6 @@ import 'dart:developer'; -import 'package:googleapis/privateca/v1.dart'; import 'package:refilc_kreta_api/models/absence.dart'; -import 'package:refilc_kreta_api/models/category.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; import 'package:refilc_kreta_api/models/subject.dart'; import 'package:refilc_kreta_api/models/week.dart'; 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 8b4f391..70f7787 100644 --- a/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart @@ -1,4 +1,3 @@ -import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:flutter_svg/svg.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; @@ -7,22 +6,11 @@ import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/helpers/subject.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc/theme/colors/utils.dart'; -import 'package:refilc/utils/reverse_search.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; -import 'package:refilc_mobile_ui/common/custom_snack_bar.dart'; -import 'package:refilc_mobile_ui/common/panel/panel_button.dart'; import 'package:refilc_mobile_ui/common/round_border_icon.dart'; -import 'package:refilc_mobile_ui/common/viewable.dart'; -import 'package:refilc_mobile_ui/common/widgets/card_handle.dart'; import 'package:refilc/ui/widgets/lesson/lesson_tile.dart'; -import 'package:refilc_mobile_ui/common/widgets/lesson/lesson_view.dart'; import 'package:flutter/material.dart'; -import 'package:refilc_mobile_ui/pages/grades/grades_page.dart'; -import 'package:refilc_plus/models/premium_scopes.dart'; -import 'package:refilc_plus/providers/plus_provider.dart'; -import 'package:refilc_plus/ui/mobile/plus/upsell.dart'; -import 'lesson_view.i18n.dart'; class LessonViewable extends StatefulWidget { const LessonViewable( diff --git a/refilc_mobile_ui/lib/pages/grades/grades_page.dart b/refilc_mobile_ui/lib/pages/grades/grades_page.dart index 3d18708..6f8d084 100644 --- a/refilc_mobile_ui/lib/pages/grades/grades_page.dart +++ b/refilc_mobile_ui/lib/pages/grades/grades_page.dart @@ -33,7 +33,6 @@ import 'package:refilc_mobile_ui/pages/grades/fail_warning.dart'; import 'package:refilc_mobile_ui/pages/grades/grades_count.dart'; import 'package:refilc_mobile_ui/pages/grades/graph.dart'; import 'package:refilc_mobile_ui/pages/grades/grade_subject_view.dart'; -import 'package:refilc_mobile_ui/pages/timetable/timetable_page.dart'; import 'package:refilc_mobile_ui/screens/navigation/navigation_route_handler.dart'; import 'package:refilc_mobile_ui/screens/navigation/navigation_screen.dart'; import 'package:refilc_plus/models/premium_scopes.dart'; @@ -640,27 +639,6 @@ class GradesPageState extends State { } void showQuickSettings(BuildContext context) { - // _sheetController = _scaffoldKey.currentState?.showBottomSheet( - // (context) => RoundedBottomSheet( - // borderRadius: 14.0, - // child: BottomSheetMenu(items: [ - // SwitchListTile( - // title: Text('show_lesson_num'.i18n), - // value: - // Provider.of(context).qTimetableLessonNum, - // onChanged: (v) { - // Provider.of(context, listen: false) - // .update(qTimetableLessonNum: v); - // }) - // ])), - // backgroundColor: const Color(0x00000000), - // elevation: 12.0, - // ); - - // _sheetController!.closed.then((value) { - // // Show fab and grades - // if (mounted) {} - // }); showRoundedModalBottomSheet( context, backgroundColor: Theme.of(context).scaffoldBackgroundColor, diff --git a/refilc_mobile_ui/lib/pages/grades/graph.dart b/refilc_mobile_ui/lib/pages/grades/graph.dart index 8f22f65..ed8e2e8 100644 --- a/refilc_mobile_ui/lib/pages/grades/graph.dart +++ b/refilc_mobile_ui/lib/pages/grades/graph.dart @@ -161,6 +161,11 @@ class GradeGraphState extends State { final x = halfYearGrade.writeDate.month + (halfYearGrade.writeDate.day / 31) + ((halfYearGrade.writeDate.year - data.last.writeDate.year) * 12); + + List dataBeforeMidYr = data + .where((e) => e.writeDate.isBefore(halfYearGrade.writeDate)) + .toList(); + if (x <= maxX) { extraLinesV.add( VerticalLine( @@ -170,7 +175,9 @@ class GradeGraphState extends State { label: VerticalLineLabel( labelResolver: (_) => " ${"mid".i18n} ​", // <- zwsp for padding show: true, - alignment: Alignment.topLeft, + alignment: dataBeforeMidYr.length < 2 + ? Alignment.topRight + : Alignment.topLeft, style: TextStyle( backgroundColor: Theme.of(context).colorScheme.background, color: AppColors.of(context).text, @@ -218,11 +225,12 @@ class GradeGraphState extends State { horizontalLines: extraLinesH), lineBarsData: [ LineChartBarData( - preventCurveOverShooting: true, + preventCurveOverShooting: false, spots: subjectSpots, isCurved: true, colors: averageColors.reversed.toList(), - barWidth: 8, + barWidth: 6, + curveSmoothness: 0.2, isStrokeCapRound: true, dotData: FlDotData(show: false), belowBarData: BarAreaData( @@ -339,11 +347,13 @@ class GradeGraphState extends State { ghostData.isNotEmpty ? ghostData : data; tData.sort((a, b) => a.writeDate.compareTo(b.writeDate)); - return tData.first.writeDate - .add(const Duration(days: 120)) - .isBefore(tData.last.writeDate) - ? 2.0 - : 1.0; + 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, 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 1d36bd2..922070a 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 @@ -6,17 +6,9 @@ import 'package:refilc/helpers/subject.dart'; import 'package:refilc/models/settings.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc/ui/widgets/lesson/lesson_tile.dart'; -import 'package:refilc_kreta_api/models/category.dart'; -import 'package:refilc_kreta_api/models/lesson.dart'; -import 'package:refilc_kreta_api/models/subject.dart'; -import 'package:refilc_kreta_api/models/teacher.dart'; import 'package:refilc_mobile_ui/common/panel/panel.dart'; import 'package:refilc_mobile_ui/common/progress_bar.dart'; import 'package:refilc_mobile_ui/common/round_border_icon.dart'; -// import 'package:refilc_kreta_api/models/category.dart'; -// import 'package:refilc_kreta_api/models/lesson.dart'; -// import 'package:refilc_kreta_api/models/subject.dart'; -// import 'package:refilc_kreta_api/models/teacher.dart'; import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart'; import 'package:refilc_mobile_ui/pages/home/live_card/heads_up_countdown.dart'; import 'package:refilc_mobile_ui/pages/home/live_card/segmented_countdown.dart'; @@ -94,7 +86,7 @@ class LiveCardStateA extends State { name: 'name', );*/ - liveCard.nextLesson = liveCard.currentLesson; + // liveCard.nextLesson = liveCard.currentLesson; // final dt = DateTime(2024, 3, 22, 17, 12, 1, 1, 1); diff --git a/refilc_mobile_ui/lib/pages/notes/notes_page.dart b/refilc_mobile_ui/lib/pages/notes/notes_page.dart index 61ff85c..b9550b0 100644 --- a/refilc_mobile_ui/lib/pages/notes/notes_page.dart +++ b/refilc_mobile_ui/lib/pages/notes/notes_page.dart @@ -1,5 +1,6 @@ // ignore_for_file: no_leading_underscores_for_local_identifiers, use_build_context_synchronously +import 'dart:convert'; import 'dart:math'; import 'package:flutter/cupertino.dart'; @@ -7,6 +8,8 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:refilc/api/providers/database_provider.dart'; import 'package:refilc/api/providers/self_note_provider.dart'; import 'package:refilc/api/providers/update_provider.dart'; +import 'package:refilc/models/self_note.dart'; +import 'package:refilc/models/settings.dart'; import 'package:refilc/utils/format.dart'; import 'package:refilc_kreta_api/models/absence.dart'; import 'package:refilc_kreta_api/models/homework.dart'; @@ -14,6 +17,8 @@ import 'package:refilc_kreta_api/models/subject.dart'; import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc_kreta_api/providers/homework_provider.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; import 'package:refilc_mobile_ui/common/empty.dart'; import 'package:refilc_mobile_ui/common/panel/panel.dart'; import 'package:refilc_mobile_ui/common/profile_image/profile_button.dart'; @@ -23,6 +28,7 @@ import 'package:refilc_mobile_ui/common/widgets/tick_tile.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:refilc_mobile_ui/pages/notes/submenu/add_note_screen.dart'; +import 'package:refilc_mobile_ui/pages/notes/submenu/create_image_note.dart'; import 'package:refilc_mobile_ui/pages/notes/submenu/note_view_screen.dart'; import 'package:refilc_mobile_ui/pages/notes/submenu/self_note_tile.dart'; import 'package:refilc_plus/models/premium_scopes.dart'; @@ -114,13 +120,37 @@ class NotesPageState extends State with TickerProviderStateMixin { if (selfNoteProvider.notes.isNotEmpty) { selfNoteTiles.addAll(selfNoteProvider.notes.reversed.map( - (e) => SelfNoteTile( - title: e.title ?? e.content.split(' ')[0], - content: e.content, - onTap: () => Navigator.of(context, rootNavigator: true).push( - CupertinoPageRoute( - builder: (context) => NoteViewScreen(note: e))), - ), + (e) => e.noteType == NoteType.text + ? SelfNoteTile( + title: e.title ?? e.content.split(' ')[0], + content: e.content, + onTap: () => Navigator.of(context, rootNavigator: true).push( + CupertinoPageRoute( + builder: (context) => NoteViewScreen(note: e))), + ) + : Container( + height: MediaQuery.of(context).size.width / 2.42, + width: MediaQuery.of(context).size.width / 2.42, + decoration: BoxDecoration( + boxShadow: [ + if (Provider.of(context, listen: false) + .shadowEffect) + BoxShadow( + offset: const Offset(0, 21), + blurRadius: 23.0, + color: Theme.of(context).shadowColor, + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(16.0), + child: Image.memory( + const Base64Decoder().convert(e.content), + fit: BoxFit.cover, + gaplessPlayback: true, + ), + ), + ), )); } @@ -235,9 +265,7 @@ class NotesPageState extends State with TickerProviderStateMixin { feature: PremiumFeature.selfNotes); } - Navigator.of(context, rootNavigator: true).push( - CupertinoPageRoute( - builder: (context) => const AddNoteScreen())); + showCreationModal(context); }, child: Icon( FeatherIcons.plus, @@ -312,4 +340,77 @@ class NotesPageState extends State with TickerProviderStateMixin { ), ); } + + void showCreationModal(BuildContext context) { + // _sheetController = _scaffoldKey.currentState?.showBottomSheet( + // (context) => RoundedBottomSheet( + // borderRadius: 14.0, + // child: BottomSheetMenu(items: [ + // SwitchListTile( + // title: Text('show_lesson_num'.i18n), + // value: + // Provider.of(context).qTimetableLessonNum, + // onChanged: (v) { + // Provider.of(context, listen: false) + // .update(qTimetableLessonNum: v); + // }) + // ])), + // backgroundColor: const Color(0x00000000), + // elevation: 12.0, + // ); + + // _sheetController!.closed.then((value) { + // // Show fab and grades + // if (mounted) {} + // }); + showRoundedModalBottomSheet( + context, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + child: BottomSheetMenu(items: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: ListTile( + title: Row( + children: [ + const Icon(Icons.sticky_note_2_outlined), + const SizedBox( + width: 10.0, + ), + Text('new_note'.i18n), + ], + ), + onTap: () => Navigator.of(context, rootNavigator: true).push( + CupertinoPageRoute( + builder: (context) => const AddNoteScreen())), + ), + ), + const SizedBox( + height: 10.0, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: ListTile( + title: Row( + children: [ + const Icon(Icons.photo_library_outlined), + const SizedBox( + width: 10.0, + ), + Text('new_image'.i18n), + ], + ), + onTap: () { + showDialog( + context: context, + builder: (context) => ImageNoteEditor(user.user!)); + }, + ), + ), + ]), + ); + } } diff --git a/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart b/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart index 7924e35..f452a9e 100644 --- a/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart +++ b/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart @@ -13,6 +13,7 @@ extension ScreensLocalization on String { "hint": "Note content...", "hint_t": "Note title...", "your_notes": "Your Notes", + "new_image": "New Image", }, "hu_hu": { "notes": "Füzet", @@ -24,6 +25,7 @@ extension ScreensLocalization on String { "hint": "Jegyzet tartalma...", "hint_t": "Jegyzet címe...", "your_notes": "Jegyzeteid", + "new_image": "Új kép", }, "de_de": { "notes": "Broschüre", @@ -35,6 +37,7 @@ extension ScreensLocalization on String { "hint": "Inhalt beachten...", "hint_t": "Titel notieren...", "your_notes": "Deine Noten", + "new_image": "Neues Bild", }, }; diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/add_note_screen.dart b/refilc_mobile_ui/lib/pages/notes/submenu/add_note_screen.dart index 4cbe5cf..30c9bb3 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/add_note_screen.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/add_note_screen.dart @@ -153,7 +153,8 @@ class AddNoteScreenState extends State { 'title': _titleController.text.replaceAll(' ', '') == '' ? null : _titleController.text, - 'content': _contentController.text + 'content': _contentController.text, + 'note_type': 'text', })); } else { var i = @@ -165,6 +166,7 @@ class AddNoteScreenState extends State { ? null : _titleController.text, 'content': _contentController.text, + 'note_type': 'text', }); } diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart b/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart new file mode 100644 index 0000000..c81faf7 --- /dev/null +++ b/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart @@ -0,0 +1,214 @@ +// ignore_for_file: use_build_context_synchronously + +import 'dart:convert'; +import 'dart:developer'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:image_crop/image_crop.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:provider/provider.dart'; +import 'package:refilc/api/providers/database_provider.dart'; +import 'package:refilc/api/providers/self_note_provider.dart'; +import 'package:refilc/models/self_note.dart'; +import 'package:refilc/models/user.dart'; +import 'package:uuid/uuid.dart'; +import 'notes_screen.i18n.dart'; + +// ignore: must_be_immutable +class ImageNoteEditor extends StatefulWidget { + late User u; + + ImageNoteEditor(this.u, {super.key}); + + @override + State createState() => _ImageNoteEditorState(); +} + +class _ImageNoteEditorState extends State { + final cropKey = GlobalKey(); + File? _file; + File? _sample; + File? _lastCropped; + + File? image; + Future pickImage() async { + try { + final image = await ImagePicker().pickImage(source: ImageSource.gallery); + if (image == null) return; + File imageFile = File(image.path); + + final sample = await ImageCrop.sampleImage( + file: imageFile, + preferredSize: context.size!.longestSide.ceil(), + ); + + _sample?.delete(); + _file?.delete(); + + setState(() { + _sample = sample; + _file = imageFile; + }); + } on PlatformException catch (e) { + log('Failed to pick image: $e'); + } + } + + Widget cropImageWidget() { + return SizedBox( + height: 300, + child: Crop.file( + _sample!, + key: cropKey, + aspectRatio: 1.0, + ), + ); + } + + Widget openImageWidget() { + return InkWell( + customBorder: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(14.0), + ), + onTap: () => pickImage(), + child: Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(14.0), + ), + width: double.infinity, + padding: const EdgeInsets.symmetric(vertical: 32.0, horizontal: 8.0), + child: Column( + children: [ + Text( + "click_here".i18n, + style: const TextStyle( + fontSize: 22.0, + fontWeight: FontWeight.w600, + ), + ), + Text( + "select_image".i18n, + style: const TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w500, + ), + ) + ], + ), + ), + ); + } + + Future _cropImage() async { + final scale = cropKey.currentState!.scale; + final area = cropKey.currentState!.area; + if (area == null || _file == null) { + return; + } + + final sample = await ImageCrop.sampleImage( + file: _file!, + preferredSize: (2000 / scale).round(), + ); + + final file = await ImageCrop.cropImage( + file: sample, + area: area, + ); + + sample.delete(); + + _lastCropped?.delete(); + _lastCropped = file; + + List imageBytes = await _lastCropped!.readAsBytes(); + String base64Image = base64Encode(imageBytes); + + List selfNotes = + await Provider.of(context, listen: false) + .userQuery + .getSelfNotes(userId: widget.u.id); + + selfNotes.add(SelfNote.fromJson({ + 'id': const Uuid().v4(), + 'content': base64Image, + 'note_type': 'image' + })); + + await Provider.of(context, listen: false) + .userStore + .storeSelfNotes(selfNotes, userId: widget.u.id); + + Provider.of(context, listen: false).restore(); + + debugPrint('$file'); + } + + @override + void dispose() { + super.dispose(); + _file?.delete(); + _sample?.delete(); + _lastCropped?.delete(); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(14.0))), + contentPadding: const EdgeInsets.only(top: 10.0), + title: Text("new_image".i18n), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: + const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0), + child: _sample == null ? openImageWidget() : cropImageWidget(), + ), + // if (widget.u.picture != "") + // TextButton( + // child: Text( + // "remove_profile_picture".i18n, + // style: const TextStyle( + // fontWeight: FontWeight.w500, color: Colors.red), + // ), + // onPressed: () { + // widget.u.picture = ""; + // Provider.of(context, listen: false) + // .store + // .storeUser(widget.u); + // Provider.of(context, listen: false).refresh(); + // Navigator.of(context).pop(true); + // }, + // ), + ], + ), + 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 { + await _cropImage(); + Navigator.of(context).pop(true); + }, + ), + ], + ); + } +} diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart index 02c848b..bbe6033 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart @@ -13,6 +13,11 @@ extension SettingsLocalization on String { "hint": "Note content...", "hint_t": "Note title...", "your_notes": "Your Notes", + "next": "Next", + "cancel": "Cancel", + "click_here": "Click here", + "select_image": "to select an image", + "new_image": "New Image", }, "hu_hu": { "notes": "Füzet", @@ -24,6 +29,11 @@ extension SettingsLocalization on String { "hint": "Jegyzet tartalma...", "hint_t": "Jegyzet címe...", "your_notes": "Jegyzeteid", + "next": "Tovább", + "cancel": "Mégse", + "click_here": "Kattints ide", + "select_image": "kép kiválasztásához", + "new_image": "Új kép", }, "de_de": { "notes": "Broschüre", @@ -35,6 +45,11 @@ extension SettingsLocalization on String { "hint": "Inhalt beachten...", "hint_t": "Titel notieren...", "your_notes": "Deine Noten", + "next": "Weiter", + "cancel": "Abbrechen", + "click_here": "Klicken Sie hier", + "select_image": "um ein Bild auszuwählen", + "new_image": "Neues Bild", }, }; diff --git a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart index f31fbb4..e77376b 100644 --- a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart +++ b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart @@ -14,7 +14,6 @@ import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart'; -import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu_item.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; import 'package:refilc_mobile_ui/common/dot.dart'; import 'package:refilc_mobile_ui/common/empty.dart'; @@ -73,8 +72,6 @@ class TimetablePageState extends State with TickerProviderStateMixin, WidgetsBindingObserver { final GlobalKey _scaffoldKey = GlobalKey(); - PersistentBottomSheetController? _sheetController; - late UserProvider user; late TimetableProvider timetableProvider; late UpdateProvider updateProvider; From 6d0315e4e63f54461b0b6d7e2f7fd38d1d39b7b4 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 00:56:42 +0200 Subject: [PATCH 11/23] fix subject rename and added new exam popup --- refilc/lib/utils/reverse_search.dart | 29 ++ .../common/widgets/exam/exam_viewable.dart | 339 +++++++++++++++++- .../widgets/lesson/lesson_viewable.dart | 15 +- 3 files changed, 376 insertions(+), 7 deletions(-) diff --git a/refilc/lib/utils/reverse_search.dart b/refilc/lib/utils/reverse_search.dart index 3dcae9a..9380806 100644 --- a/refilc/lib/utils/reverse_search.dart +++ b/refilc/lib/utils/reverse_search.dart @@ -1,6 +1,7 @@ import 'dart:developer'; import 'package:refilc_kreta_api/models/absence.dart'; +import 'package:refilc_kreta_api/models/exam.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; import 'package:refilc_kreta_api/models/subject.dart'; import 'package:refilc_kreta_api/models/week.dart'; @@ -40,6 +41,34 @@ class ReverseSearch { } } + static Future getLessonByExam( + Exam exam, BuildContext context) async { + final timetableProvider = + Provider.of(context, listen: false); + + List lessons = []; + final week = Week.fromDate(exam.writeDate); + try { + await timetableProvider.fetch(week: week); + } catch (e) { + log("[ERROR] getLessonByAbsence: $e"); + } + lessons = timetableProvider.getWeek(week) ?? []; + + // Find absence lesson in timetable + Lesson lesson = lessons.firstWhere( + (l) => + _sameDate(l.date, exam.writeDate) && l.subject.id == exam.subject.id, + orElse: () => Lesson.fromJson({'isEmpty': true}), + ); + + if (lesson.isEmpty) { + return null; + } else { + return lesson; + } + } + // difference.inDays is not reliable static bool _sameDate(DateTime a, DateTime b) => (a.year == b.year && a.month == b.month && a.day == b.day); 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 0366af7..c8b33be 100644 --- a/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart @@ -1,8 +1,19 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:flutter_svg/svg.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:refilc/helpers/subject.dart'; +import 'package:refilc/models/settings.dart'; +import 'package:refilc/theme/colors/colors.dart'; +import 'package:refilc/theme/colors/utils.dart'; +import 'package:refilc/utils/format.dart'; +import 'package:refilc/utils/reverse_search.dart'; import 'package:refilc_kreta_api/models/exam.dart'; -import 'package:refilc_mobile_ui/common/viewable.dart'; -import 'package:refilc_mobile_ui/common/widgets/card_handle.dart'; +import 'package:refilc_kreta_api/models/lesson.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; +import 'package:refilc_mobile_ui/common/round_border_icon.dart'; import 'package:refilc_mobile_ui/common/widgets/exam/exam_tile.dart'; -import 'package:refilc_mobile_ui/common/widgets/exam/exam_view.dart'; import 'package:flutter/material.dart'; class ExamViewable extends StatelessWidget { @@ -15,13 +26,329 @@ class ExamViewable extends StatelessWidget { @override Widget build(BuildContext context) { - return Viewable( - tile: ExamTile( + return GestureDetector( + onTap: () => ExamPopup.show(context: context, exam: exam), + child: ExamTile( exam, showSubject: showSubject, padding: tilePadding, ), - view: CardHandle(child: ExamView(exam)), + ); + // return Viewable( + // tile: ExamTile( + // exam, + // showSubject: showSubject, + // padding: tilePadding, + // ), + // view: CardHandle(child: ExamView(exam)), + // ); + } +} + +class ExamPopup extends StatelessWidget { + const ExamPopup({ + super.key, + required this.exam, + required this.outsideContext, + required this.lesson, + }); + + final Exam exam; + final BuildContext outsideContext; + final Lesson? lesson; + + static void show({ + required BuildContext context, + required Exam exam, + }) async => + showRoundedModalBottomSheet( + context, + child: ExamPopup( + exam: exam, + outsideContext: context, + lesson: (await ReverseSearch.getLessonByExam(exam, context)), + ), + showHandle: false, + ); + + // IconData _getIcon() => _featureLevels[feature] == PremiumFeatureLevel.cap + // ? FilcIcons.kupak + // : _featureLevels[feature] == PremiumFeatureLevel.ink + // ? FilcIcons.tinta + // : FilcIcons.tinta; + // Color _getColor(BuildContext context) => + // _featureLevels[feature] == PremiumFeatureLevel.gold + // ? const Color(0xFFC89B08) + // : Theme.of(context).brightness == Brightness.light + // ? const Color(0xff691A9B) + // : const Color(0xffA66FC8); + // String? _getAsset() => _featureAssets[feature]; + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Theme.of(context).scaffoldBackgroundColor, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12.0), + ), + ), + child: Stack( + children: [ + Stack( + children: [ + SvgPicture.asset( + "assets/svg/mesh_bg.svg", + // ignore: deprecated_member_use + color: ColorsUtils() + .fade(context, Theme.of(context).colorScheme.secondary, + darkenAmount: 0.1, lightenAmount: 0.1) + .withOpacity(0.33), + width: MediaQuery.of(context).size.width, + ), + Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12.0), + ), + gradient: LinearGradient( + colors: [ + Theme.of(context).scaffoldBackgroundColor, + Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.1), + Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.1), + Theme.of(context).scaffoldBackgroundColor, + ], + stops: const [0.1, 0.5, 0.7, 1.0], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + width: MediaQuery.of(context).size.width, + height: 175.0, + ), + ], + ), + SizedBox( + width: MediaQuery.of(context).size.width, + child: Padding( + padding: const EdgeInsets.all(18.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 40, + height: 4, + decoration: BoxDecoration( + color: ColorsUtils() + .fade( + context, Theme.of(context).colorScheme.secondary, + darkenAmount: 0.1, lightenAmount: 0.1) + .withOpacity(0.33), + borderRadius: BorderRadius.circular( + 2.0, + ), + ), + ), + const SizedBox( + height: 38.0, + ), + Container( + decoration: BoxDecoration( + color: Theme.of(context).scaffoldBackgroundColor, + borderRadius: BorderRadius.circular(50.0), + ), + child: RoundBorderIcon( + color: ColorsUtils() + .darken( + Theme.of(context).colorScheme.secondary, + amount: 0.1, + ) + .withOpacity(0.9), + width: 1.5, + padding: 10.0, + icon: Icon( + SubjectIcon.resolveVariant( + context: context, subject: exam.subject), + size: 32.0, + color: ColorsUtils() + .darken( + Theme.of(context).colorScheme.secondary, + amount: 0.1, + ) + .withOpacity(0.8), + ), + ), + ), + const SizedBox( + height: 55.0, + ), + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.background, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12.0), + bottom: Radius.circular(6.0)), + ), + padding: const EdgeInsets.all(14.0), + child: Row( + children: [ + const RoundBorderIcon( + padding: 8.0, + icon: Icon( + Icons.edit_document, + size: 20.0, + ), + ), + const SizedBox( + width: 10.0, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + exam.description.capital(), + style: TextStyle( + color: + AppColors.of(context).text.withOpacity(0.9), + fontSize: 16.0, + fontWeight: FontWeight.w600, + ), + ), + Text( + (exam.mode?.description ?? 'Ismeretlen') + .capital(), + style: TextStyle( + color: AppColors.of(context).text, + fontSize: 14.0, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ], + ), + ), + if (lesson != null) + const SizedBox( + height: 6.0, + ), + if (lesson != null) + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.background, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(6.0), + bottom: Radius.circular(12.0)), + ), + padding: const EdgeInsets.all(14.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Icon( + SubjectIcon.resolveVariant( + context: context, subject: exam.subject), + size: 20.0, + ), + const SizedBox( + width: 10.0, + ), + Text( + (((lesson?.subject.isRenamed ?? false) && + Provider.of( + context, + listen: false) + .renamedSubjectsEnabled) + ? lesson?.subject.renamedTo + : (lesson?.subject.name ?? '') + .capital()) ?? + 'Ismeretlen', + style: TextStyle( + color: AppColors.of(context) + .text + .withOpacity(0.9), + fontSize: 16.0, + fontWeight: FontWeight.w600, + fontStyle: ((lesson?.subject.isRenamed ?? + false) && + Provider.of(context, + listen: false) + .renamedSubjectsItalics) + ? FontStyle.italic + : null, + ), + ), + ], + ), + Text( + '${DateFormat('H:mm').format(lesson!.start)} - ${DateFormat('H:mm').format(lesson!.end)}', + style: TextStyle( + color: + AppColors.of(context).text.withOpacity(0.85), + fontSize: 14.0, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + + // const SizedBox( + // height: 24.0, + // ), + // GestureDetector( + // onTap: () async { + // ReverseSearch.getSubjectByLesson(lesson, context) + // .then((subject) { + // if (subject != null) { + // GradesPage.jump(outsideContext, subject: subject); + // } else { + // ScaffoldMessenger.of(context) + // .showSnackBar(CustomSnackBar( + // content: Text("Cannot find subject".i18n, + // style: const TextStyle(color: Colors.white)), + // backgroundColor: AppColors.of(context).red, + // context: context, + // )); + // } + // }); + // }, + // child: Container( + // width: double.infinity, + // decoration: BoxDecoration( + // color: Theme.of(context).colorScheme.background, + // borderRadius: BorderRadius.circular(12.0), + // ), + // padding: const EdgeInsets.all(16.0), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Text( + // 'view_subject'.i18n, + // style: TextStyle( + // color: + // AppColors.of(context).text.withOpacity(0.9), + // fontSize: 18.0, + // fontWeight: FontWeight.w500, + // ), + // ), + // ], + // ), + // ), + // ), + ], + ), + ), + ), + ], + ), ); } } 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 70f7787..ae0aa31 100644 --- a/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart @@ -4,8 +4,10 @@ import 'package:provider/provider.dart'; import 'package:refilc/api/providers/database_provider.dart'; import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/helpers/subject.dart'; +import 'package:refilc/models/settings.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc/theme/colors/utils.dart'; +import 'package:refilc/utils/format.dart'; import 'package:refilc_kreta_api/models/lesson.dart'; import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; import 'package:refilc_mobile_ui/common/round_border_icon.dart'; @@ -408,11 +410,22 @@ class TimetableLessonPopup extends StatelessWidget { height: 12.0, ), Text( - lesson.name, + lesson.subject.isRenamed && + Provider.of(context, + listen: false) + .renamedSubjectsEnabled + ? lesson.subject.renamedTo! + : lesson.subject.name.capital(), style: TextStyle( color: AppColors.of(context).text, fontSize: 20.0, fontWeight: FontWeight.w700, + fontStyle: Provider.of(context, + listen: false) + .renamedSubjectsItalics && + lesson.subject.isRenamed + ? FontStyle.italic + : null, ), ), const SizedBox( From a17600c4ea742c3c527c2d40556420c72484820b Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 08:11:38 +0200 Subject: [PATCH 12/23] fixed live card issue --- refilc/lib/api/providers/live_card_provider.dart | 9 +++++++-- refilc_mobile_ui/lib/pages/home/home_page.dart | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/refilc/lib/api/providers/live_card_provider.dart b/refilc/lib/api/providers/live_card_provider.dart index 6cf5c6e..bb71bac 100644 --- a/refilc/lib/api/providers/live_card_provider.dart +++ b/refilc/lib/api/providers/live_card_provider.dart @@ -15,9 +15,10 @@ enum LiveCardState { duringLesson, duringBreak, morning, + weekendMorning, afternoon, night, - summary + summary, } class LiveCardProvider extends ChangeNotifier { @@ -297,7 +298,11 @@ class LiveCardProvider extends ChangeNotifier { } else if (now.hour >= 20) { currentState = LiveCardState.night; } else if (now.hour >= 5 && now.hour <= 10) { - currentState = LiveCardState.morning; + if (nextLesson == null || now.weekday == 6 || now.weekday == 7) { + currentState = LiveCardState.empty; + } else { + currentState = LiveCardState.morning; + } } else { currentState = LiveCardState.empty; } diff --git a/refilc_mobile_ui/lib/pages/home/home_page.dart b/refilc_mobile_ui/lib/pages/home/home_page.dart index 8a7218e..b05a055 100644 --- a/refilc_mobile_ui/lib/pages/home/home_page.dart +++ b/refilc_mobile_ui/lib/pages/home/home_page.dart @@ -213,7 +213,7 @@ class HomePageState extends State with TickerProviderStateMixin { // } // TODO: REMOVE IN PRODUCTION BUILD!!! - // print(_liveCard.currentState); + print(_liveCard.currentState); // _liveCard.currentState = LiveCardState.duringLesson; return Scaffold( From 0a1c5bbfd212eb930ef9ae1c3d3e25367c7604c5 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 16:52:42 +0200 Subject: [PATCH 13/23] temp revert login screen --- .../lib/screens/login/login_screen.dart | 643 ++++++------------ .../lib/screens/login/login_screen_new.dart | 618 +++++++++++++++++ 2 files changed, 827 insertions(+), 434 deletions(-) create mode 100644 refilc_mobile_ui/lib/screens/login/login_screen_new.dart diff --git a/refilc_mobile_ui/lib/screens/login/login_screen.dart b/refilc_mobile_ui/lib/screens/login/login_screen.dart index a9f2dbd..572f3dc 100644 --- a/refilc_mobile_ui/lib/screens/login/login_screen.dart +++ b/refilc_mobile_ui/lib/screens/login/login_screen.dart @@ -3,10 +3,8 @@ import 'package:refilc/api/client.dart'; import 'package:refilc/api/login.dart'; import 'package:refilc/theme/colors/colors.dart'; -import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; import 'package:refilc_mobile_ui/common/custom_snack_bar.dart'; import 'package:refilc_mobile_ui/common/system_chrome.dart'; -import 'package:refilc_mobile_ui/common/widgets/absence/absence_display.dart'; import 'package:refilc_mobile_ui/screens/login/login_button.dart'; import 'package:refilc_mobile_ui/screens/login/login_input.dart'; import 'package:refilc_mobile_ui/screens/login/school_input/school_input.dart'; @@ -14,8 +12,6 @@ import 'package:refilc_mobile_ui/screens/settings/privacy_view.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'login_screen.i18n.dart'; -import 'package:carousel_slider/carousel_slider.dart'; -import 'package:flutter_svg/flutter_svg.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key, this.back = false}); @@ -79,450 +75,223 @@ class LoginScreenState extends State { @override Widget build(BuildContext context) { - precacheImage(const AssetImage('assets/images/showcase1.png'), context); - precacheImage(const AssetImage('assets/images/showcase2.png'), context); - precacheImage(const AssetImage('assets/images/showcase3.png'), context); - precacheImage(const AssetImage('assets/images/showcase4.png'), context); - bool selected = false; - return Scaffold( body: Container( - decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), + decoration: BoxDecoration(color: AppColors.of(context).loginBackground), child: SingleChildScrollView( physics: const ClampingScrollPhysics(), controller: _scrollController, child: Container( - decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), + decoration: + BoxDecoration(color: AppColors.of(context).loginBackground), width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: SafeArea( child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - // app icon - Padding( - padding: const EdgeInsets.only(left: 24, top: 20), - child: Row( - children: [ - Image.asset( - 'assets/icons/ic_rounded.png', - width: 30.0, - ), - const SizedBox(width: 8), - const Text( - 'reFilc', - style: TextStyle( - color: Color(0xFF050B15), - fontSize: 18.0, - fontWeight: FontWeight.bold, - fontFamily: 'Montserrat'), - ), - Material( - type: MaterialType.transparency, - child: showBack - ? BackButton(color: AppColors.of(context).text) - : const SizedBox(height: 48.0), - ), - ], - )), - Stack( - alignment: Alignment.bottomCenter, - children: [ - Column( - //login buttons and ui starts here - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - const SizedBox(height: 21), - CarouselSlider( - options: CarouselOptions( - height: MediaQuery.of(context).size.height, - viewportFraction: 1, - autoPlay: true, - autoPlayInterval: const Duration(seconds: 6), - pauseAutoPlayOnTouch: true), - items: [1, 2, 3, 4].map((i) { - return Builder( - builder: (BuildContext context) { - return Column( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: - const EdgeInsets.only(left: 24), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Text( - "welcome_title_$i".i18n, - style: const TextStyle( - color: Color(0xFF050B15), - fontSize: 19, - fontFamily: 'Montserrat', - fontWeight: FontWeight.w700, - height: 1.3), - ), - const SizedBox( - height: 14.375), //meth - Padding( - padding: const EdgeInsets.only( - right: 20), - child: Text( - "welcome_text_$i".i18n, - style: const TextStyle( - color: Color(0xFF050B15), - fontFamily: 'FigTree', - fontWeight: - FontWeight.w500, - fontSize: 17, - height: 1.3), - ), - ), - ], - )), - const SizedBox(height: 15.625), - Padding( - padding: const EdgeInsets.only( - left: 16, right: 16), - child: Image.asset( - 'assets/images/showcase$i.png')) - ], - ); - }, - ); - }).toList(), - ), - ], + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(left: 16.0, top: 12.0), + child: ClipOval( + child: Material( + type: MaterialType.transparency, + child: showBack + ? BackButton( + color: AppColors.of(context).loginPrimary) + : const SizedBox(height: 48.0), ), - Container( - height: 300, - width: double.infinity, - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [Color(0x00DAE4F7), Color(0xFFDAE4F7)], - stops: [0, 0.12], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - ), - child: Padding( - padding: EdgeInsets.only(top: 50, bottom: MediaQuery.of(context).viewInsets.bottom), - child: Column( - children: [ - SizedBox( - height: 48, - width: double.infinity, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16), - child: FilledButton( - style: ButtonStyle( - shape: MaterialStateProperty.all< - RoundedRectangleBorder>( - const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(12)), - ))), - onPressed: () { - showModalBottomSheet( - backgroundColor: Colors.transparent, - context: context, - builder: (BuildContext context) { - return Container( - height: MediaQuery.of(context) - .size - .height * - 0.5 + MediaQuery.of(context).viewInsets.bottom, - decoration: const BoxDecoration( - color: Color(0xFFDAE4F7), - borderRadius: BorderRadius.only( - topRight: - Radius.circular(24.0), - topLeft: - Radius.circular(24.0), - ), - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Padding( - padding: - const EdgeInsets.only( - top: 18), - child: Container( - decoration: - const BoxDecoration( - color: - Color(0xFFB9C8E5), - borderRadius: - BorderRadius.only( - topRight: - Radius.circular( - 2.0), - topLeft: - Radius.circular( - 2.0), - ), - ), - width: 40, - height: 4, - ), - ), - Container( - width: double.infinity, - child: AutofillGroup( - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .end, - children: [ - // username - Padding( - padding: - const EdgeInsets - .only( - bottom: - 6.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Expanded( - child: Text( - "username" - .i18n, - maxLines: - 1, - style: - TextStyle( - color: AppColors.of(context) - .loginPrimary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - Expanded( - child: Text( - "usernameHint" - .i18n, - maxLines: - 1, - textAlign: - TextAlign - .right, - style: - TextStyle( - color: AppColors.of(context) - .loginSecondary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - ], - ), - ), - Padding( - padding: - const EdgeInsets - .only( - bottom: - 12.0), - child: LoginInput( - style: - LoginInputStyle - .username, - controller: - usernameController, - ), - ), - - // password - Padding( - padding: - const EdgeInsets - .only( - bottom: - 6.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Expanded( - child: Text( - "password" - .i18n, - maxLines: - 1, - style: - TextStyle( - color: AppColors.of(context) - .loginPrimary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - Expanded( - child: Text( - "passwordHint" - .i18n, - maxLines: - 1, - textAlign: - TextAlign - .right, - style: - TextStyle( - color: AppColors.of(context) - .loginSecondary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - ], - ), - ), - Padding( - padding: - const EdgeInsets - .only( - bottom: - 12.0), - child: LoginInput( - style: - LoginInputStyle - .password, - controller: - passwordController, - ), - ), - - // school - Padding( - padding: - const EdgeInsets - .only( - bottom: - 6.0), - child: Text( - "school".i18n, - maxLines: 1, - style: - TextStyle( - color: AppColors.of( - context) - .loginPrimary, - fontWeight: - FontWeight - .w500, - fontSize: - 12.0, - ), - ), - ), - SchoolInput( - scroll: - _scrollController, - controller: - schoolController, - ), - ], - ), - ), - ), - const Padding( - padding: EdgeInsets.only( - left: 22.0, - right: 22.0, - top: 0.0, - ), - ), - Padding( - padding: - const EdgeInsets.only( - top: 35.0, - left: 22.0, - right: 22.0, - ), - child: Visibility( - visible: _loginState != - LoginState - .inProgress, - replacement: - const Padding( - padding: EdgeInsets - .symmetric( - vertical: - 6.0), - child: - CircularProgressIndicator( - valueColor: - AlwaysStoppedAnimation< - Color>( - Colors - .white), - ), - ), - child: LoginButton( - child: Text( - "login".i18n, - maxLines: 1, - style: - const TextStyle( - fontWeight: - FontWeight - .bold, - fontSize: 20.0, - )), - onPressed: () => - _loginAPI( - context: - context), - ), - ), - ), - ]), - ); - }, - ); - }, - child: Text( - "login".i18n, - style: const TextStyle( - fontFamily: 'Montserrat', - fontSize: 20, - fontWeight: FontWeight.w700), - )), - ), - ), - const SizedBox(height: 8), - ], - ), - ), - ), - ], + ), ), + // app icon + Padding( + padding: EdgeInsets.zero, + child: Image.asset( + 'assets/icons/ic_rounded.png', + width: 50.0, + ), + ), + + // texts + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10.0, + vertical: 12.0, + ), + child: Text( + 'reFilc', + style: TextStyle( + color: AppColors.of(context).loginPrimary, + fontSize: 28.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10.0, + ), + child: Text( + 'login_w_kreten'.i18n, + textAlign: TextAlign.center, + style: TextStyle( + color: AppColors.of(context).loginPrimary, + fontSize: 18.0, + fontWeight: FontWeight.w500, + height: 1.2, + ), + ), + ), + + const Spacer( + flex: 2, + ), + + // inputs + Padding( + padding: const EdgeInsets.only( + left: 22.0, + right: 22.0, + top: 0.0, + ), + child: AutofillGroup( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // username + Padding( + padding: const EdgeInsets.only(bottom: 6.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + "username".i18n, + maxLines: 1, + style: TextStyle( + color: AppColors.of(context).loginPrimary, + fontWeight: FontWeight.w500, + fontSize: 12.0, + ), + ), + ), + Expanded( + child: Text( + "usernameHint".i18n, + maxLines: 1, + textAlign: TextAlign.right, + style: TextStyle( + color: + AppColors.of(context).loginSecondary, + fontWeight: FontWeight.w500, + fontSize: 12.0, + ), + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 12.0), + child: LoginInput( + style: LoginInputStyle.username, + controller: usernameController, + ), + ), + + // password + Padding( + padding: const EdgeInsets.only(bottom: 6.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + "password".i18n, + maxLines: 1, + style: TextStyle( + color: AppColors.of(context).loginPrimary, + fontWeight: FontWeight.w500, + fontSize: 12.0, + ), + ), + ), + Expanded( + child: Text( + "passwordHint".i18n, + maxLines: 1, + textAlign: TextAlign.right, + style: TextStyle( + color: + AppColors.of(context).loginSecondary, + fontWeight: FontWeight.w500, + fontSize: 12.0, + ), + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 12.0), + child: LoginInput( + style: LoginInputStyle.password, + controller: passwordController, + ), + ), + + // school + Padding( + padding: const EdgeInsets.only(bottom: 6.0), + child: Text( + "school".i18n, + maxLines: 1, + style: TextStyle( + color: AppColors.of(context).loginPrimary, + fontWeight: FontWeight.w500, + fontSize: 12.0, + ), + ), + ), + SchoolInput( + scroll: _scrollController, + controller: schoolController, + ), + ], + ), + ), + ), + + // login button + Padding( + padding: const EdgeInsets.only( + top: 35.0, + left: 22.0, + right: 22.0, + ), + child: Visibility( + visible: _loginState != LoginState.inProgress, + replacement: const Padding( + padding: EdgeInsets.symmetric(vertical: 6.0), + child: CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation(Colors.white), + ), + ), + child: LoginButton( + child: Text("login".i18n, + maxLines: 1, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20.0, + )), + onPressed: () => _loginAPI(context: context), + ), + ), + ), + + // error messages if (_loginState == LoginState.missingFields || _loginState == LoginState.invalidGrant || _loginState == LoginState.failed) @@ -543,6 +312,8 @@ class LoginScreenState extends State { textAlign: TextAlign.center, ), ), + const SizedBox(height: 22.0), + // privacy policy GestureDetector( onTap: () => PrivacyView.show(context), @@ -555,6 +326,10 @@ class LoginScreenState extends State { ), ), ), + + const Spacer( + flex: 1, + ), ], ), ), diff --git a/refilc_mobile_ui/lib/screens/login/login_screen_new.dart b/refilc_mobile_ui/lib/screens/login/login_screen_new.dart new file mode 100644 index 0000000..a9f2dbd --- /dev/null +++ b/refilc_mobile_ui/lib/screens/login/login_screen_new.dart @@ -0,0 +1,618 @@ +// import 'dart:async'; + +import 'package:refilc/api/client.dart'; +import 'package:refilc/api/login.dart'; +import 'package:refilc/theme/colors/colors.dart'; +import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; +import 'package:refilc_mobile_ui/common/custom_snack_bar.dart'; +import 'package:refilc_mobile_ui/common/system_chrome.dart'; +import 'package:refilc_mobile_ui/common/widgets/absence/absence_display.dart'; +import 'package:refilc_mobile_ui/screens/login/login_button.dart'; +import 'package:refilc_mobile_ui/screens/login/login_input.dart'; +import 'package:refilc_mobile_ui/screens/login/school_input/school_input.dart'; +import 'package:refilc_mobile_ui/screens/settings/privacy_view.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'login_screen.i18n.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class LoginScreen extends StatefulWidget { + const LoginScreen({super.key, this.back = false}); + + final bool back; + + @override + LoginScreenState createState() => LoginScreenState(); +} + +class LoginScreenState extends State { + final usernameController = TextEditingController(); + final passwordController = TextEditingController(); + final schoolController = SchoolInputController(); + final _scrollController = ScrollController(); + + LoginState _loginState = LoginState.normal; + bool showBack = false; + + // Scaffold Gradient background + // final LinearGradient _backgroundGradient = const LinearGradient( + // colors: [ + // Color.fromARGB(255, 61, 122, 244), + // Color.fromARGB(255, 23, 77, 185), + // Color.fromARGB(255, 7, 42, 112), + // ], + // begin: Alignment(-0.8, -1.0), + // end: Alignment(0.8, 1.0), + // stops: [-1.0, 0.0, 1.0], + // ); + + late String tempUsername = ''; + + @override + void initState() { + super.initState(); + showBack = widget.back; + + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: Brightness.light, + systemNavigationBarColor: Colors.white, + systemNavigationBarIconBrightness: Brightness.dark, + )); + + FilcAPI.getSchools().then((schools) { + if (schools != null) { + schoolController.update(() { + schoolController.schools = schools; + }); + } else { + ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( + content: Text("schools_error".i18n, + style: const TextStyle(color: Colors.white)), + backgroundColor: AppColors.of(context).red, + context: context, + )); + } + }); + } + + @override + Widget build(BuildContext context) { + precacheImage(const AssetImage('assets/images/showcase1.png'), context); + precacheImage(const AssetImage('assets/images/showcase2.png'), context); + precacheImage(const AssetImage('assets/images/showcase3.png'), context); + precacheImage(const AssetImage('assets/images/showcase4.png'), context); + bool selected = false; + + return Scaffold( + body: Container( + decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), + child: SingleChildScrollView( + physics: const ClampingScrollPhysics(), + controller: _scrollController, + child: Container( + decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + child: SafeArea( + child: Column( + children: [ + // app icon + Padding( + padding: const EdgeInsets.only(left: 24, top: 20), + child: Row( + children: [ + Image.asset( + 'assets/icons/ic_rounded.png', + width: 30.0, + ), + const SizedBox(width: 8), + const Text( + 'reFilc', + style: TextStyle( + color: Color(0xFF050B15), + fontSize: 18.0, + fontWeight: FontWeight.bold, + fontFamily: 'Montserrat'), + ), + Material( + type: MaterialType.transparency, + child: showBack + ? BackButton(color: AppColors.of(context).text) + : const SizedBox(height: 48.0), + ), + ], + )), + Stack( + alignment: Alignment.bottomCenter, + children: [ + Column( + //login buttons and ui starts here + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const SizedBox(height: 21), + CarouselSlider( + options: CarouselOptions( + height: MediaQuery.of(context).size.height, + viewportFraction: 1, + autoPlay: true, + autoPlayInterval: const Duration(seconds: 6), + pauseAutoPlayOnTouch: true), + items: [1, 2, 3, 4].map((i) { + return Builder( + builder: (BuildContext context) { + return Column( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: + const EdgeInsets.only(left: 24), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text( + "welcome_title_$i".i18n, + style: const TextStyle( + color: Color(0xFF050B15), + fontSize: 19, + fontFamily: 'Montserrat', + fontWeight: FontWeight.w700, + height: 1.3), + ), + const SizedBox( + height: 14.375), //meth + Padding( + padding: const EdgeInsets.only( + right: 20), + child: Text( + "welcome_text_$i".i18n, + style: const TextStyle( + color: Color(0xFF050B15), + fontFamily: 'FigTree', + fontWeight: + FontWeight.w500, + fontSize: 17, + height: 1.3), + ), + ), + ], + )), + const SizedBox(height: 15.625), + Padding( + padding: const EdgeInsets.only( + left: 16, right: 16), + child: Image.asset( + 'assets/images/showcase$i.png')) + ], + ); + }, + ); + }).toList(), + ), + ], + ), + Container( + height: 300, + width: double.infinity, + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Color(0x00DAE4F7), Color(0xFFDAE4F7)], + stops: [0, 0.12], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: Padding( + padding: EdgeInsets.only(top: 50, bottom: MediaQuery.of(context).viewInsets.bottom), + child: Column( + children: [ + SizedBox( + height: 48, + width: double.infinity, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16), + child: FilledButton( + style: ButtonStyle( + shape: MaterialStateProperty.all< + RoundedRectangleBorder>( + const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(12)), + ))), + onPressed: () { + showModalBottomSheet( + backgroundColor: Colors.transparent, + context: context, + builder: (BuildContext context) { + return Container( + height: MediaQuery.of(context) + .size + .height * + 0.5 + MediaQuery.of(context).viewInsets.bottom, + decoration: const BoxDecoration( + color: Color(0xFFDAE4F7), + borderRadius: BorderRadius.only( + topRight: + Radius.circular(24.0), + topLeft: + Radius.circular(24.0), + ), + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Padding( + padding: + const EdgeInsets.only( + top: 18), + child: Container( + decoration: + const BoxDecoration( + color: + Color(0xFFB9C8E5), + borderRadius: + BorderRadius.only( + topRight: + Radius.circular( + 2.0), + topLeft: + Radius.circular( + 2.0), + ), + ), + width: 40, + height: 4, + ), + ), + Container( + width: double.infinity, + child: AutofillGroup( + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .end, + children: [ + // username + Padding( + padding: + const EdgeInsets + .only( + bottom: + 6.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Expanded( + child: Text( + "username" + .i18n, + maxLines: + 1, + style: + TextStyle( + color: AppColors.of(context) + .loginPrimary, + fontWeight: + FontWeight.w500, + fontSize: + 12.0, + ), + ), + ), + Expanded( + child: Text( + "usernameHint" + .i18n, + maxLines: + 1, + textAlign: + TextAlign + .right, + style: + TextStyle( + color: AppColors.of(context) + .loginSecondary, + fontWeight: + FontWeight.w500, + fontSize: + 12.0, + ), + ), + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets + .only( + bottom: + 12.0), + child: LoginInput( + style: + LoginInputStyle + .username, + controller: + usernameController, + ), + ), + + // password + Padding( + padding: + const EdgeInsets + .only( + bottom: + 6.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Expanded( + child: Text( + "password" + .i18n, + maxLines: + 1, + style: + TextStyle( + color: AppColors.of(context) + .loginPrimary, + fontWeight: + FontWeight.w500, + fontSize: + 12.0, + ), + ), + ), + Expanded( + child: Text( + "passwordHint" + .i18n, + maxLines: + 1, + textAlign: + TextAlign + .right, + style: + TextStyle( + color: AppColors.of(context) + .loginSecondary, + fontWeight: + FontWeight.w500, + fontSize: + 12.0, + ), + ), + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets + .only( + bottom: + 12.0), + child: LoginInput( + style: + LoginInputStyle + .password, + controller: + passwordController, + ), + ), + + // school + Padding( + padding: + const EdgeInsets + .only( + bottom: + 6.0), + child: Text( + "school".i18n, + maxLines: 1, + style: + TextStyle( + color: AppColors.of( + context) + .loginPrimary, + fontWeight: + FontWeight + .w500, + fontSize: + 12.0, + ), + ), + ), + SchoolInput( + scroll: + _scrollController, + controller: + schoolController, + ), + ], + ), + ), + ), + const Padding( + padding: EdgeInsets.only( + left: 22.0, + right: 22.0, + top: 0.0, + ), + ), + Padding( + padding: + const EdgeInsets.only( + top: 35.0, + left: 22.0, + right: 22.0, + ), + child: Visibility( + visible: _loginState != + LoginState + .inProgress, + replacement: + const Padding( + padding: EdgeInsets + .symmetric( + vertical: + 6.0), + child: + CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation< + Color>( + Colors + .white), + ), + ), + child: LoginButton( + child: Text( + "login".i18n, + maxLines: 1, + style: + const TextStyle( + fontWeight: + FontWeight + .bold, + fontSize: 20.0, + )), + onPressed: () => + _loginAPI( + context: + context), + ), + ), + ), + ]), + ); + }, + ); + }, + child: Text( + "login".i18n, + style: const TextStyle( + fontFamily: 'Montserrat', + fontSize: 20, + fontWeight: FontWeight.w700), + )), + ), + ), + const SizedBox(height: 8), + ], + ), + ), + ), + ], + ), + + if (_loginState == LoginState.missingFields || + _loginState == LoginState.invalidGrant || + _loginState == LoginState.failed) + Padding( + padding: const EdgeInsets.only( + top: 8.0, left: 12.0, right: 12.0), + child: Text( + [ + "missing_fields", + "invalid_grant", + "error" + ][_loginState.index] + .i18n, + style: const TextStyle( + color: Colors.red, + fontWeight: FontWeight.w500, + ), + textAlign: TextAlign.center, + ), + ), + // privacy policy + GestureDetector( + onTap: () => PrivacyView.show(context), + child: Text( + 'privacy'.i18n, + style: TextStyle( + color: AppColors.of(context).loginSecondary, + fontWeight: FontWeight.w500, + fontSize: 14.0, + ), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } + + void _loginAPI({required BuildContext context}) { + String username = usernameController.text; + String password = passwordController.text; + + tempUsername = username; + + if (username == "" || + password == "" || + schoolController.selectedSchool == null) { + return setState(() => _loginState = LoginState.missingFields); + } + + // ignore: no_leading_underscores_for_local_identifiers + void _callAPI() { + loginAPI( + username: username, + password: password, + instituteCode: schoolController.selectedSchool!.instituteCode, + context: context, + onLogin: (user) { + ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( + context: context, + brightness: Brightness.light, + content: Text("welcome".i18n.fill([user.name]), + overflow: TextOverflow.ellipsis), + )); + }, + onSuccess: () { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + setSystemChrome(context); + Navigator.of(context).pushReplacementNamed("login_to_navigation"); + }).then( + (res) => setState(() { + // if (res == LoginState.invalidGrant && + // tempUsername.replaceAll(username, '').length <= 3) { + // tempUsername = username + ' '; + // Timer( + // const Duration(milliseconds: 500), + // () => _loginAPI(context: context), + // ); + // // _loginAPI(context: context); + // } else { + _loginState = res; + // } + }), + ); + } + + setState(() => _loginState = LoginState.inProgress); + _callAPI(); + } +} From 0cc3aa07adc36743502714d939a39a58327a83e4 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 17:17:25 +0200 Subject: [PATCH 14/23] added room to lesson popup --- .../widgets/lesson/lesson_viewable.dart | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) 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 ae0aa31..b32e6b6 100644 --- a/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart @@ -398,13 +398,47 @@ class TimetableLessonPopup extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - '${DateFormat('H:mm').format(lesson.start)} - ${DateFormat('H:mm').format(lesson.end)}', - style: TextStyle( - color: AppColors.of(context).text.withOpacity(0.85), - fontSize: 14.0, - fontWeight: FontWeight.w500, - ), + Row( + children: [ + Text( + '${DateFormat('H:mm').format(lesson.start)} - ${DateFormat('H:mm').format(lesson.end)}', + style: TextStyle( + color: AppColors.of(context) + .text + .withOpacity(0.85), + fontSize: 14.0, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox( + width: 8.0, + ), + Container( + width: lesson.room.length > 20 ? 111 : null, + padding: const EdgeInsets.symmetric( + horizontal: 5.5, vertical: 3.0), + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .tertiary + .withOpacity(.15), + borderRadius: BorderRadius.circular(10.0), + ), + child: Text( + lesson.room, + overflow: TextOverflow.ellipsis, + style: TextStyle( + height: 1.1, + fontSize: 12.0, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .colorScheme + .secondary + .withOpacity(.9), + ), + ), + ), + ], ), const SizedBox( height: 12.0, From 55befca3aac81a21f062344cbd0bbec56d53fe76 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 17:17:47 +0200 Subject: [PATCH 15/23] last version bump before beta --- refilc/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/refilc/pubspec.yaml b/refilc/pubspec.yaml index 1ac99e5..84da3a2 100644 --- a/refilc/pubspec.yaml +++ b/refilc/pubspec.yaml @@ -3,7 +3,7 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak." homepage: https://refilc.hu publish_to: "none" -version: 5.0.0+256 +version: 5.0.0+257 environment: sdk: ">=2.17.0 <=3.3.2" From 49ebb8b1c3bb60934d1470a3144ca72596c57da2 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 17:22:07 +0200 Subject: [PATCH 16/23] added back timer for live activity --- refilc/lib/api/providers/live_card_provider.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/refilc/lib/api/providers/live_card_provider.dart b/refilc/lib/api/providers/live_card_provider.dart index bb71bac..c63c984 100644 --- a/refilc/lib/api/providers/live_card_provider.dart +++ b/refilc/lib/api/providers/live_card_provider.dart @@ -1,5 +1,7 @@ // ignore_for_file: no_leading_underscores_for_local_identifiers +import 'dart:async'; + import 'package:refilc/api/providers/liveactivity/platform_channel.dart'; import 'package:refilc/helpers/subject.dart'; import 'package:refilc/models/settings.dart'; @@ -37,6 +39,8 @@ class LiveCardProvider extends ChangeNotifier { // LiveCardState currentState = LiveCardState.empty; + // ignore: unused_field + late Timer _timer; late final TimetableProvider _timetable; late final SettingsProvider _settings; @@ -49,6 +53,7 @@ class LiveCardProvider extends ChangeNotifier { required SettingsProvider settings, }) : _timetable = timetable, _settings = settings { + _timer = Timer.periodic(const Duration(seconds: 1), (timer) => update()); _delay = settings.bellDelayEnabled ? Duration(seconds: settings.bellDelay) : Duration.zero; From 7488c9abddcf292b76f9887025cf41d27914e6b4 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 17:23:01 +0200 Subject: [PATCH 17/23] fixes --- .../lib/api/providers/live_card_provider.dart | 1 + .../lib/pages/home/home_page.dart | 2 +- .../lib/pages/timetable/timetable_page.dart | 1 - .../lib/screens/login/login_screen_new.dart | 1194 ++++++++--------- 4 files changed, 599 insertions(+), 599 deletions(-) diff --git a/refilc/lib/api/providers/live_card_provider.dart b/refilc/lib/api/providers/live_card_provider.dart index c63c984..1d581db 100644 --- a/refilc/lib/api/providers/live_card_provider.dart +++ b/refilc/lib/api/providers/live_card_provider.dart @@ -34,6 +34,7 @@ class LiveCardProvider extends ChangeNotifier { static bool hasDayEnd = false; static DateTime? storeFirstRunDate; static bool hasActivitySettingsChanged = false; + // ignore: non_constant_identifier_names static Map LAData = {}; static DateTime? now; // diff --git a/refilc_mobile_ui/lib/pages/home/home_page.dart b/refilc_mobile_ui/lib/pages/home/home_page.dart index b05a055..8a7218e 100644 --- a/refilc_mobile_ui/lib/pages/home/home_page.dart +++ b/refilc_mobile_ui/lib/pages/home/home_page.dart @@ -213,7 +213,7 @@ class HomePageState extends State with TickerProviderStateMixin { // } // TODO: REMOVE IN PRODUCTION BUILD!!! - print(_liveCard.currentState); + // print(_liveCard.currentState); // _liveCard.currentState = LiveCardState.duringLesson; return Scaffold( diff --git a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart index e77376b..03b983a 100644 --- a/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart +++ b/refilc_mobile_ui/lib/pages/timetable/timetable_page.dart @@ -1,6 +1,5 @@ import 'dart:math'; import 'package:animations/animations.dart'; -import 'package:flutter/widgets.dart'; import 'package:i18n_extension/i18n_extension.dart'; import 'package:refilc/api/providers/database_provider.dart'; import 'package:refilc/api/providers/update_provider.dart'; 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 a9f2dbd..7c9cab0 100644 --- a/refilc_mobile_ui/lib/screens/login/login_screen_new.dart +++ b/refilc_mobile_ui/lib/screens/login/login_screen_new.dart @@ -1,618 +1,618 @@ -// import 'dart:async'; +// // import 'dart:async'; -import 'package:refilc/api/client.dart'; -import 'package:refilc/api/login.dart'; -import 'package:refilc/theme/colors/colors.dart'; -import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; -import 'package:refilc_mobile_ui/common/custom_snack_bar.dart'; -import 'package:refilc_mobile_ui/common/system_chrome.dart'; -import 'package:refilc_mobile_ui/common/widgets/absence/absence_display.dart'; -import 'package:refilc_mobile_ui/screens/login/login_button.dart'; -import 'package:refilc_mobile_ui/screens/login/login_input.dart'; -import 'package:refilc_mobile_ui/screens/login/school_input/school_input.dart'; -import 'package:refilc_mobile_ui/screens/settings/privacy_view.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'login_screen.i18n.dart'; -import 'package:carousel_slider/carousel_slider.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +// import 'package:refilc/api/client.dart'; +// import 'package:refilc/api/login.dart'; +// import 'package:refilc/theme/colors/colors.dart'; +// import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart'; +// import 'package:refilc_mobile_ui/common/custom_snack_bar.dart'; +// import 'package:refilc_mobile_ui/common/system_chrome.dart'; +// import 'package:refilc_mobile_ui/common/widgets/absence/absence_display.dart'; +// import 'package:refilc_mobile_ui/screens/login/login_button.dart'; +// import 'package:refilc_mobile_ui/screens/login/login_input.dart'; +// import 'package:refilc_mobile_ui/screens/login/school_input/school_input.dart'; +// import 'package:refilc_mobile_ui/screens/settings/privacy_view.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'login_screen.i18n.dart'; +// import 'package:carousel_slider/carousel_slider.dart'; +// import 'package:flutter_svg/flutter_svg.dart'; -class LoginScreen extends StatefulWidget { - const LoginScreen({super.key, this.back = false}); +// class LoginScreen extends StatefulWidget { +// const LoginScreen({super.key, this.back = false}); - final bool back; +// final bool back; - @override - LoginScreenState createState() => LoginScreenState(); -} +// @override +// LoginScreenState createState() => LoginScreenState(); +// } -class LoginScreenState extends State { - final usernameController = TextEditingController(); - final passwordController = TextEditingController(); - final schoolController = SchoolInputController(); - final _scrollController = ScrollController(); +// class LoginScreenState extends State { +// final usernameController = TextEditingController(); +// final passwordController = TextEditingController(); +// final schoolController = SchoolInputController(); +// final _scrollController = ScrollController(); - LoginState _loginState = LoginState.normal; - bool showBack = false; +// LoginState _loginState = LoginState.normal; +// bool showBack = false; - // Scaffold Gradient background - // final LinearGradient _backgroundGradient = const LinearGradient( - // colors: [ - // Color.fromARGB(255, 61, 122, 244), - // Color.fromARGB(255, 23, 77, 185), - // Color.fromARGB(255, 7, 42, 112), - // ], - // begin: Alignment(-0.8, -1.0), - // end: Alignment(0.8, 1.0), - // stops: [-1.0, 0.0, 1.0], - // ); +// // Scaffold Gradient background +// // final LinearGradient _backgroundGradient = const LinearGradient( +// // colors: [ +// // Color.fromARGB(255, 61, 122, 244), +// // Color.fromARGB(255, 23, 77, 185), +// // Color.fromARGB(255, 7, 42, 112), +// // ], +// // begin: Alignment(-0.8, -1.0), +// // end: Alignment(0.8, 1.0), +// // stops: [-1.0, 0.0, 1.0], +// // ); - late String tempUsername = ''; +// late String tempUsername = ''; - @override - void initState() { - super.initState(); - showBack = widget.back; +// @override +// void initState() { +// super.initState(); +// showBack = widget.back; - SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( - statusBarColor: Colors.transparent, - statusBarIconBrightness: Brightness.light, - systemNavigationBarColor: Colors.white, - systemNavigationBarIconBrightness: Brightness.dark, - )); +// SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( +// statusBarColor: Colors.transparent, +// statusBarIconBrightness: Brightness.light, +// systemNavigationBarColor: Colors.white, +// systemNavigationBarIconBrightness: Brightness.dark, +// )); - FilcAPI.getSchools().then((schools) { - if (schools != null) { - schoolController.update(() { - schoolController.schools = schools; - }); - } else { - ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( - content: Text("schools_error".i18n, - style: const TextStyle(color: Colors.white)), - backgroundColor: AppColors.of(context).red, - context: context, - )); - } - }); - } +// FilcAPI.getSchools().then((schools) { +// if (schools != null) { +// schoolController.update(() { +// schoolController.schools = schools; +// }); +// } else { +// ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( +// content: Text("schools_error".i18n, +// style: const TextStyle(color: Colors.white)), +// backgroundColor: AppColors.of(context).red, +// context: context, +// )); +// } +// }); +// } - @override - Widget build(BuildContext context) { - precacheImage(const AssetImage('assets/images/showcase1.png'), context); - precacheImage(const AssetImage('assets/images/showcase2.png'), context); - precacheImage(const AssetImage('assets/images/showcase3.png'), context); - precacheImage(const AssetImage('assets/images/showcase4.png'), context); - bool selected = false; +// @override +// Widget build(BuildContext context) { +// precacheImage(const AssetImage('assets/images/showcase1.png'), context); +// precacheImage(const AssetImage('assets/images/showcase2.png'), context); +// precacheImage(const AssetImage('assets/images/showcase3.png'), context); +// precacheImage(const AssetImage('assets/images/showcase4.png'), context); +// bool selected = false; - return Scaffold( - body: Container( - decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), - child: SingleChildScrollView( - physics: const ClampingScrollPhysics(), - controller: _scrollController, - child: Container( - decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height, - child: SafeArea( - child: Column( - children: [ - // app icon - Padding( - padding: const EdgeInsets.only(left: 24, top: 20), - child: Row( - children: [ - Image.asset( - 'assets/icons/ic_rounded.png', - width: 30.0, - ), - const SizedBox(width: 8), - const Text( - 'reFilc', - style: TextStyle( - color: Color(0xFF050B15), - fontSize: 18.0, - fontWeight: FontWeight.bold, - fontFamily: 'Montserrat'), - ), - Material( - type: MaterialType.transparency, - child: showBack - ? BackButton(color: AppColors.of(context).text) - : const SizedBox(height: 48.0), - ), - ], - )), - Stack( - alignment: Alignment.bottomCenter, - children: [ - Column( - //login buttons and ui starts here - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - const SizedBox(height: 21), - CarouselSlider( - options: CarouselOptions( - height: MediaQuery.of(context).size.height, - viewportFraction: 1, - autoPlay: true, - autoPlayInterval: const Duration(seconds: 6), - pauseAutoPlayOnTouch: true), - items: [1, 2, 3, 4].map((i) { - return Builder( - builder: (BuildContext context) { - return Column( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: - const EdgeInsets.only(left: 24), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Text( - "welcome_title_$i".i18n, - style: const TextStyle( - color: Color(0xFF050B15), - fontSize: 19, - fontFamily: 'Montserrat', - fontWeight: FontWeight.w700, - height: 1.3), - ), - const SizedBox( - height: 14.375), //meth - Padding( - padding: const EdgeInsets.only( - right: 20), - child: Text( - "welcome_text_$i".i18n, - style: const TextStyle( - color: Color(0xFF050B15), - fontFamily: 'FigTree', - fontWeight: - FontWeight.w500, - fontSize: 17, - height: 1.3), - ), - ), - ], - )), - const SizedBox(height: 15.625), - Padding( - padding: const EdgeInsets.only( - left: 16, right: 16), - child: Image.asset( - 'assets/images/showcase$i.png')) - ], - ); - }, - ); - }).toList(), - ), - ], - ), - Container( - height: 300, - width: double.infinity, - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [Color(0x00DAE4F7), Color(0xFFDAE4F7)], - stops: [0, 0.12], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - ), - child: Padding( - padding: EdgeInsets.only(top: 50, bottom: MediaQuery.of(context).viewInsets.bottom), - child: Column( - children: [ - SizedBox( - height: 48, - width: double.infinity, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16), - child: FilledButton( - style: ButtonStyle( - shape: MaterialStateProperty.all< - RoundedRectangleBorder>( - const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(12)), - ))), - onPressed: () { - showModalBottomSheet( - backgroundColor: Colors.transparent, - context: context, - builder: (BuildContext context) { - return Container( - height: MediaQuery.of(context) - .size - .height * - 0.5 + MediaQuery.of(context).viewInsets.bottom, - decoration: const BoxDecoration( - color: Color(0xFFDAE4F7), - borderRadius: BorderRadius.only( - topRight: - Radius.circular(24.0), - topLeft: - Radius.circular(24.0), - ), - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Padding( - padding: - const EdgeInsets.only( - top: 18), - child: Container( - decoration: - const BoxDecoration( - color: - Color(0xFFB9C8E5), - borderRadius: - BorderRadius.only( - topRight: - Radius.circular( - 2.0), - topLeft: - Radius.circular( - 2.0), - ), - ), - width: 40, - height: 4, - ), - ), - Container( - width: double.infinity, - child: AutofillGroup( - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .end, - children: [ - // username - Padding( - padding: - const EdgeInsets - .only( - bottom: - 6.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Expanded( - child: Text( - "username" - .i18n, - maxLines: - 1, - style: - TextStyle( - color: AppColors.of(context) - .loginPrimary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - Expanded( - child: Text( - "usernameHint" - .i18n, - maxLines: - 1, - textAlign: - TextAlign - .right, - style: - TextStyle( - color: AppColors.of(context) - .loginSecondary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - ], - ), - ), - Padding( - padding: - const EdgeInsets - .only( - bottom: - 12.0), - child: LoginInput( - style: - LoginInputStyle - .username, - controller: - usernameController, - ), - ), +// return Scaffold( +// body: Container( +// decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), +// child: SingleChildScrollView( +// physics: const ClampingScrollPhysics(), +// controller: _scrollController, +// child: Container( +// decoration: const BoxDecoration(color: Color(0xFFDAE4F7)), +// width: MediaQuery.of(context).size.width, +// height: MediaQuery.of(context).size.height, +// child: SafeArea( +// child: Column( +// children: [ +// // app icon +// Padding( +// padding: const EdgeInsets.only(left: 24, top: 20), +// child: Row( +// children: [ +// Image.asset( +// 'assets/icons/ic_rounded.png', +// width: 30.0, +// ), +// const SizedBox(width: 8), +// const Text( +// 'reFilc', +// style: TextStyle( +// color: Color(0xFF050B15), +// fontSize: 18.0, +// fontWeight: FontWeight.bold, +// fontFamily: 'Montserrat'), +// ), +// Material( +// type: MaterialType.transparency, +// child: showBack +// ? BackButton(color: AppColors.of(context).text) +// : const SizedBox(height: 48.0), +// ), +// ], +// )), +// Stack( +// alignment: Alignment.bottomCenter, +// children: [ +// Column( +// //login buttons and ui starts here +// mainAxisAlignment: MainAxisAlignment.end, +// crossAxisAlignment: CrossAxisAlignment.end, +// children: [ +// const SizedBox(height: 21), +// CarouselSlider( +// options: CarouselOptions( +// height: MediaQuery.of(context).size.height, +// viewportFraction: 1, +// autoPlay: true, +// autoPlayInterval: const Duration(seconds: 6), +// pauseAutoPlayOnTouch: true), +// items: [1, 2, 3, 4].map((i) { +// return Builder( +// builder: (BuildContext context) { +// return Column( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// mainAxisAlignment: MainAxisAlignment.start, +// children: [ +// Padding( +// padding: +// const EdgeInsets.only(left: 24), +// child: Column( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// mainAxisAlignment: +// MainAxisAlignment.start, +// children: [ +// Text( +// "welcome_title_$i".i18n, +// style: const TextStyle( +// color: Color(0xFF050B15), +// fontSize: 19, +// fontFamily: 'Montserrat', +// fontWeight: FontWeight.w700, +// height: 1.3), +// ), +// const SizedBox( +// height: 14.375), //meth +// Padding( +// padding: const EdgeInsets.only( +// right: 20), +// child: Text( +// "welcome_text_$i".i18n, +// style: const TextStyle( +// color: Color(0xFF050B15), +// fontFamily: 'FigTree', +// fontWeight: +// FontWeight.w500, +// fontSize: 17, +// height: 1.3), +// ), +// ), +// ], +// )), +// const SizedBox(height: 15.625), +// Padding( +// padding: const EdgeInsets.only( +// left: 16, right: 16), +// child: Image.asset( +// 'assets/images/showcase$i.png')) +// ], +// ); +// }, +// ); +// }).toList(), +// ), +// ], +// ), +// Container( +// height: 300, +// width: double.infinity, +// decoration: const BoxDecoration( +// gradient: LinearGradient( +// colors: [Color(0x00DAE4F7), Color(0xFFDAE4F7)], +// stops: [0, 0.12], +// begin: Alignment.topCenter, +// end: Alignment.bottomCenter, +// ), +// ), +// child: Padding( +// padding: EdgeInsets.only(top: 50, bottom: MediaQuery.of(context).viewInsets.bottom), +// child: Column( +// children: [ +// SizedBox( +// height: 48, +// width: double.infinity, +// child: Padding( +// padding: const EdgeInsets.symmetric( +// horizontal: 16), +// child: FilledButton( +// style: ButtonStyle( +// shape: MaterialStateProperty.all< +// RoundedRectangleBorder>( +// const RoundedRectangleBorder( +// borderRadius: BorderRadius.all( +// Radius.circular(12)), +// ))), +// onPressed: () { +// showModalBottomSheet( +// backgroundColor: Colors.transparent, +// context: context, +// builder: (BuildContext context) { +// return Container( +// height: MediaQuery.of(context) +// .size +// .height * +// 0.5 + MediaQuery.of(context).viewInsets.bottom, +// decoration: const BoxDecoration( +// color: Color(0xFFDAE4F7), +// borderRadius: BorderRadius.only( +// topRight: +// Radius.circular(24.0), +// topLeft: +// Radius.circular(24.0), +// ), +// ), +// child: Column( +// crossAxisAlignment: +// CrossAxisAlignment.center, +// mainAxisAlignment: +// MainAxisAlignment.start, +// children: [ +// Padding( +// padding: +// const EdgeInsets.only( +// top: 18), +// child: Container( +// decoration: +// const BoxDecoration( +// color: +// Color(0xFFB9C8E5), +// borderRadius: +// BorderRadius.only( +// topRight: +// Radius.circular( +// 2.0), +// topLeft: +// Radius.circular( +// 2.0), +// ), +// ), +// width: 40, +// height: 4, +// ), +// ), +// Container( +// width: double.infinity, +// child: AutofillGroup( +// child: Column( +// crossAxisAlignment: +// CrossAxisAlignment +// .end, +// children: [ +// // username +// Padding( +// padding: +// const EdgeInsets +// .only( +// bottom: +// 6.0), +// child: Row( +// mainAxisAlignment: +// MainAxisAlignment +// .spaceBetween, +// children: [ +// Expanded( +// child: Text( +// "username" +// .i18n, +// maxLines: +// 1, +// style: +// TextStyle( +// color: AppColors.of(context) +// .loginPrimary, +// fontWeight: +// FontWeight.w500, +// fontSize: +// 12.0, +// ), +// ), +// ), +// Expanded( +// child: Text( +// "usernameHint" +// .i18n, +// maxLines: +// 1, +// textAlign: +// TextAlign +// .right, +// style: +// TextStyle( +// color: AppColors.of(context) +// .loginSecondary, +// fontWeight: +// FontWeight.w500, +// fontSize: +// 12.0, +// ), +// ), +// ), +// ], +// ), +// ), +// Padding( +// padding: +// const EdgeInsets +// .only( +// bottom: +// 12.0), +// child: LoginInput( +// style: +// LoginInputStyle +// .username, +// controller: +// usernameController, +// ), +// ), - // password - Padding( - padding: - const EdgeInsets - .only( - bottom: - 6.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Expanded( - child: Text( - "password" - .i18n, - maxLines: - 1, - style: - TextStyle( - color: AppColors.of(context) - .loginPrimary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - Expanded( - child: Text( - "passwordHint" - .i18n, - maxLines: - 1, - textAlign: - TextAlign - .right, - style: - TextStyle( - color: AppColors.of(context) - .loginSecondary, - fontWeight: - FontWeight.w500, - fontSize: - 12.0, - ), - ), - ), - ], - ), - ), - Padding( - padding: - const EdgeInsets - .only( - bottom: - 12.0), - child: LoginInput( - style: - LoginInputStyle - .password, - controller: - passwordController, - ), - ), +// // password +// Padding( +// padding: +// const EdgeInsets +// .only( +// bottom: +// 6.0), +// child: Row( +// mainAxisAlignment: +// MainAxisAlignment +// .spaceBetween, +// children: [ +// Expanded( +// child: Text( +// "password" +// .i18n, +// maxLines: +// 1, +// style: +// TextStyle( +// color: AppColors.of(context) +// .loginPrimary, +// fontWeight: +// FontWeight.w500, +// fontSize: +// 12.0, +// ), +// ), +// ), +// Expanded( +// child: Text( +// "passwordHint" +// .i18n, +// maxLines: +// 1, +// textAlign: +// TextAlign +// .right, +// style: +// TextStyle( +// color: AppColors.of(context) +// .loginSecondary, +// fontWeight: +// FontWeight.w500, +// fontSize: +// 12.0, +// ), +// ), +// ), +// ], +// ), +// ), +// Padding( +// padding: +// const EdgeInsets +// .only( +// bottom: +// 12.0), +// child: LoginInput( +// style: +// LoginInputStyle +// .password, +// controller: +// passwordController, +// ), +// ), - // school - Padding( - padding: - const EdgeInsets - .only( - bottom: - 6.0), - child: Text( - "school".i18n, - maxLines: 1, - style: - TextStyle( - color: AppColors.of( - context) - .loginPrimary, - fontWeight: - FontWeight - .w500, - fontSize: - 12.0, - ), - ), - ), - SchoolInput( - scroll: - _scrollController, - controller: - schoolController, - ), - ], - ), - ), - ), - const Padding( - padding: EdgeInsets.only( - left: 22.0, - right: 22.0, - top: 0.0, - ), - ), - Padding( - padding: - const EdgeInsets.only( - top: 35.0, - left: 22.0, - right: 22.0, - ), - child: Visibility( - visible: _loginState != - LoginState - .inProgress, - replacement: - const Padding( - padding: EdgeInsets - .symmetric( - vertical: - 6.0), - child: - CircularProgressIndicator( - valueColor: - AlwaysStoppedAnimation< - Color>( - Colors - .white), - ), - ), - child: LoginButton( - child: Text( - "login".i18n, - maxLines: 1, - style: - const TextStyle( - fontWeight: - FontWeight - .bold, - fontSize: 20.0, - )), - onPressed: () => - _loginAPI( - context: - context), - ), - ), - ), - ]), - ); - }, - ); - }, - child: Text( - "login".i18n, - style: const TextStyle( - fontFamily: 'Montserrat', - fontSize: 20, - fontWeight: FontWeight.w700), - )), - ), - ), - const SizedBox(height: 8), - ], - ), - ), - ), - ], - ), +// // school +// Padding( +// padding: +// const EdgeInsets +// .only( +// bottom: +// 6.0), +// child: Text( +// "school".i18n, +// maxLines: 1, +// style: +// TextStyle( +// color: AppColors.of( +// context) +// .loginPrimary, +// fontWeight: +// FontWeight +// .w500, +// fontSize: +// 12.0, +// ), +// ), +// ), +// SchoolInput( +// scroll: +// _scrollController, +// controller: +// schoolController, +// ), +// ], +// ), +// ), +// ), +// const Padding( +// padding: EdgeInsets.only( +// left: 22.0, +// right: 22.0, +// top: 0.0, +// ), +// ), +// Padding( +// padding: +// const EdgeInsets.only( +// top: 35.0, +// left: 22.0, +// right: 22.0, +// ), +// child: Visibility( +// visible: _loginState != +// LoginState +// .inProgress, +// replacement: +// const Padding( +// padding: EdgeInsets +// .symmetric( +// vertical: +// 6.0), +// child: +// CircularProgressIndicator( +// valueColor: +// AlwaysStoppedAnimation< +// Color>( +// Colors +// .white), +// ), +// ), +// child: LoginButton( +// child: Text( +// "login".i18n, +// maxLines: 1, +// style: +// const TextStyle( +// fontWeight: +// FontWeight +// .bold, +// fontSize: 20.0, +// )), +// onPressed: () => +// _loginAPI( +// context: +// context), +// ), +// ), +// ), +// ]), +// ); +// }, +// ); +// }, +// child: Text( +// "login".i18n, +// style: const TextStyle( +// fontFamily: 'Montserrat', +// fontSize: 20, +// fontWeight: FontWeight.w700), +// )), +// ), +// ), +// const SizedBox(height: 8), +// ], +// ), +// ), +// ), +// ], +// ), - if (_loginState == LoginState.missingFields || - _loginState == LoginState.invalidGrant || - _loginState == LoginState.failed) - Padding( - padding: const EdgeInsets.only( - top: 8.0, left: 12.0, right: 12.0), - child: Text( - [ - "missing_fields", - "invalid_grant", - "error" - ][_loginState.index] - .i18n, - style: const TextStyle( - color: Colors.red, - fontWeight: FontWeight.w500, - ), - textAlign: TextAlign.center, - ), - ), - // privacy policy - GestureDetector( - onTap: () => PrivacyView.show(context), - child: Text( - 'privacy'.i18n, - style: TextStyle( - color: AppColors.of(context).loginSecondary, - fontWeight: FontWeight.w500, - fontSize: 14.0, - ), - ), - ), - ], - ), - ), - ), - ), - ), - ); - } +// if (_loginState == LoginState.missingFields || +// _loginState == LoginState.invalidGrant || +// _loginState == LoginState.failed) +// Padding( +// padding: const EdgeInsets.only( +// top: 8.0, left: 12.0, right: 12.0), +// child: Text( +// [ +// "missing_fields", +// "invalid_grant", +// "error" +// ][_loginState.index] +// .i18n, +// style: const TextStyle( +// color: Colors.red, +// fontWeight: FontWeight.w500, +// ), +// textAlign: TextAlign.center, +// ), +// ), +// // privacy policy +// GestureDetector( +// onTap: () => PrivacyView.show(context), +// child: Text( +// 'privacy'.i18n, +// style: TextStyle( +// color: AppColors.of(context).loginSecondary, +// fontWeight: FontWeight.w500, +// fontSize: 14.0, +// ), +// ), +// ), +// ], +// ), +// ), +// ), +// ), +// ), +// ); +// } - void _loginAPI({required BuildContext context}) { - String username = usernameController.text; - String password = passwordController.text; +// void _loginAPI({required BuildContext context}) { +// String username = usernameController.text; +// String password = passwordController.text; - tempUsername = username; +// tempUsername = username; - if (username == "" || - password == "" || - schoolController.selectedSchool == null) { - return setState(() => _loginState = LoginState.missingFields); - } +// if (username == "" || +// password == "" || +// schoolController.selectedSchool == null) { +// return setState(() => _loginState = LoginState.missingFields); +// } - // ignore: no_leading_underscores_for_local_identifiers - void _callAPI() { - loginAPI( - username: username, - password: password, - instituteCode: schoolController.selectedSchool!.instituteCode, - context: context, - onLogin: (user) { - ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( - context: context, - brightness: Brightness.light, - content: Text("welcome".i18n.fill([user.name]), - overflow: TextOverflow.ellipsis), - )); - }, - onSuccess: () { - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - setSystemChrome(context); - Navigator.of(context).pushReplacementNamed("login_to_navigation"); - }).then( - (res) => setState(() { - // if (res == LoginState.invalidGrant && - // tempUsername.replaceAll(username, '').length <= 3) { - // tempUsername = username + ' '; - // Timer( - // const Duration(milliseconds: 500), - // () => _loginAPI(context: context), - // ); - // // _loginAPI(context: context); - // } else { - _loginState = res; - // } - }), - ); - } +// // ignore: no_leading_underscores_for_local_identifiers +// void _callAPI() { +// loginAPI( +// username: username, +// password: password, +// instituteCode: schoolController.selectedSchool!.instituteCode, +// context: context, +// onLogin: (user) { +// ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( +// context: context, +// brightness: Brightness.light, +// content: Text("welcome".i18n.fill([user.name]), +// overflow: TextOverflow.ellipsis), +// )); +// }, +// onSuccess: () { +// ScaffoldMessenger.of(context).hideCurrentSnackBar(); +// setSystemChrome(context); +// Navigator.of(context).pushReplacementNamed("login_to_navigation"); +// }).then( +// (res) => setState(() { +// // if (res == LoginState.invalidGrant && +// // tempUsername.replaceAll(username, '').length <= 3) { +// // tempUsername = username + ' '; +// // Timer( +// // const Duration(milliseconds: 500), +// // () => _loginAPI(context: context), +// // ); +// // // _loginAPI(context: context); +// // } else { +// _loginState = res; +// // } +// }), +// ); +// } - setState(() => _loginState = LoginState.inProgress); - _callAPI(); - } -} +// setState(() => _loginState = LoginState.inProgress); +// _callAPI(); +// } +// } From d915200faac1dceeaac869e5be4f8782ecde41b9 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 21:11:13 +0200 Subject: [PATCH 18/23] made task creation flow --- .../lib/api/providers/self_note_provider.dart | 37 ++++ refilc/lib/database/init.dart | 4 +- refilc/lib/database/query.dart | 12 ++ refilc/lib/database/store.dart | 7 + refilc/lib/models/self_note.dart | 34 ++++ .../lib/pages/grades/grades_page.dart | 2 + .../lib/pages/notes/notes_page.dart | 177 +++++++++++++++++- .../lib/pages/notes/notes_page.i18n.dart | 12 ++ .../notes/submenu/create_image_note.dart | 1 + .../lib/pages/notes/submenu/notes_screen.dart | 1 + 10 files changed, 284 insertions(+), 3 deletions(-) diff --git a/refilc/lib/api/providers/self_note_provider.dart b/refilc/lib/api/providers/self_note_provider.dart index 3a095b7..4be70a5 100644 --- a/refilc/lib/api/providers/self_note_provider.dart +++ b/refilc/lib/api/providers/self_note_provider.dart @@ -7,17 +7,23 @@ import 'package:provider/provider.dart'; class SelfNoteProvider with ChangeNotifier { late List _notes; + late List _todoItems; late BuildContext _context; + List get notes => _notes; + List get todos => _todoItems; SelfNoteProvider({ List initialNotes = const [], + List initialTodoItems = const [], required BuildContext context, }) { _notes = List.castFrom(initialNotes); + _todoItems = List.castFrom(initialTodoItems); _context = context; if (_notes.isEmpty) restore(); + if (_todoItems.isEmpty) restoreTodo(); } // restore self notes from db @@ -38,6 +44,24 @@ class SelfNoteProvider with ChangeNotifier { } } + // restore todo items from db + Future restoreTodo() async { + String? userId = Provider.of(_context, listen: false).id; + + // await Provider.of(_context, listen: false) + // .userStore + // .storeSelfNotes([], userId: userId!); + + // load self notes from db + if (userId != null) { + var dbTodo = await Provider.of(_context, listen: false) + .userQuery + .getTodoItems(userId: userId); + _todoItems = dbTodo; + notifyListeners(); + } + } + // fetches fresh data from api (not needed, cuz no api for that) // Future fetch() async { // } @@ -54,4 +78,17 @@ class SelfNoteProvider with ChangeNotifier { _notes = notes; notifyListeners(); } + + // store todo items in db + Future storeTodo(List todos) async { + User? user = Provider.of(_context, listen: false).user; + if (user == null) throw "Cannot store Self Notes for User null"; + String userId = user.id; + + await Provider.of(_context, listen: false) + .userStore + .storeSelfTodoItems(todos, userId: userId); + _todoItems = todos; + notifyListeners(); + } } diff --git a/refilc/lib/database/init.dart b/refilc/lib/database/init.dart index 23960a9..0d2822a 100644 --- a/refilc/lib/database/init.dart +++ b/refilc/lib/database/init.dart @@ -84,7 +84,7 @@ const userDataDB = DatabaseStruct("user_data", { "goal_befores": String, "goal_pin_dates": String, // todo and notes - "todo_items": String, "self_notes": String, + "todo_items": String, "self_notes": String, "self_todo": String, // v5 shit "roundings": String, "grade_rarities": String, @@ -152,7 +152,7 @@ Future initDB(DatabaseProvider database) async { "goal_befores": "{}", "goal_pin_dates": "{}", // todo and notes - "todo_items": "{}", "self_notes": "[]", + "todo_items": "{}", "self_notes": "[]", "self_todo": "[]", // v5 shit "roundings": "{}", "grade_rarities": "{}", diff --git a/refilc/lib/database/query.dart b/refilc/lib/database/query.dart index e899e6d..741a253 100644 --- a/refilc/lib/database/query.dart +++ b/refilc/lib/database/query.dart @@ -317,6 +317,18 @@ class UserDatabaseQuery { return selfNotes; } + Future> getTodoItems({required String userId}) async { + List userData = + await db.query("user_data", where: "id = ?", whereArgs: [userId]); + if (userData.isEmpty) return []; + String? todoItemsJson = userData.elementAt(0)["self_todo"] as String?; + if (todoItemsJson == null) return []; + List todoItems = (jsonDecode(todoItemsJson) as List) + .map((e) => TodoItem.fromJson(e)) + .toList(); + return todoItems; + } + // v5 Future> getRoundings({required String userId}) async { List userData = diff --git a/refilc/lib/database/store.dart b/refilc/lib/database/store.dart index 6132780..46929c0 100644 --- a/refilc/lib/database/store.dart +++ b/refilc/lib/database/store.dart @@ -196,6 +196,13 @@ class UserDatabaseStore { where: "id = ?", whereArgs: [userId]); } + Future storeSelfTodoItems(List todoItems, + {required String userId}) async { + String todoItemsJson = jsonEncode(todoItems.map((e) => e.json).toList()); + await db.update("user_data", {"self_todo": todoItemsJson}, + where: "id = ?", whereArgs: [userId]); + } + // v5 Future storeRoundings(Map roundings, {required String userId}) async { diff --git a/refilc/lib/models/self_note.dart b/refilc/lib/models/self_note.dart index bd86a1d..cbaf42b 100644 --- a/refilc/lib/models/self_note.dart +++ b/refilc/lib/models/self_note.dart @@ -33,3 +33,37 @@ class SelfNote { 'note_type': noteType == NoteType.image ? 'image' : 'text', }; } + +class TodoItem { + String id; + String title; + String content; + bool done; + + Map? json; + + TodoItem({ + required this.id, + required this.title, + required this.content, + required this.done, + this.json, + }); + + factory TodoItem.fromJson(Map json) { + return TodoItem( + id: json['id'], + title: json['title'], + content: json['content'], + done: json['done'], + json: json, + ); + } + + get toJson => { + 'id': id, + 'title': title, + 'content': content, + 'done': done, + }; +} diff --git a/refilc_mobile_ui/lib/pages/grades/grades_page.dart b/refilc_mobile_ui/lib/pages/grades/grades_page.dart index 6f8d084..9cb4742 100644 --- a/refilc_mobile_ui/lib/pages/grades/grades_page.dart +++ b/refilc_mobile_ui/lib/pages/grades/grades_page.dart @@ -667,6 +667,8 @@ class GradesPageState extends State { // SoonAlert.show(context: context); gradeCalcTotal(context); + + Navigator.of(context, rootNavigator: true).pop(); }, ), ), diff --git a/refilc_mobile_ui/lib/pages/notes/notes_page.dart b/refilc_mobile_ui/lib/pages/notes/notes_page.dart index b9550b0..47c509f 100644 --- a/refilc_mobile_ui/lib/pages/notes/notes_page.dart +++ b/refilc_mobile_ui/lib/pages/notes/notes_page.dart @@ -35,6 +35,7 @@ import 'package:refilc_plus/models/premium_scopes.dart'; import 'package:refilc_plus/providers/plus_provider.dart'; import 'package:refilc_plus/ui/mobile/plus/premium_inline.dart'; import 'package:refilc_plus/ui/mobile/plus/upsell.dart'; +import 'package:uuid/uuid.dart'; import 'notes_page.i18n.dart'; enum AbsenceFilter { absences, delays, misses } @@ -65,9 +66,14 @@ class NotesPageState extends State with TickerProviderStateMixin { Map doneItems = {}; List noteTiles = []; + List todoItems = []; + + final TextEditingController _taskName = TextEditingController(); + final TextEditingController _taskContent = TextEditingController(); void generateTiles() async { doneItems = await databaseProvider.userQuery.toDoItems(userId: user.id!); + todoItems = await databaseProvider.userQuery.getTodoItems(userId: user.id!); List tiles = []; @@ -82,7 +88,7 @@ class NotesPageState extends State with TickerProviderStateMixin { List toDoTiles = []; if (hw.isNotEmpty && - !Provider.of(context, listen: false) + Provider.of(context, listen: false) .hasScope(PremiumScopes.unlimitedSelfNotes)) { toDoTiles.addAll(hw.map((e) => TickTile( padding: EdgeInsets.zero, @@ -102,6 +108,21 @@ class NotesPageState extends State with TickerProviderStateMixin { ))); } + if (selfNoteProvider.todos.isNotEmpty) { + toDoTiles.addAll(selfNoteProvider.todos.map((e) => TickTile( + padding: EdgeInsets.zero, + title: e.title, + description: e.content, + isTicked: e.done, + onTap: (p0) async { + todoItems.firstWhere((element) => element.id == e.id).done = p0; + + await databaseProvider.userStore + .storeSelfTodoItems(todoItems, userId: user.id!); + }, + ))); + } + if (toDoTiles.isNotEmpty) { tiles.add(const SizedBox( height: 10.0, @@ -313,6 +334,8 @@ class NotesPageState extends State with TickerProviderStateMixin { .fetch( from: DateTime.now().subtract(const Duration(days: 30))); Provider.of(context, listen: false).restore(); + Provider.of(context, listen: false) + .restoreTodo(); generateTiles(); @@ -410,7 +433,159 @@ class NotesPageState extends State with TickerProviderStateMixin { }, ), ), + const SizedBox( + height: 10.0, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: ListTile( + title: Row( + children: [ + const Icon(Icons.task_outlined), + const SizedBox( + width: 10.0, + ), + Text('new_task'.i18n), + ], + ), + onTap: () { + if (!Provider.of(context, listen: false) + .hasScope(PremiumScopes.unlimitedSelfNotes)) { + PlusLockedFeaturePopup.show( + context: context, feature: PremiumFeature.selfNotes); + + return; + } + + showTaskCreation(context); + }, + ), + ), ]), ); } + + void showTaskCreation(context) { + 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("new_task".i18n), + content: Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 10.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: _taskName, + 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: "task_name".i18n, + suffixIcon: IconButton( + icon: const Icon( + FeatherIcons.x, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _taskName.text = ""; + }); + }, + ), + ), + ), + const SizedBox( + height: 10.0, + ), + TextField( + controller: _taskContent, + 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: "task_content".i18n, + suffixIcon: IconButton( + icon: const Icon( + FeatherIcons.x, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _taskContent.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 { + todoItems.add(TodoItem.fromJson({ + 'id': const Uuid().v4(), + 'title': _taskName.text.replaceAll(' ', '') != "" + ? _taskName.text + : 'no_title'.i18n, + 'content': _taskContent.text, + 'done': false, + })); + + await databaseProvider.userStore + .storeSelfTodoItems(todoItems, userId: user.id!); + + setState(() { + _taskName.text = ""; + _taskContent.text = ""; + }); + + Provider.of(context, listen: false).restore(); + Provider.of(context, listen: false) + .restoreTodo(); + + generateTiles(); + + Navigator.of(context).pop(true); + }, + ), + ], + ), + ); + } } diff --git a/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart b/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart index f452a9e..28bc703 100644 --- a/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart +++ b/refilc_mobile_ui/lib/pages/notes/notes_page.i18n.dart @@ -14,6 +14,10 @@ extension ScreensLocalization on String { "hint_t": "Note title...", "your_notes": "Your Notes", "new_image": "New Image", + "no_title": "No title", + "task_content": "Task content...", + "task_name": "Task title...", + "new_task": "New Task", }, "hu_hu": { "notes": "Füzet", @@ -26,6 +30,10 @@ extension ScreensLocalization on String { "hint_t": "Jegyzet címe...", "your_notes": "Jegyzeteid", "new_image": "Új kép", + "no_title": "Nincs cím", + "task_content": "Feladat tartalma...", + "task_name": "Feladat címe...", + "new_task": "Új feladat", }, "de_de": { "notes": "Broschüre", @@ -38,6 +46,10 @@ extension ScreensLocalization on String { "hint_t": "Titel notieren...", "your_notes": "Deine Noten", "new_image": "Neues Bild", + "no_title": "Kein Titel", + "task_content": "Aufgabeninhalt...", + "task_name": "Aufgabentitel...", + "new_task": "Neue Aufgabe", }, }; diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart b/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart index c81faf7..9da532b 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart @@ -143,6 +143,7 @@ class _ImageNoteEditorState extends State { .storeSelfNotes(selfNotes, userId: widget.u.id); Provider.of(context, listen: false).restore(); + Provider.of(context, listen: false).restoreTodo(); debugPrint('$file'); } diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.dart b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.dart index 8f2795a..df9b01b 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.dart @@ -268,6 +268,7 @@ class NotesScreenState extends State { Provider.of(context, listen: false) .fetch(from: DateTime.now().subtract(const Duration(days: 30))); Provider.of(context, listen: false).restore(); + Provider.of(context, listen: false).restoreTodo(); return Future(() => null); }, From c9db496e59c6fbb345f1a601ab424063d9105034 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 21:39:22 +0200 Subject: [PATCH 19/23] fixed text overflow and teacher custom name --- .../common/widgets/exam/exam_viewable.dart | 20 ++++++++++++------- .../widgets/lesson/lesson_viewable.dart | 8 +++++++- 2 files changed, 20 insertions(+), 8 deletions(-) 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 c8b33be..60a67ab 100644 --- a/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/exam/exam_viewable.dart @@ -210,13 +210,19 @@ class ExamPopup extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - exam.description.capital(), - style: TextStyle( - color: - AppColors.of(context).text.withOpacity(0.9), - fontSize: 16.0, - fontWeight: FontWeight.w600, + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: Text( + exam.description.capital(), + style: TextStyle( + color: AppColors.of(context) + .text + .withOpacity(0.9), + fontSize: 16.0, + fontWeight: FontWeight.w600, + ), + maxLines: 3, + overflow: TextOverflow.ellipsis, ), ), Text( 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 b32e6b6..507c65e 100644 --- a/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart +++ b/refilc_mobile_ui/lib/common/widgets/lesson/lesson_viewable.dart @@ -466,7 +466,13 @@ class TimetableLessonPopup extends StatelessWidget { height: 8.0, ), Text( - lesson.teacher.name, + (lesson.teacher.isRenamed && + Provider.of(context, + listen: false) + .renamedTeachersEnabled) + ? (lesson.teacher.renamedTo ?? + lesson.teacher.name) + : lesson.teacher.name, style: TextStyle( color: AppColors.of(context).text.withOpacity(0.9), fontSize: 14.0, From f64b1360d9a40f770b1956874d9ca93db841a5ae Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 21:53:39 +0200 Subject: [PATCH 20/23] images are now removable --- .../lib/pages/notes/notes_page.dart | 45 +++--- .../pages/notes/submenu/note_view_screen.dart | 129 ++++++++++-------- .../notes/submenu/notes_screen.i18n.dart | 3 + 3 files changed, 101 insertions(+), 76 deletions(-) diff --git a/refilc_mobile_ui/lib/pages/notes/notes_page.dart b/refilc_mobile_ui/lib/pages/notes/notes_page.dart index 47c509f..f777747 100644 --- a/refilc_mobile_ui/lib/pages/notes/notes_page.dart +++ b/refilc_mobile_ui/lib/pages/notes/notes_page.dart @@ -149,26 +149,31 @@ class NotesPageState extends State with TickerProviderStateMixin { CupertinoPageRoute( builder: (context) => NoteViewScreen(note: e))), ) - : Container( - height: MediaQuery.of(context).size.width / 2.42, - width: MediaQuery.of(context).size.width / 2.42, - decoration: BoxDecoration( - boxShadow: [ - if (Provider.of(context, listen: false) - .shadowEffect) - BoxShadow( - offset: const Offset(0, 21), - blurRadius: 23.0, - color: Theme.of(context).shadowColor, - ), - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(16.0), - child: Image.memory( - const Base64Decoder().convert(e.content), - fit: BoxFit.cover, - gaplessPlayback: true, + : GestureDetector( + onTap: () => Navigator.of(context, rootNavigator: true).push( + CupertinoPageRoute( + builder: (context) => NoteViewScreen(note: e))), + child: Container( + height: MediaQuery.of(context).size.width / 2.42, + width: MediaQuery.of(context).size.width / 2.42, + decoration: BoxDecoration( + boxShadow: [ + if (Provider.of(context, listen: false) + .shadowEffect) + BoxShadow( + offset: const Offset(0, 21), + blurRadius: 23.0, + color: Theme.of(context).shadowColor, + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(16.0), + child: Image.memory( + const Base64Decoder().convert(e.content), + fit: BoxFit.cover, + gaplessPlayback: true, + ), ), ), ), diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/note_view_screen.dart b/refilc_mobile_ui/lib/pages/notes/submenu/note_view_screen.dart index 5ea5ddd..6c53209 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/note_view_screen.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/note_view_screen.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:refilc/api/providers/self_note_provider.dart'; import 'package:refilc/models/self_note.dart'; @@ -8,6 +10,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:provider/provider.dart'; import 'package:markdown/markdown.dart' as md; +import 'notes_screen.i18n.dart'; class NoteViewScreen extends StatefulWidget { const NoteViewScreen({super.key, required this.note}); @@ -30,7 +33,9 @@ class NoteViewScreenState extends State { surfaceTintColor: Theme.of(context).scaffoldBackgroundColor, leading: BackButton(color: AppColors.of(context).text), title: Text( - widget.note.title ?? '${widget.note.content.split(' ')[0]}...', + widget.note.noteType == NoteType.text + ? (widget.note.title ?? '${widget.note.content.split(' ')[0]}...') + : 'image_note'.i18n, style: TextStyle( color: AppColors.of(context).text, fontSize: 26.0, @@ -38,52 +43,55 @@ class NoteViewScreenState extends State { ), ), actions: [ - ClipRRect( - borderRadius: BorderRadius.circular(10.1), - child: GestureDetector( - onTap: () { - // handle tap - Navigator.of(context, rootNavigator: true).push( - CupertinoPageRoute( - builder: (context) => - AddNoteScreen(initialNote: widget.note))); - }, - child: Container( - color: Theme.of(context).colorScheme.secondary.withOpacity(0.2), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Stack( - children: [ - IconTheme( - data: IconThemeData( - color: Theme.of(context).colorScheme.secondary, + if (widget.note.noteType == NoteType.text) + ClipRRect( + borderRadius: BorderRadius.circular(10.1), + child: GestureDetector( + onTap: () { + // handle tap + Navigator.of(context, rootNavigator: true).push( + CupertinoPageRoute( + builder: (context) => + AddNoteScreen(initialNote: widget.note))); + }, + child: Container( + color: + Theme.of(context).colorScheme.secondary.withOpacity(0.2), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Stack( + children: [ + IconTheme( + data: IconThemeData( + color: Theme.of(context).colorScheme.secondary, + ), + child: const Icon( + FeatherIcons.edit, + size: 20.0, + ), ), - child: const Icon( - FeatherIcons.edit, - size: 20.0, + IconTheme( + data: IconThemeData( + color: + Theme.of(context).brightness == Brightness.light + ? Colors.black.withOpacity(.5) + : Colors.white.withOpacity(.3), + ), + child: const Icon( + FeatherIcons.edit, + size: 20.0, + ), ), - ), - IconTheme( - data: IconThemeData( - color: - Theme.of(context).brightness == Brightness.light - ? Colors.black.withOpacity(.5) - : Colors.white.withOpacity(.3), - ), - child: const Icon( - FeatherIcons.edit, - size: 20.0, - ), - ), - ], + ], + ), ), ), ), ), - ), - const SizedBox( - width: 10, - ), + if (widget.note.noteType == NoteType.text) + const SizedBox( + width: 10, + ), ClipRRect( borderRadius: BorderRadius.circular(10.1), child: GestureDetector( @@ -140,21 +148,30 @@ class NoteViewScreenState extends State { child: Column( children: [ Expanded( - child: MarkdownBody( - data: widget.note.content, - extensionSet: md.ExtensionSet( - md.ExtensionSet.gitHubFlavored.blockSyntaxes, - [ - md.EmojiSyntax(), - ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes - ], - ), - styleSheet: MarkdownStyleSheet( - p: const TextStyle( - fontSize: 15.0, - ), - ), - ), + child: widget.note.noteType == NoteType.text + ? MarkdownBody( + data: widget.note.content, + extensionSet: md.ExtensionSet( + md.ExtensionSet.gitHubFlavored.blockSyntaxes, + [ + md.EmojiSyntax(), + ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes + ], + ), + styleSheet: MarkdownStyleSheet( + p: const TextStyle( + fontSize: 15.0, + ), + ), + ) + : ClipRRect( + borderRadius: BorderRadius.circular(10.0), + child: Image.memory( + const Base64Decoder().convert(widget.note.content), + fit: BoxFit.contain, + gaplessPlayback: true, + ), + ), ), // Expanded( // child: Text( diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart index bbe6033..77d6128 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart @@ -18,6 +18,7 @@ extension SettingsLocalization on String { "click_here": "Click here", "select_image": "to select an image", "new_image": "New Image", + "image_note": "Image", }, "hu_hu": { "notes": "Füzet", @@ -34,6 +35,7 @@ extension SettingsLocalization on String { "click_here": "Kattints ide", "select_image": "kép kiválasztásához", "new_image": "Új kép", + "image_note": "Kép", }, "de_de": { "notes": "Broschüre", @@ -50,6 +52,7 @@ extension SettingsLocalization on String { "click_here": "Klicken Sie hier", "select_image": "um ein Bild auszuwählen", "new_image": "Neues Bild", + "image_note": "Bild", }, }; From 3ed456c01fc5be7f7d72657ac4e59bc66baaa662 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 21:55:05 +0200 Subject: [PATCH 21/23] fixed subject page padding --- refilc_mobile_ui/lib/pages/grades/grades_page.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/refilc_mobile_ui/lib/pages/grades/grades_page.dart b/refilc_mobile_ui/lib/pages/grades/grades_page.dart index 9cb4742..0a50cde 100644 --- a/refilc_mobile_ui/lib/pages/grades/grades_page.dart +++ b/refilc_mobile_ui/lib/pages/grades/grades_page.dart @@ -267,6 +267,12 @@ class GradesPageState extends State { ), ), ), + if (hasHomework && + nearestExam != null && + Provider.of(context).qSubjectsSubTiles) + const SizedBox( + height: 6.0, + ), if (nearestExam != null && Provider.of(context).qSubjectsSubTiles) Container( From e04cc5ea2bf53ba3643f0edab8079a17f51cc04f Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 22:20:24 +0200 Subject: [PATCH 22/23] added analytics warning --- .../lib/plus/components/plan_card.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/refilc_mobile_ui/lib/plus/components/plan_card.dart b/refilc_mobile_ui/lib/plus/components/plan_card.dart index d1a9567..27b0c9b 100644 --- a/refilc_mobile_ui/lib/plus/components/plan_card.dart +++ b/refilc_mobile_ui/lib/plus/components/plan_card.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:refilc/models/settings.dart'; import 'package:refilc_plus/providers/plus_provider.dart'; import 'package:refilc_plus/ui/mobile/plus/activation_view/activation_view.dart'; import 'package:refilc_mobile_ui/plus/plus_screen.i18n.dart'; @@ -50,6 +51,19 @@ class PlusPlanCard extends StatelessWidget { return; } + if (Provider.of(context).xFilcId == "none") { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + content: Text( + "Be kell kapcsolnod a Névtelen Analitikát a beállítások főoldalán, mielőtt reFilc+ előfizetést vásárolnál!", + style: + TextStyle(color: Colors.black, fontWeight: FontWeight.bold), + ), + backgroundColor: Colors.white, + )); + + return; + } + if (Provider.of(context, listen: false).hasPremium) { if (!active) { launchUrl( From c85f15eb497978f2a6a2139daabee5ae52c91458 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 5 May 2024 22:21:40 +0200 Subject: [PATCH 23/23] updated build number --- refilc/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/refilc/pubspec.yaml b/refilc/pubspec.yaml index 84da3a2..904b70f 100644 --- a/refilc/pubspec.yaml +++ b/refilc/pubspec.yaml @@ -3,7 +3,7 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak." homepage: https://refilc.hu publish_to: "none" -version: 5.0.0+257 +version: 5.0.0+258 environment: sdk: ">=2.17.0 <=3.3.2"