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 f991fd77..4257c182 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 e4a26c00..2cc04b99 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 1c0c0293..1970da85 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 8e1d4624..127fedee 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 8e1d4624..127fedee 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 39cc8c69..dfc7c68d 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 89392758..8a7218e7 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 3cf6f4b9..1d36bd25 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 21a3cc14..00000000 --- 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 18d98100..00000000 --- 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 f9b0d7c5..00000000 --- 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 00000000..21a3cc14 --- /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 00000000..18d98100 --- /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 00000000..f9b0d7c5 --- /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 04a8ade5..ebe191e4 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 574d3ab0..0d449541 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 d06a6009..23960a98 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 f4bb86be..da4976bc 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 0d449541..1f5cca7b 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 9cea67f6..72d23f13 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 152046a9..df27bc0a 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 00000000..aa7f080d --- /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 1acae125..8b4594ba 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 f2041daa..de1cde11 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 35e34251..f2b33012 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 7bb49772..9a64aa28 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 17e624c8..894ac41c 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 1cca6689..8b4f391e 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 88f1030c..3d187080 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 1985e342..59eee56b 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 da4976bc..f31fbb4c 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 c2d9f316..843090d9 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 e566eeae..75959e23 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 dfc7c68d..1ac99e57 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 7ace094c..6cf5c6e1 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 b19816c3..3a095b75 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 609f6ff4..bd86a1d4 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 8b4594ba..e1a92159 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 de1cde11..f2041daa 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 f2b33012..3dcae9ac 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 8b4f391e..70f77872 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 3d187080..6f8d0848 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 8f22f653..ed8e2e80 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 1d36bd25..922070a1 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 61ff85c3..b9550b0e 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 7924e35d..f452a9e6 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 4cbe5cfa..30c9bb3b 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 00000000..c81faf78 --- /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 02c848b0..bbe60335 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 f31fbb4c..e77376bd 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 3dcae9ac..93808067 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 0366af79..c8b33be3 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 70f77872..ae0aa311 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 6cf5c6e1..bb71bacf 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 8a7218e7..b05a055b 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 a9f2dbd1..572f3dc9 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 00000000..a9f2dbd1 --- /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 ae0aa311..b32e6b6e 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 1ac99e57..84da3a25 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 bb71bacf..c63c9846 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 c63c9846..1d581dbf 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 b05a055b..8a7218e7 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 e77376bd..03b983a1 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 a9f2dbd1..7c9cab0e 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 3a095b75..4be70a54 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 23960a98..0d2822ac 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 e899e6d3..741a2536 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 61327803..46929c00 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 bd86a1d4..cbaf42b6 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 6f8d0848..9cb47426 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 b9550b0e..47c509fc 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 f452a9e6..28bc7032 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 c81faf78..9da532b1 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 8f2795af..df9b01bf 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 c8b33be3..60a67ab7 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 b32e6b6e..507c65e6 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 47c509fc..f7777471 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 5ea5dddd..6c532099 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 bbe60335..77d61281 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 9cb47426..0a50cde5 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 d1a95670..27b0c9b2 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 84da3a25..904b70fe 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"