forked from firka/student-legacy
Merge branch 'dev' of github.com:refilc/naplo into dev
This commit is contained in:
commit
6803ac8642
28
refilc/.gitignore
vendored
28
refilc/.gitignore
vendored
@ -47,3 +47,31 @@ app.*.map.json
|
|||||||
Pods
|
Pods
|
||||||
Podfile.lock
|
Podfile.lock
|
||||||
UserInterfaceState.xcuserstate
|
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.*
|
||||||
|
0
refilc/build-ipa.sh
Normal file → Executable file
0
refilc/build-ipa.sh
Normal file → Executable file
20
refilc/ios/PrivacyInfo.xcprivacy
Normal file
20
refilc/ios/PrivacyInfo.xcprivacy
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyAccessedAPITypes</key>
|
||||||
|
<array>
|
||||||
|
<!-- [1] background_fetch: UserDefaults -->
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyAccessedAPIType</key>
|
||||||
|
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||||
|
|
||||||
|
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||||
|
<array>
|
||||||
|
<string>CA92.1</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -17,7 +17,13 @@
|
|||||||
3127F7A828EAEE8500C2EFB3 /* lesson_model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */; };
|
3127F7A828EAEE8500C2EFB3 /* lesson_model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */; };
|
||||||
373A6ECB5FC71FE9D8AF2EDB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F0ADD56276103500A3016C8 /* Pods_Runner.framework */; };
|
373A6ECB5FC71FE9D8AF2EDB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F0ADD56276103500A3016C8 /* Pods_Runner.framework */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
4F35BF332BE2FFA30098EF72 /* public_vars.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F35BF322BE2FFA30098EF72 /* public_vars.swift */; };
|
||||||
|
4F35BF352BE2FFD80098EF72 /* LiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F35BF342BE2FFD80098EF72 /* LiveActivityManager.swift */; };
|
||||||
|
4F35BF362BE2FFD80098EF72 /* LiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F35BF342BE2FFD80098EF72 /* LiveActivityManager.swift */; };
|
||||||
|
4F35BF382BE300A70098EF72 /* lesson_model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */; };
|
||||||
|
4F35BF392BE300B10098EF72 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
|
4F35BF3A2BE301180098EF72 /* public_vars.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F35BF322BE2FFA30098EF72 /* public_vars.swift */; };
|
||||||
|
4F35BF3E2BE304550098EF72 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 4F35BF3D2BE304550098EF72 /* PrivacyInfo.xcprivacy */; };
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||||
@ -73,6 +79,10 @@
|
|||||||
3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = lesson_model.swift; sourceTree = "<group>"; };
|
3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = lesson_model.swift; sourceTree = "<group>"; };
|
||||||
317DE77A294F6FFB002E323E /* livecard.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = livecard.entitlements; sourceTree = "<group>"; };
|
317DE77A294F6FFB002E323E /* livecard.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = livecard.entitlements; sourceTree = "<group>"; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
|
4F35BF322BE2FFA30098EF72 /* public_vars.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = public_vars.swift; sourceTree = "<group>"; };
|
||||||
|
4F35BF342BE2FFD80098EF72 /* LiveActivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivityManager.swift; sourceTree = "<group>"; };
|
||||||
|
4F35BF3B2BE303A40098EF72 /* app_group_directory.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = app_group_directory.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
4F35BF3D2BE304550098EF72 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||||
707F8089D970F81C480F73C4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
707F8089D970F81C480F73C4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
@ -118,6 +128,7 @@
|
|||||||
3127F79728EAEDE300C2EFB3 /* Assets.xcassets */,
|
3127F79728EAEDE300C2EFB3 /* Assets.xcassets */,
|
||||||
3127F79928EAEDE300C2EFB3 /* Info.plist */,
|
3127F79928EAEDE300C2EFB3 /* Info.plist */,
|
||||||
3127F7A528EAEE5900C2EFB3 /* livecard.swift */,
|
3127F7A528EAEE5900C2EFB3 /* livecard.swift */,
|
||||||
|
4F35BF342BE2FFD80098EF72 /* LiveActivityManager.swift */,
|
||||||
);
|
);
|
||||||
path = livecard;
|
path = livecard;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -125,6 +136,7 @@
|
|||||||
6640A963014A9D4F31026053 /* Frameworks */ = {
|
6640A963014A9D4F31026053 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4F35BF3B2BE303A40098EF72 /* app_group_directory.framework */,
|
||||||
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */,
|
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */,
|
||||||
3127F73F28EAEC8A00C2EFB3 /* IntentsUI.framework */,
|
3127F73F28EAEC8A00C2EFB3 /* IntentsUI.framework */,
|
||||||
3127F75528EAECC800C2EFB3 /* WidgetKit.framework */,
|
3127F75528EAECC800C2EFB3 /* WidgetKit.framework */,
|
||||||
@ -157,6 +169,7 @@
|
|||||||
97C146E51CF9000F007C117D = {
|
97C146E51CF9000F007C117D = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4F35BF3D2BE304550098EF72 /* PrivacyInfo.xcprivacy */,
|
||||||
9740EEB11CF90186004384FC /* Flutter */,
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
3127F78F28EAEDE200C2EFB3 /* livecard */,
|
3127F78F28EAEDE200C2EFB3 /* livecard */,
|
||||||
@ -187,6 +200,7 @@
|
|||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||||
|
4F35BF322BE2FFA30098EF72 /* public_vars.swift */,
|
||||||
);
|
);
|
||||||
path = Runner;
|
path = Runner;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -242,7 +256,7 @@
|
|||||||
97C146E61CF9000F007C117D /* Project object */ = {
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 1410;
|
LastSwiftUpdateCheck = 1530;
|
||||||
LastUpgradeCheck = 1510;
|
LastUpgradeCheck = 1510;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
@ -290,6 +304,7 @@
|
|||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||||
|
4F35BF3E2BE304550098EF72 /* PrivacyInfo.xcprivacy in Resources */,
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -320,6 +335,8 @@
|
|||||||
buildActionMask = 12;
|
buildActionMask = 12;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||||
);
|
);
|
||||||
@ -372,7 +389,7 @@
|
|||||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 12;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
@ -391,9 +408,11 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
4F35BF362BE2FFD80098EF72 /* LiveActivityManager.swift in Sources */,
|
||||||
3127F7A828EAEE8500C2EFB3 /* lesson_model.swift in Sources */,
|
3127F7A828EAEE8500C2EFB3 /* lesson_model.swift in Sources */,
|
||||||
3127F7A428EAEE3D00C2EFB3 /* livecard.intentdefinition in Sources */,
|
3127F7A428EAEE3D00C2EFB3 /* livecard.intentdefinition in Sources */,
|
||||||
3127F7A628EAEE5900C2EFB3 /* livecard.swift in Sources */,
|
3127F7A628EAEE5900C2EFB3 /* livecard.swift in Sources */,
|
||||||
|
4F35BF3A2BE301180098EF72 /* public_vars.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -401,8 +420,11 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
4F35BF392BE300B10098EF72 /* AppDelegate.swift in Sources */,
|
||||||
|
4F35BF382BE300A70098EF72 /* lesson_model.swift in Sources */,
|
||||||
|
4F35BF352BE2FFD80098EF72 /* LiveActivityManager.swift in Sources */,
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||||
|
4F35BF332BE2FFA30098EF72 /* public_vars.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -495,7 +517,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 250;
|
CURRENT_PROJECT_VERSION = 255;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -527,7 +549,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 250;
|
CURRENT_PROJECT_VERSION = 255;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@ -535,7 +557,7 @@
|
|||||||
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -569,7 +591,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 250;
|
CURRENT_PROJECT_VERSION = 255;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@ -577,7 +599,7 @@
|
|||||||
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -609,7 +631,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 250;
|
CURRENT_PROJECT_VERSION = 255;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@ -617,7 +639,7 @@
|
|||||||
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -753,7 +775,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 250;
|
CURRENT_PROJECT_VERSION = 255;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -781,7 +803,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 250;
|
CURRENT_PROJECT_VERSION = 255;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<key>livecard.xcscheme_^#shared#^_</key>
|
<key>livecard.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>78</integer>
|
<integer>83</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
Binary file not shown.
@ -1,25 +1,113 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
import background_fetch
|
||||||
|
import ActivityKit
|
||||||
import Flutter
|
import Flutter
|
||||||
|
|
||||||
@UIApplicationMain
|
@UIApplicationMain
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
|
private var methodChannel: FlutterMethodChannel?
|
||||||
|
|
||||||
override func application(
|
override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
|
guard let controller = window?.rootViewController as? FlutterViewController else {
|
||||||
// here, Without this code the task will not work.
|
fatalError("rootViewController is not type FlutterViewController")
|
||||||
//SwiftFlutterForegroundTaskPlugin.setPluginRegistrantCallback(registerPlugins)
|
|
||||||
if #available(iOS 10.0, *) {
|
|
||||||
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
|
|
||||||
}
|
}
|
||||||
|
methodChannel = FlutterMethodChannel(name: "hu.refilc/liveactivity",
|
||||||
|
binaryMessenger: controller as! FlutterBinaryMessenger)
|
||||||
|
methodChannel?.setMethodCallHandler({
|
||||||
|
[weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
|
||||||
|
guard call.method == "createLiveActivity" || call.method == "endLiveActivity" || call.method == "updateLiveActivity" else {
|
||||||
|
result(FlutterMethodNotImplemented)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self?.handleMethodCall(call, result: result)
|
||||||
|
})
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// here
|
override func applicationWillTerminate(_ application: UIApplication) {
|
||||||
func registerPlugins(registry: FlutterPluginRegistry) {
|
if #available(iOS 16.2, *) {
|
||||||
GeneratedPluginRegistrant.register(with: registry)
|
LiveActivityManager.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleMethodCall(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
|
if call.method == "createLiveActivity" {
|
||||||
|
if let args = call.arguments as? [String: Any] {
|
||||||
|
lessonDataDictionary = args
|
||||||
|
globalLessonData = LessonData(from: lessonDataDictionary)
|
||||||
|
print("swift: megkapott flutter adatok:",lessonDataDictionary)
|
||||||
|
print("Live Activity bekapcsolva az eszközön: ",checkLiveActivityFeatureAvailable())
|
||||||
|
if(checkLiveActivityFeatureAvailable()) {
|
||||||
|
createLiveActivity(with: lessonDataDictionary)
|
||||||
|
result(checkLiveActivityFeatureAvailable())
|
||||||
|
} else {
|
||||||
|
result(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result(FlutterError(code: "INVALID_ARGUMENTS", message: "Invalid iOS arguments received", details: nil))
|
||||||
|
}
|
||||||
|
} else if call.method == "updateLiveActivity" {
|
||||||
|
if let args = call.arguments as? [String: Any] {
|
||||||
|
lessonDataDictionary = args
|
||||||
|
globalLessonData = LessonData(from: lessonDataDictionary)
|
||||||
|
updateLiveActivity(with: lessonDataDictionary)
|
||||||
|
result(nil)
|
||||||
|
} else {
|
||||||
|
result(FlutterError(code: "INVALID_ARGUMENTS", message: "Invalid iOS arguments received", details: nil))
|
||||||
|
}
|
||||||
|
} else if call.method == "endLiveActivity" {
|
||||||
|
endLiveActivity()
|
||||||
|
result(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func createLiveActivity(with activityData: [String: Any]) -> String? {
|
||||||
|
var lessonData = LessonData(from: activityData)
|
||||||
|
print("Live Activity létrehozása...")
|
||||||
|
if #available(iOS 16.2, *) {
|
||||||
|
LiveActivityManager.create()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateLiveActivity(with activityData: [String: Any]) {
|
||||||
|
let lessonData = LessonData(from: activityData)
|
||||||
|
print("swift: megkapott flutter adatok:",lessonDataDictionary)
|
||||||
|
print("Live Activity frissítés...")
|
||||||
|
if #available(iOS 16.2, *) {
|
||||||
|
LiveActivityManager.update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private func endLiveActivity() {
|
||||||
|
print("Live Activity befejezése...")
|
||||||
|
if #available(iOS 16.2, *) {
|
||||||
|
LiveActivityManager.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func checkIfLiveActivityExists() -> Bool {
|
||||||
|
if let activityID = activityID {
|
||||||
|
if #available(iOS 16.2, *) {
|
||||||
|
return LiveActivityManager.isRunning(activityID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func checkLiveActivityFeatureAvailable() -> Bool {
|
||||||
|
if #available(iOS 16.2, *) {
|
||||||
|
guard ActivityAuthorizationInfo().areActivitiesEnabled else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
||||||
<array>
|
<array>
|
||||||
<string>com.transistorsoft.fetch</string>
|
<string>com.transistorsoft.refilcnotification</string>
|
||||||
|
<string>com.transistorsoft.refilcliveactivity</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
@ -133,5 +134,5 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
<key>aps-environment</key>
|
<key>aps-environment</key>
|
||||||
<string>development</string>
|
<string>development</string>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array/>
|
||||||
<string>group.refilc2.livecard</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
12
refilc/ios/Runner/public_vars.swift
Normal file
12
refilc/ios/Runner/public_vars.swift
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// public_vars.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by Geryy on 02/05/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
var lessonDataDictionary: [String: Any] = [:]
|
||||||
|
var globalLessonData = LessonData(from: lessonDataDictionary)
|
||||||
|
var activityID: String? = ""
|
92
refilc/ios/livecard/LiveActivityManager.swift
Normal file
92
refilc/ios/livecard/LiveActivityManager.swift
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import ActivityKit
|
||||||
|
import WidgetKit
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
|
||||||
|
public typealias LiveDeliveryData = ContentState
|
||||||
|
public struct ContentState: Codable, Hashable {
|
||||||
|
var color: String
|
||||||
|
var icon: String
|
||||||
|
var index: String
|
||||||
|
var title: String
|
||||||
|
var subtitle: String
|
||||||
|
var description: String
|
||||||
|
var startDate: Date
|
||||||
|
var endDate: Date
|
||||||
|
var date: ClosedRange<Date>
|
||||||
|
var nextSubject: String
|
||||||
|
var nextRoom: String
|
||||||
|
}
|
||||||
|
|
||||||
|
public var id = UUID()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 16.2, *)
|
||||||
|
final class LiveActivityManager {
|
||||||
|
static let shared = LiveActivityManager()
|
||||||
|
var currentActivity: Activity<LiveActivitiesAppAttributes>?
|
||||||
|
|
||||||
|
class func create() {
|
||||||
|
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
let contentState = LiveActivitiesAppAttributes.ContentState(color: globalLessonData.color, icon: globalLessonData.icon, index: globalLessonData.index, title: globalLessonData.title, subtitle: globalLessonData.subtitle, description: globalLessonData.description, startDate: globalLessonData.startDate, endDate: globalLessonData.endDate, date: globalLessonData.date, nextSubject: globalLessonData.nextSubject, nextRoom: globalLessonData.nextRoom)
|
||||||
|
|
||||||
|
let activityContent = ActivityContent(state: contentState, staleDate: globalLessonData.endDate, relevanceScore: 0)
|
||||||
|
|
||||||
|
let activity = try Activity<LiveActivitiesAppAttributes>.request(
|
||||||
|
attributes: LiveActivitiesAppAttributes(),
|
||||||
|
content: activityContent,
|
||||||
|
pushType: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
activityID = activity.id
|
||||||
|
print("Live Activity létrehozva. Azonosító: \(activity.id)")
|
||||||
|
} catch {
|
||||||
|
print("Hiba történt a Live Activity létrehozásakor: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class func update() {
|
||||||
|
Task {
|
||||||
|
for activity in Activity<LiveActivitiesAppAttributes>.activities {
|
||||||
|
do {
|
||||||
|
let contentState = LiveActivitiesAppAttributes.ContentState(color: globalLessonData.color, icon: globalLessonData.icon, index: globalLessonData.index, title: globalLessonData.title, subtitle: globalLessonData.subtitle, description: globalLessonData.description, startDate: globalLessonData.startDate, endDate: globalLessonData.endDate, date: globalLessonData.date, nextSubject: globalLessonData.nextSubject, nextRoom: globalLessonData.nextRoom)
|
||||||
|
|
||||||
|
let activityContent = ActivityContent(state: contentState, staleDate: globalLessonData.endDate, relevanceScore: 0)
|
||||||
|
|
||||||
|
await activity.update(activityContent)
|
||||||
|
activityID = activity.id
|
||||||
|
print("Live Activity frissítve. Azonosító: \(activity.id)")
|
||||||
|
} catch {
|
||||||
|
print("Hiba történt a Live Activity frissítésekor: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class func stop() {
|
||||||
|
if (activityID != "") {
|
||||||
|
Task {
|
||||||
|
for activity in Activity<LiveActivitiesAppAttributes>.activities{
|
||||||
|
let contentState = LiveActivitiesAppAttributes.ContentState(color: globalLessonData.color, icon: globalLessonData.icon, index: globalLessonData.index, title: globalLessonData.title, subtitle: globalLessonData.subtitle, description: globalLessonData.description, startDate: globalLessonData.startDate, endDate: globalLessonData.endDate, date: globalLessonData.date, nextSubject: globalLessonData.nextSubject, nextRoom: globalLessonData.nextRoom)
|
||||||
|
|
||||||
|
await activity.end(ActivityContent(state: contentState, staleDate: Date.distantFuture),dismissalPolicy: .immediate)
|
||||||
|
}
|
||||||
|
activityID = nil
|
||||||
|
print("Live Activity sikeresen leállítva")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class func isRunning(_ activityID: String) -> Bool {
|
||||||
|
for activity in Activity<LiveActivitiesAppAttributes>.activities {
|
||||||
|
if activity.id == activityID {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
import ActivityKit
|
||||||
|
|
||||||
class LessonData {
|
public struct LessonData {
|
||||||
var color: String
|
var color: String
|
||||||
var icon: String
|
var icon: String
|
||||||
var index: String
|
var index: String
|
||||||
@ -13,19 +14,27 @@ class LessonData {
|
|||||||
var nextSubject: String
|
var nextSubject: String
|
||||||
var nextRoom: String
|
var nextRoom: String
|
||||||
|
|
||||||
init?() {
|
init(from dictionary: [String: Any]) {
|
||||||
let sharedDefault = UserDefaults(suiteName: "group.refilc2.livecard")!
|
self.color = dictionary["color"] as? String ?? ""
|
||||||
|
self.icon = dictionary["icon"] as? String ?? ""
|
||||||
|
self.index = dictionary["index"] as? String ?? ""
|
||||||
|
self.title = dictionary["title"] as? String ?? ""
|
||||||
|
self.subtitle = dictionary["subtitle"] as? String ?? ""
|
||||||
|
self.description = dictionary["description"] as? String ?? ""
|
||||||
|
self.nextSubject = dictionary["nextSubject"] as? String ?? ""
|
||||||
|
self.nextRoom = dictionary["nextRoom"] as? String ?? ""
|
||||||
|
|
||||||
self.color = sharedDefault.string(forKey: "color")!
|
if let startDateStr = dictionary["startDate"] as? String, let startDateInt = Int(startDateStr) {
|
||||||
self.icon = sharedDefault.string(forKey: "icon")!
|
self.startDate = Date(timeIntervalSince1970: TimeInterval(startDateInt) / 1000)
|
||||||
self.index = sharedDefault.string(forKey: "index")!
|
} else {
|
||||||
self.title = sharedDefault.string(forKey: "title")!
|
self.startDate = Date()
|
||||||
self.subtitle = sharedDefault.string(forKey: "subtitle")!
|
}
|
||||||
self.description = sharedDefault.string(forKey: "description")!
|
|
||||||
self.startDate = Date(timeIntervalSince1970: Double(sharedDefault.string(forKey: "startDate")!)! / 1000)
|
if let endDateStr = dictionary["endDate"] as? String, let endDateInt = Int(endDateStr) {
|
||||||
self.endDate = Date(timeIntervalSince1970: Double(sharedDefault.string(forKey: "endDate")!)! / 1000)
|
self.endDate = Date(timeIntervalSince1970: TimeInterval(endDateInt) / 1000)
|
||||||
|
} else {
|
||||||
|
self.endDate = Date()
|
||||||
|
}
|
||||||
date = self.startDate...self.endDate
|
date = self.startDate...self.endDate
|
||||||
self.nextSubject = sharedDefault.string(forKey: "nextSubject")!
|
|
||||||
self.nextRoom = sharedDefault.string(forKey: "nextRoom")!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
<key>aps-environment</key>
|
<key>aps-environment</key>
|
||||||
<string>development</string>
|
<string>development</string>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array/>
|
||||||
<string>group.refilc2.livecard</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -5,7 +5,7 @@ import SwiftUI
|
|||||||
@main
|
@main
|
||||||
struct Widgets: WidgetBundle {
|
struct Widgets: WidgetBundle {
|
||||||
var body: some Widget {
|
var body: some Widget {
|
||||||
if #available(iOS 16.1, *) {
|
if #available(iOS 16.2, *) {
|
||||||
LiveCardWidget()
|
LiveCardWidget()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,58 +37,56 @@ extension Color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// We need to redefined live activities pipe
|
|
||||||
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
|
|
||||||
public struct ContentState: Codable, Hashable { }
|
|
||||||
|
|
||||||
var id = UUID()
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LockScreenLiveActivityView: View {
|
struct LockScreenLiveActivityView: View {
|
||||||
let context: ActivityViewContext<LiveActivitiesAppAttributes>
|
let context: ActivityViewContext<LiveActivitiesAppAttributes>
|
||||||
|
|
||||||
let lesson = LessonData()
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
Image(systemName: lesson!.icon)
|
// Ikon
|
||||||
|
Image(systemName: context.state.icon)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(width: CGFloat(30), height: CGFloat(30))
|
.frame(width: CGFloat(30), height: CGFloat(30))
|
||||||
.padding(.leading, CGFloat(24))
|
.padding(.leading, CGFloat(24))
|
||||||
|
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .center) {
|
||||||
HStack(alignment: .center) {
|
// Jelenlegi óra
|
||||||
Text(lesson!.index + lesson!.title)
|
VStack {
|
||||||
.font(.title3)
|
Text(context.state.index + " " + context.state.title)
|
||||||
|
.font(.body)
|
||||||
.bold()
|
.bold()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
|
||||||
Text(lesson!.subtitle)
|
Text("Terem: \(context.state.subtitle)")
|
||||||
.font(.subheadline)
|
.italic()
|
||||||
.padding(.trailing, 12)
|
.font(.caption)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lesson!.description != "") {
|
// Leírás
|
||||||
Text(lesson!.description)
|
if (context.state.description != "") {
|
||||||
|
Text(context.state.description)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Következő óra
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "arrow.right")
|
Image(systemName: "arrow.right")
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(width: CGFloat(8), height: CGFloat(8))
|
.frame(width: CGFloat(8), height: CGFloat(8))
|
||||||
Text(lesson!.nextSubject)
|
Text(context.state.nextSubject)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
Text(lesson!.nextRoom)
|
Text(context.state.nextRoom)
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
}
|
}
|
||||||
}.padding(15)
|
.multilineTextAlignment(.center)
|
||||||
|
}
|
||||||
|
.padding(15)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Text(timerInterval: lesson!.date, countsDown: true)
|
// Visszaszámláló
|
||||||
|
Text(timerInterval: context.state.date, countsDown: true)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.frame(width: 85)
|
.frame(width: 85)
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
@ -96,15 +94,14 @@ struct LockScreenLiveActivityView: View {
|
|||||||
.padding(.trailing, CGFloat(24))
|
.padding(.trailing, CGFloat(24))
|
||||||
}
|
}
|
||||||
.activityBackgroundTint(
|
.activityBackgroundTint(
|
||||||
lesson!.color != "#676767"
|
context.state.color != "#676767"
|
||||||
? Color(hex: lesson!.color)
|
? Color(hex: context.state.color)
|
||||||
// Ha nem megy hat nem megy
|
|
||||||
: Color.clear
|
: Color.clear
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOSApplicationExtension 16.1, *)
|
@available(iOSApplicationExtension 16.2, *)
|
||||||
struct LiveCardWidget: Widget {
|
struct LiveCardWidget: Widget {
|
||||||
var body: some WidgetConfiguration {
|
var body: some WidgetConfiguration {
|
||||||
/// Live Activity Notification
|
/// Live Activity Notification
|
||||||
@ -112,7 +109,6 @@ struct LiveCardWidget: Widget {
|
|||||||
LockScreenLiveActivityView(context: context)
|
LockScreenLiveActivityView(context: context)
|
||||||
/// Dynamic Island
|
/// Dynamic Island
|
||||||
} dynamicIsland: { context in
|
} dynamicIsland: { context in
|
||||||
let lesson = LessonData()
|
|
||||||
|
|
||||||
/// Expanded
|
/// Expanded
|
||||||
return DynamicIsland {
|
return DynamicIsland {
|
||||||
@ -120,16 +116,16 @@ struct LiveCardWidget: Widget {
|
|||||||
VStack {
|
VStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
ProgressView(
|
ProgressView(
|
||||||
timerInterval: lesson!.date,
|
timerInterval: context.state.date,
|
||||||
countsDown: true,
|
countsDown: true,
|
||||||
label: {
|
label: {
|
||||||
Image(systemName: lesson!.icon)
|
Image(systemName: context.state.icon)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(width: CGFloat(32), height: CGFloat(32))
|
.frame(width: CGFloat(32), height: CGFloat(32))
|
||||||
},
|
},
|
||||||
currentValueLabel: {
|
currentValueLabel: {
|
||||||
Image(systemName: lesson!.icon)
|
Image(systemName: context.state.icon)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(width: CGFloat(32), height: CGFloat(32))
|
.frame(width: CGFloat(32), height: CGFloat(32))
|
||||||
@ -138,38 +134,34 @@ struct LiveCardWidget: Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicIslandExpandedRegion(.center) {
|
DynamicIslandExpandedRegion(.center) {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .center) {
|
||||||
Text(lesson!.index + lesson!.title)
|
Text(context.state.index + context.state.title)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.font(.title3)
|
.font(.body)
|
||||||
.bold()
|
.bold()
|
||||||
|
|
||||||
Text(lesson!.description)
|
Text(context.state.subtitle)
|
||||||
.lineLimit(2)
|
|
||||||
.font(.caption)
|
|
||||||
}.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0))
|
|
||||||
}
|
|
||||||
DynamicIslandExpandedRegion(.trailing) {
|
|
||||||
VStack {
|
|
||||||
Spacer()
|
|
||||||
Text(lesson!.subtitle)
|
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
|
||||||
|
Text(context.state.description)
|
||||||
|
.lineLimit(2)
|
||||||
|
.font(.caption)
|
||||||
|
}.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compact
|
/// Compact
|
||||||
} compactLeading: {
|
} compactLeading: {
|
||||||
Label {
|
Label {
|
||||||
Text(lesson!.title)
|
Text(context.state.title)
|
||||||
} icon: {
|
} icon: {
|
||||||
Image(systemName: lesson!.icon)
|
Image(systemName: context.state.icon)
|
||||||
}
|
}
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
}
|
}
|
||||||
compactTrailing: {
|
compactTrailing: {
|
||||||
Text(timerInterval: lesson!.date, countsDown: true)
|
Text(timerInterval: context.state.date, countsDown: true)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.frame(width: 40)
|
.frame(width: 40)
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
@ -178,16 +170,16 @@ struct LiveCardWidget: Widget {
|
|||||||
} minimal: {
|
} minimal: {
|
||||||
VStack(alignment: .center, content: {
|
VStack(alignment: .center, content: {
|
||||||
ProgressView(
|
ProgressView(
|
||||||
timerInterval: lesson!.date,
|
timerInterval: context.state.date,
|
||||||
countsDown: true,
|
countsDown: true,
|
||||||
label: {
|
label: {
|
||||||
Image(systemName: lesson!.icon)
|
Image(systemName: context.state.icon)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(width: CGFloat(12), height: CGFloat(12))
|
.frame(width: CGFloat(12), height: CGFloat(12))
|
||||||
},
|
},
|
||||||
currentValueLabel: {
|
currentValueLabel: {
|
||||||
Image(systemName: lesson!.icon)
|
Image(systemName: context.state.icon)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(width: CGFloat(12), height: CGFloat(12))
|
.frame(width: CGFloat(12), height: CGFloat(12))
|
||||||
@ -196,8 +188,8 @@ struct LiveCardWidget: Widget {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
.keylineTint(
|
.keylineTint(
|
||||||
lesson!.color != "#676767"
|
context.state.color != "#676767"
|
||||||
? Color(hex: lesson!.color)
|
? Color(hex: context.state.color)
|
||||||
: Color.clear
|
: Color.clear
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:refilc/api/providers/liveactivity/platform_channel.dart';
|
||||||
import 'package:refilc/helpers/subject.dart';
|
import 'package:refilc/helpers/subject.dart';
|
||||||
import 'package:refilc/models/settings.dart';
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc_kreta_api/models/lesson.dart';
|
import 'package:refilc_kreta_api/models/lesson.dart';
|
||||||
@ -10,7 +11,6 @@ import 'package:refilc_kreta_api/models/week.dart';
|
|||||||
import 'package:refilc/utils/format.dart';
|
import 'package:refilc/utils/format.dart';
|
||||||
import 'package:refilc_kreta_api/providers/timetable_provider.dart';
|
import 'package:refilc_kreta_api/providers/timetable_provider.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:live_activities/live_activities.dart';
|
|
||||||
import 'package:refilc_mobile_ui/pages/home/live_card/live_card.i18n.dart';
|
import 'package:refilc_mobile_ui/pages/home/live_card/live_card.i18n.dart';
|
||||||
|
|
||||||
enum LiveCardState {
|
enum LiveCardState {
|
||||||
@ -29,6 +29,15 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
Lesson? prevLesson;
|
Lesson? prevLesson;
|
||||||
List<Lesson>? nextLessons;
|
List<Lesson>? nextLessons;
|
||||||
|
|
||||||
|
// new variables
|
||||||
|
static bool hasActivityStarted = false;
|
||||||
|
static bool hasDayEnd = false;
|
||||||
|
static DateTime? storeFirstRunDate;
|
||||||
|
static bool hasActivitySettingsChanged = false;
|
||||||
|
static Map<String, String> LAData = {};
|
||||||
|
static DateTime? now;
|
||||||
|
//
|
||||||
|
|
||||||
LiveCardState currentState = LiveCardState.empty;
|
LiveCardState currentState = LiveCardState.empty;
|
||||||
late Timer _timer;
|
late Timer _timer;
|
||||||
late final TimetableProvider _timetable;
|
late final TimetableProvider _timetable;
|
||||||
@ -36,9 +45,6 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
late Duration _delay;
|
late Duration _delay;
|
||||||
|
|
||||||
final _liveActivitiesPlugin = LiveActivities();
|
|
||||||
String? _latestActivityId;
|
|
||||||
Map<String, String> _lastActivity = {};
|
|
||||||
|
|
||||||
bool _hasCheckedTimetable = false;
|
bool _hasCheckedTimetable = false;
|
||||||
|
|
||||||
@ -47,23 +53,6 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
required SettingsProvider settings,
|
required SettingsProvider settings,
|
||||||
}) : _timetable = timetable,
|
}) : _timetable = timetable,
|
||||||
_settings = settings {
|
_settings = settings {
|
||||||
if (Platform.isIOS) {
|
|
||||||
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
|
||||||
// Console log
|
|
||||||
if (kDebugMode) {
|
|
||||||
print("iOS LiveActivity enabled: $value");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
_liveActivitiesPlugin.init(appGroupId: "group.refilc2.livecard");
|
|
||||||
|
|
||||||
_liveActivitiesPlugin.getAllActivitiesIds().then((value) {
|
|
||||||
_latestActivityId = value.isNotEmpty ? value.first : null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
|
||||||
_delay = settings.bellDelayEnabled
|
_delay = settings.bellDelayEnabled
|
||||||
? Duration(seconds: settings.bellDelay)
|
? Duration(seconds: settings.bellDelay)
|
||||||
@ -71,21 +60,6 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_timer.cancel();
|
|
||||||
if (Platform.isIOS) {
|
|
||||||
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
|
||||||
if (value) {
|
|
||||||
if (_latestActivityId != null) {
|
|
||||||
_liveActivitiesPlugin.endActivity(_latestActivityId!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
static DateTime _now() {
|
static DateTime _now() {
|
||||||
// return DateTime(2023, 9, 27, 9, 30);
|
// return DateTime(2023, 9, 27, 9, 30);
|
||||||
@ -110,6 +84,66 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
Map<String, String> toMap() {
|
Map<String, String> toMap() {
|
||||||
switch (currentState) {
|
switch (currentState) {
|
||||||
|
case LiveCardState.morning:
|
||||||
|
return {
|
||||||
|
"color":
|
||||||
|
'#${_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(): "",
|
||||||
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
|
_delay.inMilliseconds)
|
||||||
|
.toString(),
|
||||||
|
"nextSubject": nextLesson != null
|
||||||
|
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
|
: "",
|
||||||
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
|
};
|
||||||
|
|
||||||
|
case LiveCardState.afternoon:
|
||||||
|
return {
|
||||||
|
"color":
|
||||||
|
'#${_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(): "",
|
||||||
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
|
_delay.inMilliseconds)
|
||||||
|
.toString(),
|
||||||
|
"nextSubject": nextLesson != null
|
||||||
|
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
|
: "",
|
||||||
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
|
};
|
||||||
|
|
||||||
|
case LiveCardState.night:
|
||||||
|
return {
|
||||||
|
"color":
|
||||||
|
'#${_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(): "",
|
||||||
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
|
_delay.inMilliseconds)
|
||||||
|
.toString(),
|
||||||
|
"nextSubject": nextLesson != null
|
||||||
|
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
|
: "",
|
||||||
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
|
};
|
||||||
|
|
||||||
case LiveCardState.duringLesson:
|
case LiveCardState.duringLesson:
|
||||||
return {
|
return {
|
||||||
"color":
|
"color":
|
||||||
@ -120,9 +154,7 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
"index":
|
"index":
|
||||||
currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
|
currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
|
||||||
"title": currentLesson != null
|
"title": currentLesson != null
|
||||||
? currentLesson?.subject.renamedTo ??
|
? currentLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: currentLesson?.subject).capital()
|
||||||
ShortSubject.resolve(subject: currentLesson?.subject)
|
|
||||||
.capital()
|
|
||||||
: "",
|
: "",
|
||||||
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
|
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
"description": currentLesson?.description ?? "",
|
"description": currentLesson?.description ?? "",
|
||||||
@ -133,8 +165,7 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"nextSubject": nextLesson != null
|
"nextSubject": nextLesson != null
|
||||||
? nextLesson?.subject.renamedTo ??
|
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
|
||||||
: "",
|
: "",
|
||||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
};
|
};
|
||||||
@ -163,9 +194,7 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"nextSubject": (nextLesson != null
|
"nextSubject": (nextLesson != null
|
||||||
? nextLesson?.subject.renamedTo ??
|
? nextLesson?.subject.renamedTo ?? ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
ShortSubject.resolve(subject: nextLesson?.subject)
|
|
||||||
.capital()
|
|
||||||
: "")
|
: "")
|
||||||
.capital(),
|
.capital(),
|
||||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
@ -178,37 +207,6 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void update() async {
|
void update() async {
|
||||||
if (Platform.isIOS) {
|
|
||||||
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
|
|
||||||
if (value) {
|
|
||||||
final cmap = toMap();
|
|
||||||
if (!mapEquals(cmap, _lastActivity)) {
|
|
||||||
_lastActivity = cmap;
|
|
||||||
try {
|
|
||||||
if (_lastActivity.isNotEmpty) {
|
|
||||||
if (_latestActivityId == null) {
|
|
||||||
_liveActivitiesPlugin
|
|
||||||
.createActivity(_lastActivity)
|
|
||||||
.then((value) => _latestActivityId = value);
|
|
||||||
} else {
|
|
||||||
_liveActivitiesPlugin.updateActivity(
|
|
||||||
_latestActivityId!, _lastActivity);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (_latestActivityId != null) {
|
|
||||||
_liveActivitiesPlugin.endActivity(_latestActivityId!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (kDebugMode) {
|
|
||||||
print('ERROR: Unable to create or update iOS LiveActivity!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Lesson> today = _today(_timetable);
|
List<Lesson> today = _today(_timetable);
|
||||||
|
|
||||||
if (today.isEmpty && !_hasCheckedTimetable) {
|
if (today.isEmpty && !_hasCheckedTimetable) {
|
||||||
@ -221,7 +219,14 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
? Duration(seconds: _settings.bellDelay)
|
? Duration(seconds: _settings.bellDelay)
|
||||||
: Duration.zero;
|
: Duration.zero;
|
||||||
|
|
||||||
final now = _now().add(_delay);
|
|
||||||
|
DateTime now = _now().add(_delay);
|
||||||
|
|
||||||
|
if ((currentState == LiveCardState.morning ||
|
||||||
|
currentState == LiveCardState.afternoon ||
|
||||||
|
currentState == LiveCardState.night) && storeFirstRunDate == null) {
|
||||||
|
storeFirstRunDate = now;
|
||||||
|
}
|
||||||
|
|
||||||
// Filter cancelled lessons #20
|
// Filter cancelled lessons #20
|
||||||
// Filter label lessons #128
|
// Filter label lessons #128
|
||||||
@ -283,11 +288,65 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
currentState = LiveCardState.empty;
|
currentState = LiveCardState.empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//LIVE ACTIVITIES
|
||||||
|
|
||||||
|
//CREATE
|
||||||
|
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...");
|
||||||
|
PlatformChannel.createLiveActivity(toMap());
|
||||||
|
hasActivityStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//UPDATE
|
||||||
|
else if (hasActivityStarted) {
|
||||||
|
if (hasActivitySettingsChanged) {
|
||||||
|
debugPrint("Valamelyik beállítás megváltozott. Frissítés...");
|
||||||
|
PlatformChannel.updateLiveActivity(toMap());
|
||||||
|
hasActivitySettingsChanged = false;
|
||||||
|
}
|
||||||
|
else if (nextLesson != null || currentLesson != null) {
|
||||||
|
bool afterPrevLessonEnd = prevLesson != null &&
|
||||||
|
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);
|
||||||
|
if (afterPrevLessonEnd || afterCurrentLessonStart) {
|
||||||
|
debugPrint(
|
||||||
|
"Óra kezdete/vége után 1 másodperccel vagyunk. Frissítés...");
|
||||||
|
PlatformChannel.updateLiveActivity(toMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//END
|
||||||
|
if (hasActivityStarted && !hasDayEnd && nextLesson == null &&
|
||||||
|
now.isAfter(prevLesson!.end)) {
|
||||||
|
debugPrint("Az utolsó óra véget ért. Befejezés...");
|
||||||
|
PlatformChannel.endLiveActivity();
|
||||||
|
hasDayEnd = true;
|
||||||
|
hasActivityStarted = false;
|
||||||
|
}
|
||||||
|
LAData = toMap();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get show => currentState != LiveCardState.empty;
|
bool get show => currentState != LiveCardState.empty;
|
||||||
|
|
||||||
Duration get delay => _delay;
|
Duration get delay => _delay;
|
||||||
|
|
||||||
bool _sameDate(DateTime a, DateTime b) =>
|
bool _sameDate(DateTime a, DateTime b) =>
|
||||||
|
43
refilc/lib/api/providers/liveactivity/platform_channel.dart
Normal file
43
refilc/lib/api/providers/liveactivity/platform_channel.dart
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class PlatformChannel {
|
||||||
|
static const MethodChannel _channel = MethodChannel('hu.refilc/liveactivity');
|
||||||
|
|
||||||
|
static Future<void> createLiveActivity(
|
||||||
|
Map<String, dynamic> activityData) async {
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
try {
|
||||||
|
debugPrint("creating...");
|
||||||
|
await _channel.invokeMethod('createLiveActivity', activityData);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
debugPrint("Hiba történt a Live Activity létrehozásakor: ${e.message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> updateLiveActivity(
|
||||||
|
Map<String, dynamic> activityData) async {
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
try {
|
||||||
|
debugPrint("updating...");
|
||||||
|
await _channel.invokeMethod('updateLiveActivity', activityData);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
debugPrint("Hiba történt a Live Activity frissítésekor: ${e.message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> endLiveActivity() async {
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
try {
|
||||||
|
debugPrint("finishing...");
|
||||||
|
await _channel.invokeMethod('endLiveActivity');
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
debugPrint("Hiba történt a Live Activity befejezésekor: ${e.message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,9 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:home_widget/home_widget.dart';
|
import 'package:home_widget/home_widget.dart';
|
||||||
|
|
||||||
|
import 'live_card_provider.dart';
|
||||||
|
import 'liveactivity/platform_channel.dart';
|
||||||
|
|
||||||
// Mutex
|
// Mutex
|
||||||
bool lock = false;
|
bool lock = false;
|
||||||
|
|
||||||
@ -86,10 +89,17 @@ Future<void> syncAll(BuildContext context) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Future.wait(tasks).then((value) {
|
return Future.wait(tasks).then((value) {
|
||||||
// Unlock
|
// Unlock
|
||||||
lock = false;
|
lock = false;
|
||||||
|
|
||||||
|
if(Platform.isIOS && LiveCardProvider.hasActivityStarted == true){
|
||||||
|
PlatformChannel.endLiveActivity();
|
||||||
|
LiveCardProvider.hasActivityStarted = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Update Widget
|
// Update Widget
|
||||||
if (Platform.isAndroid) updateWidget();
|
if (Platform.isAndroid) updateWidget();
|
||||||
});
|
});
|
||||||
|
15
refilc/lib/helpers/live_activity_helper.dart
Normal file
15
refilc/lib/helpers/live_activity_helper.dart
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import 'package:refilc/api/providers/live_card_provider.dart';
|
||||||
|
import '../api/providers/liveactivity/platform_channel.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class LiveActivityHelper {
|
||||||
|
@pragma('vm:entry-point')
|
||||||
|
void backgroundJob() async {
|
||||||
|
// initialize provider
|
||||||
|
if (!LiveCardProvider.hasDayEnd) {
|
||||||
|
await PlatformChannel.updateLiveActivity(LiveCardProvider.LAData);
|
||||||
|
} else {
|
||||||
|
await PlatformChannel.endLiveActivity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,8 @@ import 'package:refilc_mobile_ui/screens/error_screen.dart';
|
|||||||
import 'package:refilc_mobile_ui/screens/error_report_screen.dart';
|
import 'package:refilc_mobile_ui/screens/error_report_screen.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
|
||||||
|
import 'helpers/live_activity_helper.dart';
|
||||||
|
|
||||||
// days without touching grass: 5,843 (16 yrs)
|
// days without touching grass: 5,843 (16 yrs)
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
@ -84,6 +86,7 @@ class Startup {
|
|||||||
// Notifications setup
|
// Notifications setup
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
initPlatformState();
|
initPlatformState();
|
||||||
|
initAdditionalBackgroundFetch();
|
||||||
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
|
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +199,12 @@ Future<void> initPlatformState() async {
|
|||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print("[BackgroundFetch] Event received $taskId");
|
print("[BackgroundFetch] Event received $taskId");
|
||||||
}
|
}
|
||||||
|
if (taskId == "com.transistorsoft.refilcliveactivity") {
|
||||||
|
if (!Platform.isIOS) return;
|
||||||
|
LiveActivityHelper().backgroundJob();
|
||||||
|
} else {
|
||||||
NotificationsHelper().backgroundJob();
|
NotificationsHelper().backgroundJob();
|
||||||
|
}
|
||||||
BackgroundFetch.finish(taskId);
|
BackgroundFetch.finish(taskId);
|
||||||
}, (String taskId) async {
|
}, (String taskId) async {
|
||||||
// <-- Task timeout handler.
|
// <-- Task timeout handler.
|
||||||
@ -231,6 +239,50 @@ void backgroundHeadlessTask(HeadlessTask task) {
|
|||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('[BackgroundFetch] Headless event received.');
|
print('[BackgroundFetch] Headless event received.');
|
||||||
}
|
}
|
||||||
|
if (taskId == "com.transistorsoft.refilcliveactivity") {
|
||||||
|
if (!Platform.isIOS) return;
|
||||||
|
LiveActivityHelper().backgroundJob();
|
||||||
|
} else {
|
||||||
NotificationsHelper().backgroundJob();
|
NotificationsHelper().backgroundJob();
|
||||||
BackgroundFetch.finish(task.taskId);
|
} BackgroundFetch.finish(task.taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initAdditionalBackgroundFetch() async {
|
||||||
|
int status = await BackgroundFetch.configure(
|
||||||
|
BackgroundFetchConfig(
|
||||||
|
minimumFetchInterval: 1, // 1 minute
|
||||||
|
stopOnTerminate: false,
|
||||||
|
enableHeadless: true,
|
||||||
|
requiresBatteryNotLow: false,
|
||||||
|
requiresCharging: false,
|
||||||
|
requiresStorageNotLow: false,
|
||||||
|
requiresDeviceIdle: false,
|
||||||
|
requiredNetworkType: NetworkType.ANY,
|
||||||
|
startOnBoot: true), (String taskId) async {
|
||||||
|
// <-- Event handler
|
||||||
|
|
||||||
|
if (kDebugMode) {
|
||||||
|
print("[BackgroundFetch] Event received $taskId");
|
||||||
|
}
|
||||||
|
LiveActivityHelper liveActivityHelper = LiveActivityHelper();
|
||||||
|
liveActivityHelper.backgroundJob();
|
||||||
|
|
||||||
|
BackgroundFetch.finish(taskId);
|
||||||
|
}, (String taskId) async {
|
||||||
|
// <-- Task timeout handler.
|
||||||
|
if (kDebugMode) {
|
||||||
|
print("[BackgroundFetch] TASK TIMEOUT taskId: $taskId");
|
||||||
|
}
|
||||||
|
BackgroundFetch.finish(taskId);
|
||||||
|
});
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('[BackgroundFetch] configure success: $status');
|
||||||
|
}
|
||||||
|
BackgroundFetch.scheduleTask(TaskConfig(
|
||||||
|
taskId: "com.transistorsoft.refilcliveactivity",
|
||||||
|
delay: 300000, // 5 minute
|
||||||
|
periodic: true,
|
||||||
|
forceAlarmManager: true,
|
||||||
|
stopOnTerminate: false,
|
||||||
|
enableHeadless: true));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:refilc/api/providers/database_provider.dart';
|
import 'package:refilc/api/providers/database_provider.dart';
|
||||||
@ -10,6 +11,8 @@ import 'package:refilc/theme/colors/dark_mobile.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
import '../api/providers/live_card_provider.dart';
|
||||||
|
|
||||||
enum Pages { home, grades, timetable, notes, absences }
|
enum Pages { home, grades, timetable, notes, absences }
|
||||||
|
|
||||||
enum UpdateChannel { stable, beta, dev }
|
enum UpdateChannel { stable, beta, dev }
|
||||||
@ -691,6 +694,9 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
if (bellDelay != null && bellDelay != _bellDelay) _bellDelay = bellDelay;
|
if (bellDelay != null && bellDelay != _bellDelay) _bellDelay = bellDelay;
|
||||||
if (bellDelayEnabled != null && bellDelayEnabled != _bellDelayEnabled) {
|
if (bellDelayEnabled != null && bellDelayEnabled != _bellDelayEnabled) {
|
||||||
_bellDelayEnabled = bellDelayEnabled;
|
_bellDelayEnabled = bellDelayEnabled;
|
||||||
|
if(Platform.isIOS){
|
||||||
|
LiveCardProvider.hasActivitySettingsChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (gradeOpeningFun != null && gradeOpeningFun != _gradeOpeningFun) {
|
if (gradeOpeningFun != null && gradeOpeningFun != _gradeOpeningFun) {
|
||||||
_gradeOpeningFun = gradeOpeningFun;
|
_gradeOpeningFun = gradeOpeningFun;
|
||||||
|
@ -187,7 +187,7 @@ class AppTheme {
|
|||||||
accentColor == AccentColor.ogfilc) ||
|
accentColor == AccentColor.ogfilc) ||
|
||||||
!settings.newColors
|
!settings.newColors
|
||||||
? accent
|
? accent
|
||||||
: ColorsUtils().lighten(accent, amount: 0.3);
|
: ColorsUtils().lighten(accent, amount: 0.22);
|
||||||
// Color newScaffoldBg = ColorsUtils().lighten(accent, amount: 0.4);
|
// Color newScaffoldBg = ColorsUtils().lighten(accent, amount: 0.4);
|
||||||
Color newTertiary = (accentColor == AccentColor.adaptive ||
|
Color newTertiary = (accentColor == AccentColor.adaptive ||
|
||||||
accentColor == AccentColor.custom ||
|
accentColor == AccentColor.custom ||
|
||||||
|
@ -27,7 +27,7 @@ class LessonTile extends StatelessWidget {
|
|||||||
this.currentLessonIndicator = true,
|
this.currentLessonIndicator = true,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.contentPadding,
|
this.contentPadding,
|
||||||
this.showSubTiles = false,
|
this.showSubTiles = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Lesson lesson;
|
final Lesson lesson;
|
||||||
@ -151,7 +151,8 @@ class LessonTile extends StatelessWidget {
|
|||||||
child: PanelTitle(title: Text(lesson.name)),
|
child: PanelTitle(title: Text(lesson.name)),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(bottom: subtiles.isEmpty ? 0.0 : 12.0),
|
padding: EdgeInsets.only(
|
||||||
|
bottom: (subtiles.isNotEmpty && showSubTiles) ? 12.0 : 0.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@ -245,7 +246,7 @@ class LessonTile extends StatelessWidget {
|
|||||||
? accent.withOpacity(.15)
|
? accent.withOpacity(.15)
|
||||||
: Theme.of(context)
|
: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.secondary
|
.tertiary
|
||||||
.withOpacity(.15),
|
.withOpacity(.15),
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
),
|
),
|
||||||
@ -397,7 +398,7 @@ class LessonTile extends StatelessWidget {
|
|||||||
? accent.withOpacity(.15)
|
? accent.withOpacity(.15)
|
||||||
: Theme.of(context)
|
: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.secondary
|
.tertiary
|
||||||
.withOpacity(.15),
|
.withOpacity(.15),
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
),
|
),
|
||||||
|
@ -3,7 +3,7 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak."
|
|||||||
homepage: https://refilc.hu
|
homepage: https://refilc.hu
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
|
|
||||||
version: 5.0.0+253
|
version: 5.0.0+255
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.0 <=3.3.2"
|
sdk: ">=2.17.0 <=3.3.2"
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:refilc/api/providers/database_provider.dart';
|
import 'package:refilc/api/providers/database_provider.dart';
|
||||||
import 'package:refilc/api/providers/user_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_kreta_api/models/lesson.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/panel/panel_button.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/viewable.dart';
|
||||||
import 'package:refilc_mobile_ui/common/widgets/card_handle.dart';
|
import 'package:refilc_mobile_ui/common/widgets/card_handle.dart';
|
||||||
import 'package:refilc/ui/widgets/lesson/lesson_tile.dart';
|
import 'package:refilc/ui/widgets/lesson/lesson_tile.dart';
|
||||||
@ -49,98 +55,48 @@ class LessonViewableState extends State<LessonViewable> {
|
|||||||
|
|
||||||
if (lsn.subject.id == '' || tile.lesson.isEmpty) return tile;
|
if (lsn.subject.id == '' || tile.lesson.isEmpty) return tile;
|
||||||
|
|
||||||
return Viewable(
|
return LessonTile(
|
||||||
tile: tile,
|
lsn,
|
||||||
view: CardHandle(child: LessonView(lsn)),
|
swapDesc: widget.swapDesc,
|
||||||
actions: [
|
onTap: () => TimetableLessonPopup.show(context: context, lesson: lsn),
|
||||||
PanelButton(
|
);
|
||||||
background: true,
|
|
||||||
title: Text(
|
|
||||||
"edit_lesson".i18n,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context, rootNavigator: true).pop();
|
|
||||||
|
|
||||||
if (!Provider.of<PlusProvider>(context, listen: false)
|
// return Viewable(
|
||||||
.hasScope(PremiumScopes.timetableNotes)) {
|
// tile: tile,
|
||||||
PlusLockedFeaturePopup.show(
|
// view: CardHandle(child: LessonView(lsn)),
|
||||||
context: context, feature: PremiumFeature.timetableNotes);
|
// actions: [
|
||||||
|
// PanelButton(
|
||||||
return;
|
// background: true,
|
||||||
}
|
// title: Text(
|
||||||
|
// "edit_lesson".i18n,
|
||||||
showDialog(
|
// textAlign: TextAlign.center,
|
||||||
context: context,
|
// maxLines: 2,
|
||||||
builder: (context) => StatefulBuilder(builder: (context, setS) {
|
// overflow: TextOverflow.ellipsis,
|
||||||
return AlertDialog(
|
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
|
||||||
title: Text("edit_lesson".i18n),
|
|
||||||
content: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
// description
|
|
||||||
TextField(
|
|
||||||
controller: _descTxt,
|
|
||||||
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: 'l_desc'.i18n,
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
icon: const Icon(
|
|
||||||
FeatherIcons.x,
|
|
||||||
color: Colors.grey,
|
|
||||||
size: 18.0,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
setState(() {
|
|
||||||
_descTxt.text = '';
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// const SizedBox(
|
|
||||||
// height: 14.0,
|
|
||||||
// ),
|
// ),
|
||||||
// // class
|
// onPressed: () {
|
||||||
|
// Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
|
||||||
|
// if (!Provider.of<PlusProvider>(context, listen: false)
|
||||||
|
// .hasScope(PremiumScopes.timetableNotes)) {
|
||||||
|
// PlusLockedFeaturePopup.show(
|
||||||
|
// context: context, feature: PremiumFeature.timetableNotes);
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// showDialog(
|
||||||
|
// context: context,
|
||||||
|
// builder: (context) => StatefulBuilder(builder: (context, setS) {
|
||||||
|
// return AlertDialog(
|
||||||
|
// shape: const RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
||||||
|
// title: Text("edit_lesson".i18n),
|
||||||
|
// content: Column(
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// children: [
|
||||||
|
// // description
|
||||||
// TextField(
|
// TextField(
|
||||||
// controller: _descTxt,
|
// controller: _descTxt,
|
||||||
// onEditingComplete: () async {
|
|
||||||
// // SharedTheme? theme = await shareProvider.getThemeById(
|
|
||||||
// // context,
|
|
||||||
// // id: _paintId.text.replaceAll(' ', ''),
|
|
||||||
// // );
|
|
||||||
|
|
||||||
// // if (theme != null) {
|
|
||||||
// // // set theme variable
|
|
||||||
// // newThemeByID = theme;
|
|
||||||
|
|
||||||
// // _paintId.clear();
|
|
||||||
// // } else {
|
|
||||||
// // ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
// // CustomSnackBar(
|
|
||||||
// // content: Text("theme_not_found".i18n,
|
|
||||||
// // style: const TextStyle(color: Colors.white)),
|
|
||||||
// // backgroundColor: AppColors.of(context).red,
|
|
||||||
// // context: context,
|
|
||||||
// // ),
|
|
||||||
// // );
|
|
||||||
// // }
|
|
||||||
// },
|
|
||||||
// decoration: InputDecoration(
|
// decoration: InputDecoration(
|
||||||
// border: OutlineInputBorder(
|
// border: OutlineInputBorder(
|
||||||
// borderSide: const BorderSide(
|
// borderSide: const BorderSide(
|
||||||
@ -169,38 +125,94 @@ class LessonViewableState extends State<LessonViewable> {
|
|||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
],
|
// // const SizedBox(
|
||||||
),
|
// // height: 14.0,
|
||||||
actions: [
|
// // ),
|
||||||
TextButton(
|
// // // class
|
||||||
child: Text(
|
// // TextField(
|
||||||
"cancel".i18n,
|
// // controller: _descTxt,
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
// // onEditingComplete: () async {
|
||||||
),
|
// // // SharedTheme? theme = await shareProvider.getThemeById(
|
||||||
onPressed: () {
|
// // // context,
|
||||||
Navigator.of(context).maybePop();
|
// // // id: _paintId.text.replaceAll(' ', ''),
|
||||||
},
|
// // // );
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
child: Text(
|
|
||||||
"done".i18n,
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
saveLesson();
|
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
// // // if (theme != null) {
|
||||||
setState(() {});
|
// // // // set theme variable
|
||||||
},
|
// // // newThemeByID = theme;
|
||||||
),
|
|
||||||
],
|
// // // _paintId.clear();
|
||||||
);
|
// // // } else {
|
||||||
}),
|
// // // ScaffoldMessenger.of(context).showSnackBar(
|
||||||
);
|
// // // CustomSnackBar(
|
||||||
},
|
// // // content: Text("theme_not_found".i18n,
|
||||||
),
|
// // // style: const TextStyle(color: Colors.white)),
|
||||||
],
|
// // // backgroundColor: AppColors.of(context).red,
|
||||||
);
|
// // // context: context,
|
||||||
|
// // // ),
|
||||||
|
// // // );
|
||||||
|
// // // }
|
||||||
|
// // },
|
||||||
|
// // 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: 'l_desc'.i18n,
|
||||||
|
// // suffixIcon: IconButton(
|
||||||
|
// // icon: const Icon(
|
||||||
|
// // FeatherIcons.x,
|
||||||
|
// // color: Colors.grey,
|
||||||
|
// // size: 18.0,
|
||||||
|
// // ),
|
||||||
|
// // onPressed: () {
|
||||||
|
// // setState(() {
|
||||||
|
// // _descTxt.text = '';
|
||||||
|
// // });
|
||||||
|
// // },
|
||||||
|
// // ),
|
||||||
|
// // ),
|
||||||
|
// // ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// actions: [
|
||||||
|
// TextButton(
|
||||||
|
// child: Text(
|
||||||
|
// "cancel".i18n,
|
||||||
|
// style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
// ),
|
||||||
|
// onPressed: () {
|
||||||
|
// Navigator.of(context).maybePop();
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// TextButton(
|
||||||
|
// child: Text(
|
||||||
|
// "done".i18n,
|
||||||
|
// style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
// ),
|
||||||
|
// onPressed: () async {
|
||||||
|
// saveLesson();
|
||||||
|
|
||||||
|
// Navigator.of(context).pop();
|
||||||
|
// setState(() {});
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveLesson() async {
|
void saveLesson() async {
|
||||||
@ -218,3 +230,197 @@ class LessonViewableState extends State<LessonViewable> {
|
|||||||
.storeCustomLessonDescriptions(lessonDesc, userId: user.id!);
|
.storeCustomLessonDescriptions(lessonDesc, userId: user.id!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TimetableLessonPopup extends StatelessWidget {
|
||||||
|
const TimetableLessonPopup({super.key, required this.lesson});
|
||||||
|
|
||||||
|
final Lesson lesson;
|
||||||
|
|
||||||
|
static void show({
|
||||||
|
required BuildContext context,
|
||||||
|
required Lesson lesson,
|
||||||
|
}) =>
|
||||||
|
showRoundedModalBottomSheet(
|
||||||
|
context,
|
||||||
|
child: TimetableLessonPopup(
|
||||||
|
lesson: lesson,
|
||||||
|
),
|
||||||
|
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: [
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
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).scaffoldBackgroundColor,
|
||||||
|
darkenAmount: 0.2, lightenAmount: 0.2),
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 38.0,
|
||||||
|
),
|
||||||
|
RoundBorderIcon(
|
||||||
|
icon: Icon(
|
||||||
|
SubjectIcon.resolveVariant(
|
||||||
|
context: context, subject: lesson.subject),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'6:09 - 4:20',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.85),
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12.0,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
lesson.name,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 20.0,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8.0,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
lesson.teacher.name,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.9),
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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(
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -362,6 +362,7 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
|
|
||||||
List<Absence> unexcused = [];
|
List<Absence> unexcused = [];
|
||||||
List<Absence> excused = [];
|
List<Absence> excused = [];
|
||||||
|
List<Absence> pending = [];
|
||||||
|
|
||||||
List<double> absencePositions = [];
|
List<double> absencePositions = [];
|
||||||
List<Color> finalChartColors = [];
|
List<Color> finalChartColors = [];
|
||||||
@ -375,13 +376,14 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
.where((e) =>
|
.where((e) =>
|
||||||
e.delay == 0 && e.state == Justification.excused)
|
e.delay == 0 && e.state == Justification.excused)
|
||||||
.toList();
|
.toList();
|
||||||
|
pending = absenceProvider.absences
|
||||||
|
.where((e) =>
|
||||||
|
e.delay == 0 && e.state == Justification.pending)
|
||||||
|
.toList();
|
||||||
|
|
||||||
value1 = excused.length;
|
value1 = excused.length;
|
||||||
value2 = unexcused.length;
|
value2 = unexcused.length;
|
||||||
value3 = absenceProvider.absences
|
value3 = pending.length;
|
||||||
.where((e) =>
|
|
||||||
e.delay == 0 && e.state == Justification.pending)
|
|
||||||
.length;
|
|
||||||
title1 = "stat_1".i18n;
|
title1 = "stat_1".i18n;
|
||||||
title2 = "stat_2".i18n;
|
title2 = "stat_2".i18n;
|
||||||
suffix = " ${"hr".i18n}";
|
suffix = " ${"hr".i18n}";
|
||||||
@ -394,15 +396,15 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
.where((e) =>
|
.where((e) =>
|
||||||
e.delay != 0 && e.state == Justification.excused)
|
e.delay != 0 && e.state == Justification.excused)
|
||||||
.toList();
|
.toList();
|
||||||
|
pending = absenceProvider.absences
|
||||||
|
.where((e) =>
|
||||||
|
e.delay != 0 && e.state == Justification.pending)
|
||||||
|
.toList();
|
||||||
|
|
||||||
value1 = excused.map((e) => e.delay).fold(0, (a, b) => a + b);
|
value1 = excused.map((e) => e.delay).fold(0, (a, b) => a + b);
|
||||||
value2 =
|
value2 =
|
||||||
unexcused.map((e) => e.delay).fold(0, (a, b) => a + b);
|
unexcused.map((e) => e.delay).fold(0, (a, b) => a + b);
|
||||||
value3 = absenceProvider.absences
|
value3 = pending.map((e) => e.delay).fold(0, (a, b) => a + b);
|
||||||
.where((e) =>
|
|
||||||
e.delay != 0 && e.state == Justification.pending)
|
|
||||||
.map((e) => e.delay)
|
|
||||||
.fold(0, (a, b) => a + b);
|
|
||||||
title1 = "stat_3".i18n;
|
title1 = "stat_3".i18n;
|
||||||
title2 = "stat_4".i18n;
|
title2 = "stat_4".i18n;
|
||||||
suffix = " ${"min".i18n}";
|
suffix = " ${"min".i18n}";
|
||||||
@ -417,7 +419,7 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
int barTotal =
|
int barTotal =
|
||||||
DateTime.now().difference(DateTime(yr, 09, 01)).inDays;
|
DateTime.now().difference(DateTime(yr, 09, 01)).inDays;
|
||||||
|
|
||||||
[...unexcused, ...excused].forEachIndexed((i, a) {
|
[...unexcused, ...excused, ...pending].forEachIndexed((i, a) {
|
||||||
int abs = DateTime.now().difference(a.date).inDays;
|
int abs = DateTime.now().difference(a.date).inDays;
|
||||||
|
|
||||||
double startPos = (barTotal - abs) / barTotal;
|
double startPos = (barTotal - abs) / barTotal;
|
||||||
@ -435,11 +437,14 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
end: endPos,
|
end: endPos,
|
||||||
color: a.state == Justification.excused
|
color: a.state == Justification.excused
|
||||||
? Colors.green
|
? Colors.green
|
||||||
: Colors.red,
|
: a.state == Justification.unexcused
|
||||||
|
? Colors.red
|
||||||
|
: Colors.orange,
|
||||||
));
|
));
|
||||||
if ([...unexcused, ...excused].length > i + 1) {
|
if ([...unexcused, ...excused, ...pending].length > i + 1) {
|
||||||
int nextAbs = DateTime.now()
|
int nextAbs = DateTime.now()
|
||||||
.difference([...unexcused, ...excused][i + 1].date)
|
.difference(
|
||||||
|
[...unexcused, ...excused, ...pending][i + 1].date)
|
||||||
.inDays;
|
.inDays;
|
||||||
|
|
||||||
double nextStartPos = (barTotal - nextAbs) / barTotal;
|
double nextStartPos = (barTotal - nextAbs) / barTotal;
|
||||||
@ -454,7 +459,8 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
|
|
||||||
// print(value2.toString() + '-total');
|
// print(value2.toString() + '-total');
|
||||||
// print(absenceChartData.length.toString() + '-chartdata');
|
// print(absenceChartData.length.toString() + '-chartdata');
|
||||||
if ((i + 1 == [...unexcused, ...excused].length) &&
|
if ((i + 1 ==
|
||||||
|
[...unexcused, ...excused, ...pending].length) &&
|
||||||
endPos < 0.999) {
|
endPos < 0.999) {
|
||||||
absenceChartData.add(AbsenceChartData(
|
absenceChartData.add(AbsenceChartData(
|
||||||
start: endPos,
|
start: endPos,
|
||||||
|
@ -19,6 +19,7 @@ import 'package:refilc_kreta_api/models/grade.dart';
|
|||||||
import 'package:refilc_kreta_api/models/subject.dart';
|
import 'package:refilc_kreta_api/models/subject.dart';
|
||||||
import 'package:refilc_mobile_ui/common/average_display.dart';
|
import 'package:refilc_mobile_ui/common/average_display.dart';
|
||||||
import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.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/filter_bar.dart';
|
import 'package:refilc_mobile_ui/common/filter_bar.dart';
|
||||||
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
||||||
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
||||||
@ -281,7 +282,7 @@ class _GradeSubjectViewState extends State<GradeSubjectView>
|
|||||||
title: Text("exams".i18n),
|
title: Text("exams".i18n),
|
||||||
children: _tiles,
|
children: _tiles,
|
||||||
))
|
))
|
||||||
: const SizedBox(),
|
: const Empty(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
// TODO: REMOVE IN PRODUCTION BUILD!!!
|
// TODO: REMOVE IN PRODUCTION BUILD!!!
|
||||||
// print(_liveCard.currentState);
|
// print(_liveCard.currentState);
|
||||||
// _liveCard.currentState = LiveCardState.duringBreak;
|
// _liveCard.currentState = LiveCardState.duringLesson;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Stack(
|
body: Stack(
|
||||||
@ -330,7 +330,7 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
LiveCardState.duringLesson ||
|
LiveCardState.duringLesson ||
|
||||||
_liveCard.currentState ==
|
_liveCard.currentState ==
|
||||||
LiveCardState.duringBreak)
|
LiveCardState.duringBreak)
|
||||||
? 288.0
|
? 292.0
|
||||||
: 238.0)),
|
: 238.0)),
|
||||||
|
|
||||||
// Live Card
|
// Live Card
|
||||||
@ -348,10 +348,15 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
? 0.0
|
? 0.0
|
||||||
: 62.0) +
|
: 62.0) +
|
||||||
MediaQuery.of(context).padding.top,
|
MediaQuery.of(context).padding.top,
|
||||||
bottom: _liveCard.currentState ==
|
bottom: (_liveCard.currentState ==
|
||||||
LiveCardState.morning
|
LiveCardState.morning)
|
||||||
? 44.0
|
? 44.0
|
||||||
: 52.0,
|
: ((_liveCard.currentState ==
|
||||||
|
LiveCardState.duringLesson ||
|
||||||
|
_liveCard.currentState ==
|
||||||
|
LiveCardState.duringBreak)
|
||||||
|
? 55.0
|
||||||
|
: 52.0),
|
||||||
),
|
),
|
||||||
child: Transform.scale(
|
child: Transform.scale(
|
||||||
scale: _liveCardAnimation.value,
|
scale: _liveCardAnimation.value,
|
||||||
|
@ -6,6 +6,10 @@ import 'package:refilc/helpers/subject.dart';
|
|||||||
import 'package:refilc/models/settings.dart';
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:refilc/ui/widgets/lesson/lesson_tile.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/panel/panel.dart';
|
||||||
import 'package:refilc_mobile_ui/common/progress_bar.dart';
|
import 'package:refilc_mobile_ui/common/progress_bar.dart';
|
||||||
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
||||||
@ -67,30 +71,30 @@ class LiveCardStateA extends State<LiveCard> {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
// TODO: REMOVE IN PRODUCTION BUILD!!!
|
// TODO: REMOVE IN PRODUCTION BUILD!!!
|
||||||
// liveCard.currentState = LiveCardState.duringBreak;
|
/*liveCard.currentState = LiveCardState.duringLesson;
|
||||||
// liveCard.nextLesson = Lesson(
|
liveCard.currentLesson = Lesson(
|
||||||
// date: DateTime.now().add(Duration(
|
date: DateTime.now().add(const Duration(
|
||||||
// minutes: 30,
|
minutes: 30,
|
||||||
// )),
|
)),
|
||||||
// subject: GradeSubject(
|
subject: GradeSubject(
|
||||||
// category: Category(id: 'asd'), id: 'asd', name: 'Matematika'),
|
category: Category(id: 'asd'), id: 'asd', name: 'Matematika'),
|
||||||
// lessonIndex: '1',
|
lessonIndex: '1',
|
||||||
// teacher: Teacher(id: 'id', name: 'name'),
|
teacher: Teacher(id: 'id', name: 'name'),
|
||||||
// start: DateTime.now().subtract(Duration(
|
start: DateTime.now().subtract(const Duration(
|
||||||
// minutes: 30,
|
minutes: 30,
|
||||||
// )),
|
)),
|
||||||
// end: DateTime.now().add(Duration(
|
end: DateTime.now().add(const Duration(
|
||||||
// minutes: 15,
|
minutes: 15,
|
||||||
// )),
|
)),
|
||||||
// homeworkId: 'homeworkId',
|
homeworkId: 'homeworkId',
|
||||||
// id: 'id',
|
id: 'id',
|
||||||
// description: 'description',
|
description: 'description',
|
||||||
// room: 'ABC69',
|
room: 'ABC69',
|
||||||
// groupName: 'groupName',
|
groupName: 'groupName',
|
||||||
// name: 'name',
|
name: 'name',
|
||||||
// );
|
);*/
|
||||||
|
|
||||||
// liveCard.prevLesson = liveCard.nextLesson;
|
liveCard.nextLesson = liveCard.currentLesson;
|
||||||
|
|
||||||
// final dt = DateTime(2024, 3, 22, 17, 12, 1, 1, 1);
|
// final dt = DateTime(2024, 3, 22, 17, 12, 1, 1, 1);
|
||||||
|
|
||||||
@ -408,8 +412,9 @@ class LiveCardStateA extends State<LiveCard> {
|
|||||||
swapRoom: true,
|
swapRoom: true,
|
||||||
currentLessonIndicator: false,
|
currentLessonIndicator: false,
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(top: 8.0, bottom: 4.0),
|
const EdgeInsets.only(top: 6.0, bottom: 4.0),
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
showSubTiles: false,
|
||||||
),
|
),
|
||||||
if (!(nextSubject == null &&
|
if (!(nextSubject == null &&
|
||||||
progressCurrent == null &&
|
progressCurrent == null &&
|
||||||
@ -520,7 +525,7 @@ class LiveCardStateA extends State<LiveCard> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.secondary
|
.tertiary
|
||||||
.withOpacity(.15),
|
.withOpacity(.15),
|
||||||
borderRadius:
|
borderRadius:
|
||||||
BorderRadius.circular(10.0),
|
BorderRadius.circular(10.0),
|
||||||
|
@ -135,12 +135,18 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
title: Text('your_notes'.i18n),
|
title: Text('your_notes'.i18n),
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
isTransparent: true,
|
isTransparent: true,
|
||||||
child: Center(
|
child: selfNoteTiles.length > 1
|
||||||
|
? Center(
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 18.0,
|
spacing: 18.0,
|
||||||
runSpacing: 18.0,
|
runSpacing: 18.0,
|
||||||
children: selfNoteTiles,
|
children: selfNoteTiles,
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
: Wrap(
|
||||||
|
spacing: 18.0,
|
||||||
|
runSpacing: 18.0,
|
||||||
|
children: selfNoteTiles,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
// import 'dart:async';
|
// import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:refilc/api/client.dart';
|
import 'package:refilc/api/client.dart';
|
||||||
import 'package:refilc/api/login.dart';
|
import 'package:refilc/api/login.dart';
|
||||||
import 'package:refilc/theme/colors/colors.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/custom_snack_bar.dart';
|
||||||
import 'package:refilc_mobile_ui/common/system_chrome.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/common/widgets/absence/absence_display.dart';
|
||||||
@ -17,7 +16,6 @@ import 'package:flutter/services.dart';
|
|||||||
import 'login_screen.i18n.dart';
|
import 'login_screen.i18n.dart';
|
||||||
import 'package:carousel_slider/carousel_slider.dart';
|
import 'package:carousel_slider/carousel_slider.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:flutter_portal/flutter_portal.dart';
|
|
||||||
|
|
||||||
class LoginScreen extends StatefulWidget {
|
class LoginScreen extends StatefulWidget {
|
||||||
const LoginScreen({super.key, this.back = false});
|
const LoginScreen({super.key, this.back = false});
|
||||||
@ -85,9 +83,9 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
precacheImage(const AssetImage('assets/images/showcase2.png'), context);
|
precacheImage(const AssetImage('assets/images/showcase2.png'), context);
|
||||||
precacheImage(const AssetImage('assets/images/showcase3.png'), context);
|
precacheImage(const AssetImage('assets/images/showcase3.png'), context);
|
||||||
precacheImage(const AssetImage('assets/images/showcase4.png'), context);
|
precacheImage(const AssetImage('assets/images/showcase4.png'), context);
|
||||||
|
bool selected = false;
|
||||||
|
|
||||||
return Portal(
|
return Scaffold(
|
||||||
child: Scaffold(
|
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: const BoxDecoration(color: Color(0xFFDAE4F7)),
|
decoration: const BoxDecoration(color: Color(0xFFDAE4F7)),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
@ -121,8 +119,7 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
Material(
|
Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
child: showBack
|
child: showBack
|
||||||
? BackButton(
|
? BackButton(color: AppColors.of(context).text)
|
||||||
color: AppColors.of(context).text)
|
|
||||||
: const SizedBox(height: 48.0),
|
: const SizedBox(height: 48.0),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -130,172 +127,208 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
Stack(
|
Stack(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
children: [
|
children: [
|
||||||
// Column(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
// 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: 250,
|
|
||||||
// width: double.infinity,
|
|
||||||
// decoration: const BoxDecoration(
|
|
||||||
// gradient: LinearGradient(
|
|
||||||
// colors: [Color(0x00DAE4F7), Color(0xFFDAE4F7)],
|
|
||||||
// stops: [0, 0.1],
|
|
||||||
// begin: Alignment.topCenter,
|
|
||||||
// end: Alignment.bottomCenter,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// child: Padding(
|
|
||||||
// padding: const EdgeInsets.only(top: 3),
|
|
||||||
// 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: () {},
|
|
||||||
// child: Text(
|
|
||||||
// "login".i18n,
|
|
||||||
// style: const TextStyle(
|
|
||||||
// fontFamily: 'Montserrat',
|
|
||||||
// fontSize: 20,
|
|
||||||
// fontWeight: FontWeight.w700),
|
|
||||||
// )),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(height: 8),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// TODO: OLD LOGIN FROM HERE
|
|
||||||
Column(
|
Column(
|
||||||
//login buttons and ui starts here
|
//login buttons and ui starts here
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
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(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 22.0,
|
right: 20),
|
||||||
right: 22.0,
|
child: Text(
|
||||||
top: 0.0,
|
"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: AutofillGroup(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment
|
||||||
|
.end,
|
||||||
children: [
|
children: [
|
||||||
// username
|
// username
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(bottom: 6.0),
|
const EdgeInsets
|
||||||
|
.only(
|
||||||
|
bottom:
|
||||||
|
6.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
MainAxisAlignment.spaceBetween,
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"username".i18n,
|
"username"
|
||||||
maxLines: 1,
|
.i18n,
|
||||||
style: TextStyle(
|
maxLines:
|
||||||
|
1,
|
||||||
|
style:
|
||||||
|
TextStyle(
|
||||||
color: AppColors.of(context)
|
color: AppColors.of(context)
|
||||||
.loginPrimary,
|
.loginPrimary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight:
|
||||||
fontSize: 12.0,
|
FontWeight.w500,
|
||||||
|
fontSize:
|
||||||
|
12.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"usernameHint".i18n,
|
"usernameHint"
|
||||||
maxLines: 1,
|
.i18n,
|
||||||
textAlign: TextAlign.right,
|
maxLines:
|
||||||
style: TextStyle(
|
1,
|
||||||
|
textAlign:
|
||||||
|
TextAlign
|
||||||
|
.right,
|
||||||
|
style:
|
||||||
|
TextStyle(
|
||||||
color: AppColors.of(context)
|
color: AppColors.of(context)
|
||||||
.loginSecondary,
|
.loginSecondary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight:
|
||||||
fontSize: 12.0,
|
FontWeight.w500,
|
||||||
|
fontSize:
|
||||||
|
12.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -304,43 +337,65 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(bottom: 12.0),
|
const EdgeInsets
|
||||||
|
.only(
|
||||||
|
bottom:
|
||||||
|
12.0),
|
||||||
child: LoginInput(
|
child: LoginInput(
|
||||||
style: LoginInputStyle.username,
|
style:
|
||||||
controller: usernameController,
|
LoginInputStyle
|
||||||
|
.username,
|
||||||
|
controller:
|
||||||
|
usernameController,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// password
|
// password
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(bottom: 6.0),
|
const EdgeInsets
|
||||||
|
.only(
|
||||||
|
bottom:
|
||||||
|
6.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
MainAxisAlignment.spaceBetween,
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"password".i18n,
|
"password"
|
||||||
maxLines: 1,
|
.i18n,
|
||||||
style: TextStyle(
|
maxLines:
|
||||||
|
1,
|
||||||
|
style:
|
||||||
|
TextStyle(
|
||||||
color: AppColors.of(context)
|
color: AppColors.of(context)
|
||||||
.loginPrimary,
|
.loginPrimary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight:
|
||||||
fontSize: 12.0,
|
FontWeight.w500,
|
||||||
|
fontSize:
|
||||||
|
12.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"passwordHint".i18n,
|
"passwordHint"
|
||||||
maxLines: 1,
|
.i18n,
|
||||||
textAlign: TextAlign.right,
|
maxLines:
|
||||||
style: TextStyle(
|
1,
|
||||||
|
textAlign:
|
||||||
|
TextAlign
|
||||||
|
.right,
|
||||||
|
style:
|
||||||
|
TextStyle(
|
||||||
color: AppColors.of(context)
|
color: AppColors.of(context)
|
||||||
.loginSecondary,
|
.loginSecondary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight:
|
||||||
fontSize: 12.0,
|
FontWeight.w500,
|
||||||
|
fontSize:
|
||||||
|
12.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -349,65 +404,122 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(bottom: 12.0),
|
const EdgeInsets
|
||||||
|
.only(
|
||||||
|
bottom:
|
||||||
|
12.0),
|
||||||
child: LoginInput(
|
child: LoginInput(
|
||||||
style: LoginInputStyle.password,
|
style:
|
||||||
controller: passwordController,
|
LoginInputStyle
|
||||||
|
.password,
|
||||||
|
controller:
|
||||||
|
passwordController,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// school
|
// school
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(bottom: 6.0),
|
const EdgeInsets
|
||||||
|
.only(
|
||||||
|
bottom:
|
||||||
|
6.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"school".i18n,
|
"school".i18n,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
style: TextStyle(
|
style:
|
||||||
color: AppColors.of(context)
|
TextStyle(
|
||||||
|
color: AppColors.of(
|
||||||
|
context)
|
||||||
.loginPrimary,
|
.loginPrimary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight:
|
||||||
fontSize: 12.0,
|
FontWeight
|
||||||
|
.w500,
|
||||||
|
fontSize:
|
||||||
|
12.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SchoolInput(
|
SchoolInput(
|
||||||
scroll: _scrollController,
|
scroll:
|
||||||
controller: schoolController,
|
_scrollController,
|
||||||
|
controller:
|
||||||
|
schoolController,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: 22.0,
|
||||||
|
right: 22.0,
|
||||||
|
top: 0.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding:
|
||||||
|
const EdgeInsets.only(
|
||||||
top: 35.0,
|
top: 35.0,
|
||||||
left: 22.0,
|
left: 22.0,
|
||||||
right: 22.0,
|
right: 22.0,
|
||||||
),
|
),
|
||||||
child: Visibility(
|
child: Visibility(
|
||||||
visible: _loginState != LoginState.inProgress,
|
visible: _loginState !=
|
||||||
replacement: const Padding(
|
LoginState
|
||||||
padding: EdgeInsets.symmetric(vertical: 6.0),
|
.inProgress,
|
||||||
child: CircularProgressIndicator(
|
replacement:
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
const Padding(
|
||||||
Colors.white),
|
padding: EdgeInsets
|
||||||
|
.symmetric(
|
||||||
|
vertical:
|
||||||
|
6.0),
|
||||||
|
child:
|
||||||
|
CircularProgressIndicator(
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<
|
||||||
|
Color>(
|
||||||
|
Colors
|
||||||
|
.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: LoginButton(
|
child: LoginButton(
|
||||||
child: Text("login".i18n,
|
child: Text(
|
||||||
|
"login".i18n,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
style: const TextStyle(
|
style:
|
||||||
fontWeight: FontWeight.bold,
|
const TextStyle(
|
||||||
|
fontWeight:
|
||||||
|
FontWeight
|
||||||
|
.bold,
|
||||||
fontSize: 20.0,
|
fontSize: 20.0,
|
||||||
)),
|
)),
|
||||||
onPressed: () => _loginAPI(context: context),
|
onPressed: () =>
|
||||||
|
_loginAPI(
|
||||||
|
context:
|
||||||
|
context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
"login".i18n,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontFamily: 'Montserrat',
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w700),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// TODO: OLD LOGIN FROM HERE
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -449,7 +561,6 @@ class LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:refilc/api/providers/database_provider.dart';
|
import 'package:refilc/api/providers/database_provider.dart';
|
||||||
|
import 'package:refilc/api/providers/live_card_provider.dart';
|
||||||
import 'package:refilc/api/providers/user_provider.dart';
|
import 'package:refilc/api/providers/user_provider.dart';
|
||||||
import 'package:refilc/helpers/quick_actions.dart';
|
import 'package:refilc/helpers/quick_actions.dart';
|
||||||
import 'package:refilc/models/settings.dart';
|
import 'package:refilc/models/settings.dart';
|
||||||
@ -750,6 +751,9 @@ class _BellDelaySettingState extends State<BellDelaySetting>
|
|||||||
Provider.of<SettingsProvider>(context, listen: false)
|
Provider.of<SettingsProvider>(context, listen: false)
|
||||||
.update(bellDelay: currentDelay.inSeconds);
|
.update(bellDelay: currentDelay.inSeconds);
|
||||||
_tabController.index = currentDelay.inSeconds > 0 ? 1 : 0;
|
_tabController.index = currentDelay.inSeconds > 0 ? 1 : 0;
|
||||||
|
if(Platform.isIOS){
|
||||||
|
LiveCardProvider.hasActivitySettingsChanged = true;
|
||||||
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -760,6 +764,9 @@ class _BellDelaySettingState extends State<BellDelaySetting>
|
|||||||
//Provider.of<SettingsProvider>(context, listen: false).update(context, rounding: (r * 10).toInt());
|
//Provider.of<SettingsProvider>(context, listen: false).update(context, rounding: (r * 10).toInt());
|
||||||
Provider.of<SettingsProvider>(context, listen: false)
|
Provider.of<SettingsProvider>(context, listen: false)
|
||||||
.update(bellDelay: currentDelay.inSeconds);
|
.update(bellDelay: currentDelay.inSeconds);
|
||||||
|
if(Platform.isIOS){
|
||||||
|
LiveCardProvider.hasActivitySettingsChanged = true;
|
||||||
|
}
|
||||||
Navigator.of(context).maybePop();
|
Navigator.of(context).maybePop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -897,6 +904,7 @@ class _LiveActivityColorSettingState extends State<LiveActivityColorSetting> {
|
|||||||
currentColor = k as Color;
|
currentColor = k as Color;
|
||||||
settings.update(
|
settings.update(
|
||||||
liveActivityColor: currentColor.withAlpha(255));
|
liveActivityColor: currentColor.withAlpha(255));
|
||||||
|
LiveCardProvider.hasActivitySettingsChanged = true;
|
||||||
Navigator.of(context).maybePop();
|
Navigator.of(context).maybePop();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -913,6 +921,7 @@ class _LiveActivityColorSettingState extends State<LiveActivityColorSetting> {
|
|||||||
var defaultColors =
|
var defaultColors =
|
||||||
SettingsProvider.defaultSettings().liveActivityColor;
|
SettingsProvider.defaultSettings().liveActivityColor;
|
||||||
settings.update(liveActivityColor: defaultColors);
|
settings.update(liveActivityColor: defaultColors);
|
||||||
|
LiveCardProvider.hasActivitySettingsChanged = true;
|
||||||
Navigator.of(context).maybePop();
|
Navigator.of(context).maybePop();
|
||||||
},
|
},
|
||||||
child: Text(SettingsLocalization("reset").i18n),
|
child: Text(SettingsLocalization("reset").i18n),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user