ios live activity

This commit is contained in:
55nknown 2022-10-03 19:37:39 +02:00
parent 75eba2c83f
commit ea33d00f54
20 changed files with 876 additions and 66 deletions

View File

@ -46,6 +46,8 @@ PODS:
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- live_activities (0.0.1):
- Flutter
- open_file (0.0.1):
- Flutter
- path_provider_ios (0.0.1):
@ -77,6 +79,7 @@ DEPENDENCIES:
- flutter_custom_tabs (from `.symlinks/plugins/flutter_custom_tabs/ios`)
- flutter_foreground_task (from `.symlinks/plugins/flutter_foreground_task/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- live_activities (from `.symlinks/plugins/live_activities/ios`)
- open_file (from `.symlinks/plugins/open_file/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
@ -109,6 +112,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_foreground_task/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
live_activities:
:path: ".symlinks/plugins/live_activities/ios"
open_file:
:path: ".symlinks/plugins/open_file/ios"
path_provider_ios:
@ -141,6 +146,7 @@ SPEC CHECKSUMS:
flutter_foreground_task: 21ef182ab0a29a3005cc72cd70e5f45cb7f7f817
flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
live_activities: 9ff56a06a2d43ecd68f56deeed13b18a8304789c
open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce

View File

@ -8,6 +8,13 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3127F78D28EAEDE200C2EFB3 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3127F75528EAECC800C2EFB3 /* WidgetKit.framework */; };
3127F78E28EAEDE200C2EFB3 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3127F75728EAECC800C2EFB3 /* SwiftUI.framework */; };
3127F79828EAEDE300C2EFB3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3127F79728EAEDE300C2EFB3 /* Assets.xcassets */; };
3127F79E28EAEDE300C2EFB3 /* livecard.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 3127F78C28EAEDE200C2EFB3 /* livecard.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
3127F7A428EAEE3D00C2EFB3 /* livecard.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A328EAEE3D00C2EFB3 /* livecard.intentdefinition */; };
3127F7A628EAEE5900C2EFB3 /* livecard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A528EAEE5900C2EFB3 /* livecard.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 */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
@ -16,7 +23,28 @@
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
3127F79C28EAEDE300C2EFB3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 3127F78B28EAEDE200C2EFB3;
remoteInfo = livecardExtension;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
3127F74F28EAEC8A00C2EFB3 /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
3127F79E28EAEDE300C2EFB3 /* livecard.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -33,6 +61,16 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3127F73928EAEC3200C2EFB3 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
3127F73F28EAEC8A00C2EFB3 /* IntentsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IntentsUI.framework; path = System/Library/Frameworks/IntentsUI.framework; sourceTree = SDKROOT; };
3127F75528EAECC800C2EFB3 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
3127F75728EAECC800C2EFB3 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
3127F78C28EAEDE200C2EFB3 /* livecard.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = livecard.appex; sourceTree = BUILT_PRODUCTS_DIR; };
3127F79728EAEDE300C2EFB3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
3127F79928EAEDE300C2EFB3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3127F7A328EAEE3D00C2EFB3 /* livecard.intentdefinition */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.intentdefinition; path = livecard.intentdefinition; sourceTree = "<group>"; };
3127F7A528EAEE5900C2EFB3 /* livecard.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = livecard.swift; sourceTree = "<group>"; tabWidth = 2; };
3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = lesson_model.swift; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; 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>"; };
@ -50,6 +88,15 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
3127F78928EAEDE200C2EFB3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3127F78E28EAEDE200C2EFB3 /* SwiftUI.framework in Frameworks */,
3127F78D28EAEDE200C2EFB3 /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -61,10 +108,25 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
3127F78F28EAEDE200C2EFB3 /* livecard */ = {
isa = PBXGroup;
children = (
3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */,
3127F7A328EAEE3D00C2EFB3 /* livecard.intentdefinition */,
3127F79728EAEDE300C2EFB3 /* Assets.xcassets */,
3127F79928EAEDE300C2EFB3 /* Info.plist */,
3127F7A528EAEE5900C2EFB3 /* livecard.swift */,
);
path = livecard;
sourceTree = "<group>";
};
6640A963014A9D4F31026053 /* Frameworks */ = {
isa = PBXGroup;
children = (
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */,
3127F73F28EAEC8A00C2EFB3 /* IntentsUI.framework */,
3127F75528EAECC800C2EFB3 /* WidgetKit.framework */,
3127F75728EAECC800C2EFB3 /* SwiftUI.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -95,6 +157,7 @@
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
3127F78F28EAEDE200C2EFB3 /* livecard */,
97C146EF1CF9000F007C117D /* Products */,
91FEB6212755D596FFFFEC73 /* Pods */,
6640A963014A9D4F31026053 /* Frameworks */,
@ -105,6 +168,7 @@
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
3127F78C28EAEDE200C2EFB3 /* livecard.appex */,
);
name = Products;
sourceTree = "<group>";
@ -112,6 +176,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
3127F73928EAEC3200C2EFB3 /* Runner.entitlements */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@ -127,6 +192,23 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
3127F78B28EAEDE200C2EFB3 /* livecard */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3127F79F28EAEDE300C2EFB3 /* Build configuration list for PBXNativeTarget "livecard" */;
buildPhases = (
3127F78828EAEDE200C2EFB3 /* Sources */,
3127F78928EAEDE200C2EFB3 /* Frameworks */,
3127F78A28EAEDE200C2EFB3 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = livecard;
productName = livecardExtension;
productReference = 3127F78C28EAEDE200C2EFB3 /* livecard.appex */;
productType = "com.apple.product-type.app-extension";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
@ -139,10 +221,12 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
71459C0EB905E05018E3D78F /* [CP] Embed Pods Frameworks */,
3127F74F28EAEC8A00C2EFB3 /* Embed Foundation Extensions */,
);
buildRules = (
);
dependencies = (
3127F79D28EAEDE300C2EFB3 /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
@ -155,9 +239,13 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1410;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
3127F78B28EAEDE200C2EFB3 = {
CreatedOnToolsVersion = 14.1;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
@ -178,11 +266,20 @@
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
3127F78B28EAEDE200C2EFB3 /* livecard */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
3127F78A28EAEDE200C2EFB3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3127F79828EAEDE300C2EFB3 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -267,6 +364,16 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
3127F78828EAEDE200C2EFB3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3127F7A828EAEE8500C2EFB3 /* lesson_model.swift in Sources */,
3127F7A428EAEE3D00C2EFB3 /* livecard.intentdefinition in Sources */,
3127F7A628EAEE5900C2EFB3 /* livecard.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -278,6 +385,14 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
3127F79D28EAEDE300C2EFB3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 3127F78B28EAEDE200C2EFB3 /* livecard */;
targetProxy = 3127F79C28EAEDE300C2EFB3 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
@ -353,9 +468,12 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = MYUTW2GF6J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -370,6 +488,119 @@
};
name = Profile;
};
3127F7A028EAEDE300C2EFB3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = MYUTW2GF6J;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = livecard/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = livecard;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo.livecard;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
3127F7A128EAEDE300C2EFB3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = MYUTW2GF6J;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = livecard/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = livecard;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo.livecard;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
3127F7A228EAEDE300C2EFB3 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = MYUTW2GF6J;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = livecard/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = livecard;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo.livecard;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -483,9 +714,12 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = MYUTW2GF6J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -505,9 +739,12 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = MYUTW2GF6J;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -525,6 +762,16 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
3127F79F28EAEDE300C2EFB3 /* Build configuration list for PBXNativeTarget "livecard" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3127F7A028EAEDE300C2EFB3 /* Debug */,
3127F7A128EAEDE300C2EFB3 /* Release */,
3127F7A228EAEDE300C2EFB3 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -22,6 +22,8 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSSupportsLiveActivities</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>

View File

@ -1,8 +1,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">
<plist version="1.0">
<dict>
<dict>
<key>aps-environment</key>
<string>production</string>
</dict>
<string>development</string>
</dict>
</plist>

View File

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,13 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,11 @@
<?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>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,27 @@
import Foundation
class LessonData {
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
init?(JSONData data:[String: String]) {
self.icon = data["icon"]!
self.index = data["index"]!
self.title = data["title"]!
self.subtitle = data["subtitle"]!
self.description = data["description"]!
self.startDate = Date(timeIntervalSince1970: Double(data["startDate"]!)! / 1000)
self.endDate = Date(timeIntervalSince1970: Double(data["endDate"]!)! / 1000)
date = self.startDate...self.endDate
self.nextSubject = data["nextSubject"]!
self.nextRoom = data["nextRoom"]!
}
}

View File

@ -0,0 +1,59 @@
<?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>INEnums</key>
<array/>
<key>INIntentDefinitionModelVersion</key>
<string>1.2</string>
<key>INIntentDefinitionNamespace</key>
<string>88xZPY</string>
<key>INIntentDefinitionSystemVersion</key>
<string>20A294</string>
<key>INIntentDefinitionToolsBuildVersion</key>
<string>12A6144</string>
<key>INIntentDefinitionToolsVersion</key>
<string>12.0</string>
<key>INIntents</key>
<array>
<dict>
<key>INIntentCategory</key>
<string>information</string>
<key>INIntentDescriptionID</key>
<string>tVvJ9c</string>
<key>INIntentEligibleForWidgets</key>
<true/>
<key>INIntentIneligibleForSuggestions</key>
<true/>
<key>INIntentName</key>
<string>Configuration</string>
<key>INIntentResponse</key>
<dict>
<key>INIntentResponseCodes</key>
<array>
<dict>
<key>INIntentResponseCodeName</key>
<string>success</string>
<key>INIntentResponseCodeSuccess</key>
<true/>
</dict>
<dict>
<key>INIntentResponseCodeName</key>
<string>failure</string>
</dict>
</array>
</dict>
<key>INIntentTitle</key>
<string>Configuration</string>
<key>INIntentTitleID</key>
<string>gpCwrM</string>
<key>INIntentType</key>
<string>Custom</string>
<key>INIntentVerb</key>
<string>View</string>
</dict>
</array>
<key>INTypes</key>
<array/>
</dict>
</plist>

View File

@ -0,0 +1,137 @@
import ActivityKit
import WidgetKit
import SwiftUI
@main
struct Widgets: WidgetBundle {
var body: some Widget {
if #available(iOS 16.1, *) {
LiveCardWidget()
}
}
}
// We need to redefined live activities pipe
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
public typealias LiveDeliveryData = ContentState
public struct ContentState: Codable, Hashable {
var data: Dictionary<String, String>
}
var id = UUID()
}
@available(iOSApplicationExtension 16.1, *)
struct LiveCardWidget: Widget {
var body: some WidgetConfiguration {
/// Live Activity Notification
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
let lesson = LessonData(JSONData: context.state.data)
HStack(alignment: .center) {
Image(systemName: lesson!.icon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: CGFloat(30), height: CGFloat(30))
.padding(.leading, CGFloat(8))
VStack(alignment: .leading) {
Text(lesson!.index + lesson!.title)
.font(.title3)
.bold()
Text(lesson!.description)
.font(.subheadline)
Spacer()
HStack {
Image(systemName: "arrow.right")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: CGFloat(12), height: CGFloat(12))
Text(lesson!.nextSubject)
.font(.caption)
Text(lesson!.nextRoom)
.font(.caption2)
}
}.padding(15)
Spacer()
Text(lesson!.subtitle)
.font(.subheadline)
.padding(.trailing, 12)
}.padding(12)
/// Dynamic Island
} dynamicIsland: { context in
let lesson = LessonData(JSONData: context.state.data)
/// Expanded
return DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
VStack {
Spacer()
Image(systemName: lesson!.icon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: CGFloat(30), height: CGFloat(30))
.padding(.leading, CGFloat(6))
.padding(.bottom, CGFloat(6))
}
}
DynamicIslandExpandedRegion(.center) {
VStack(alignment: .leading) {
Text(lesson!.index + lesson!.title)
.lineLimit(1)
.font(.title3)
.bold()
Text(lesson!.description)
.lineLimit(2)
.font(.caption)
}
}
DynamicIslandExpandedRegion(.trailing) {
VStack {
Spacer()
Text(lesson!.subtitle)
.lineLimit(1)
.font(.subheadline)
Spacer()
}
}
/// Compact
} compactLeading: {
Label {
Text(lesson!.title)
} icon: {
Image(systemName: lesson!.icon)
}
.font(.caption2)
} compactTrailing: {
Text(timerInterval: lesson!.date, countsDown: true)
.multilineTextAlignment(.center)
.frame(width: 40)
.font(.caption2)
/// Collapsed
} minimal: {
VStack(alignment: .center) {
Image(systemName: lesson!.icon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: CGFloat(12), height: CGFloat(12))
Text(timerInterval: lesson!.date, countsDown: true)
.multilineTextAlignment(.center)
.monospacedDigit()
.font(.system(size: CGFloat(10)))
}
}
.keylineTint(.accentColor)
}
}
}

View File

@ -23,7 +23,7 @@ import 'package:filcnaplo/api/nonce.dart';
enum LoginState { missingFields, invalidGrant, failed, normal, inProgress, success }
Nonce getNonce(BuildContext context, String nonce, String username, String instituteCode) {
Nonce getNonce(String nonce, String username, String instituteCode) {
Nonce nonceEncoder = Nonce(key: [98, 97, 83, 115, 120, 79, 119, 108, 85, 49, 106, 77], nonce: nonce);
nonceEncoder.encode(instituteCode.toUpperCase() + nonce + username.toUpperCase());
@ -46,7 +46,7 @@ Future loginApi({
String nonceStr = await Provider.of<KretaClient>(context, listen: false).getAPI(KretaAPI.nonce, json: false);
Nonce nonce = getNonce(context, nonceStr, username, instituteCode);
Nonce nonce = getNonce(nonceStr, username, instituteCode);
headers.addAll(nonce.header());
Map? res = await Provider.of<KretaClient>(context, listen: false).postAPI(KretaAPI.login,

View File

@ -0,0 +1,198 @@
// ignore_for_file: no_leading_underscores_for_local_identifiers
import 'dart:async';
import 'dart:io';
import 'package:filcnaplo/helpers/subject.dart';
import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo_kreta_api/models/lesson.dart';
import 'package:filcnaplo_kreta_api/models/week.dart';
import 'package:filcnaplo/utils/format.dart';
import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart';
import 'package:flutter/widgets.dart';
import 'package:live_activities/live_activities.dart';
enum LiveCardState { empty, duringLesson, duringBreak, morning, afternoon, night }
class LiveCardProvider extends ChangeNotifier {
Lesson? currentLesson;
Lesson? nextLesson;
Lesson? prevLesson;
List<Lesson>? nextLessons;
LiveCardState currentState = LiveCardState.empty;
late Timer _timer;
late final TimetableProvider _lessonProvider;
late final SettingsProvider _settingsProvider;
late Duration _delay;
final _liveActivitiesPlugin = LiveActivities();
String? _latestActivityId;
Map<String, String> _lastActivity = {};
LiveCardProvider({
required TimetableProvider lessonProvider,
required SettingsProvider settingsProvider,
}) : _lessonProvider = lessonProvider,
_settingsProvider = settingsProvider {
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
lessonProvider.restore().then((_) => update());
_delay = settingsProvider.bellDelayEnabled ? Duration(seconds: settingsProvider.bellDelay) : Duration.zero;
}
@override
void dispose() {
_timer.cancel();
if (_latestActivityId != null && Platform.isIOS) _liveActivitiesPlugin.endActivity(_latestActivityId!);
super.dispose();
}
// Debugging
static DateTime _now() {
return DateTime.now();
}
String getFloorDifference() {
final prevFloor = prevLesson!.getFloor();
final nextFloor = nextLesson!.getFloor();
if (prevFloor == null || nextFloor == null || prevFloor == nextFloor) {
return "to room";
}
if (nextFloor == 0) {
return "ground floor";
}
if (nextFloor > prevFloor) {
return "up floor";
} else {
return "down floor";
}
}
Map<String, String> toMap() {
switch (currentState) {
case LiveCardState.duringLesson:
return {
"icon": currentLesson != null ? SubjectIcon.resolve(subject: currentLesson?.subject).name : "book",
"index": currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
"title": currentLesson != null ? ShortSubject.resolve(subject: currentLesson?.subject).capital() : "",
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
"description": currentLesson?.description ?? "",
"startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
"endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
"nextSubject": nextLesson != null ? ShortSubject.resolve(subject: nextLesson?.subject).capital() : "",
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
};
case LiveCardState.duringBreak:
final iconFloorMap = {
"to room": "chevron.right.2",
"up floor": "arrow.up.right",
"down floor": "arrow.down.left",
"ground floor": "arrow.down.left",
};
final diff = getFloorDifference();
return {
"icon": iconFloorMap[diff] ?? "cup.and.saucer",
"title": "Szünet",
"description": "Maradj ebben a teremben.",
"startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
"nextSubject": nextLesson != null ? ShortSubject.resolve(subject: nextLesson?.subject) : "",
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
"index": "",
"subtitle": "",
};
default:
return {};
}
}
void update() async {
if (Platform.isIOS) {
final cmap = toMap();
if (cmap != _lastActivity) {
_lastActivity = cmap;
if (_lastActivity != {}) {
if (_latestActivityId == null) {
_liveActivitiesPlugin.createActivity(_lastActivity).then((value) => _latestActivityId = value);
} else {
_liveActivitiesPlugin.updateActivity(_latestActivityId!, _lastActivity);
}
} else {
if (_latestActivityId != null) _liveActivitiesPlugin.endActivity(_latestActivityId!);
}
}
}
List<Lesson> today = _today(_lessonProvider);
if (today.isEmpty) {
await _lessonProvider.fetch(week: Week.current());
today = _today(_lessonProvider);
}
_delay = _settingsProvider.bellDelayEnabled ? Duration(seconds: _settingsProvider.bellDelay) : Duration.zero;
final now = _now().add(_delay);
// Filter cancelled lessons #20
today = today.where((lesson) => lesson.status?.name != "Elmaradt").toList();
if (today.isNotEmpty) {
// sort
today.sort((a, b) => a.start.compareTo(b.start));
final _lesson = today.firstWhere((l) => l.start.isBefore(now) && l.end.isAfter(now), orElse: () => Lesson.fromJson({}));
if (_lesson.start.year != 0) {
currentLesson = _lesson;
} else {
currentLesson = null;
}
final _next = today.firstWhere((l) => l.start.isAfter(_now()), orElse: () => Lesson.fromJson({}));
nextLessons = today.where((l) => l.start.isAfter(_now())).toList();
if (_next.start.year != 0) {
nextLesson = _next;
} else {
nextLesson = null;
}
final _prev = today.lastWhere((l) => l.end.isBefore(now), orElse: () => Lesson.fromJson({}));
if (_prev.start.year != 0) {
prevLesson = _prev;
} else {
prevLesson = null;
}
}
if (currentLesson != null) {
currentState = LiveCardState.duringLesson;
} else if (nextLesson != null && prevLesson != null) {
currentState = LiveCardState.duringBreak;
} else if (now.hour >= 12 && now.hour < 20) {
currentState = LiveCardState.afternoon;
} else if (now.hour >= 20) {
currentState = LiveCardState.night;
} else if (now.hour >= 5 && now.hour <= 10) {
currentState = LiveCardState.morning;
} else {
currentState = LiveCardState.empty;
}
notifyListeners();
}
bool get show => currentState != LiveCardState.empty;
Duration get delay => _delay;
bool _sameDate(DateTime a, DateTime b) => (a.year == b.year && a.month == b.month && a.day == b.day);
List<Lesson> _today(TimetableProvider p) => p.lessons.where((l) => _sameDate(l.date, _now())).toList();
}

View File

@ -3,6 +3,7 @@ import 'dart:math';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:filcnaplo/api/client.dart';
import 'package:filcnaplo/api/providers/live_card_provider.dart';
import 'package:filcnaplo/api/providers/news_provider.dart';
import 'package:filcnaplo/api/providers/database_provider.dart';
import 'package:filcnaplo/api/providers/status_provider.dart';
@ -69,14 +70,18 @@ class App extends StatelessWidget {
CorePalette? corePalette;
final status = StatusProvider();
final kreta = KretaClient(user: user, settings: settings, status: status);
final timetable = TimetableProvider(user: user, database: database, kreta: kreta);
return I18n(
initialLocale: Locale(settings.language, settings.language.toUpperCase()),
child: MultiProvider(
providers: [
ChangeNotifierProvider<SettingsProvider>(create: (_) => settings),
ChangeNotifierProvider<UserProvider>(create: (_) => user),
ChangeNotifierProvider<StatusProvider>(create: (context) => StatusProvider()),
Provider<KretaClient>(create: (context) => KretaClient(context: context, userAgent: settings.config.userAgent)),
ChangeNotifierProvider<StatusProvider>(create: (_) => status),
Provider<KretaClient>(create: (_) => kreta),
Provider<DatabaseProvider>(create: (context) => database),
ChangeNotifierProvider<ThemeModeObserver>(create: (context) => ThemeModeObserver(initialTheme: settings.theme)),
ChangeNotifierProvider<NewsProvider>(create: (context) => NewsProvider(context: context)),
@ -84,7 +89,7 @@ class App extends StatelessWidget {
// User data providers
ChangeNotifierProvider<GradeProvider>(create: (context) => GradeProvider(context: context)),
ChangeNotifierProvider<TimetableProvider>(create: (context) => TimetableProvider(context: context)),
ChangeNotifierProvider<TimetableProvider>(create: (_) => timetable),
ChangeNotifierProvider<ExamProvider>(create: (context) => ExamProvider(context: context)),
ChangeNotifierProvider<HomeworkProvider>(create: (context) => HomeworkProvider(context: context)),
ChangeNotifierProvider<MessageProvider>(create: (context) => MessageProvider(context: context)),
@ -93,6 +98,7 @@ class App extends StatelessWidget {
ChangeNotifierProvider<AbsenceProvider>(create: (context) => AbsenceProvider(context: context)),
ChangeNotifierProvider<GradeCalculatorProvider>(create: (context) => GradeCalculatorProvider(context)),
ChangeNotifierProvider<LiveCardProvider>(create: (context) => LiveCardProvider(lessonProvider: timetable, settingsProvider: settings))
],
child: Consumer<ThemeModeObserver>(
builder: (context, themeMode, child) {

View File

@ -0,0 +1,119 @@
import 'package:filcnaplo/icons/filc_icons.dart';
import 'package:filcnaplo/utils/format.dart';
import 'package:filcnaplo_kreta_api/models/subject.dart';
import 'package:flutter/cupertino.dart';
class SubjectIconData {
final IconData data;
final String name; // for iOS live activities compatibilty
SubjectIconData({
this.data = CupertinoIcons.rectangle_grid_2x2,
this.name = "square.grid.2x2",
});
}
class SubjectIcon {
static SubjectIconData resolve({Subject? subject, String? subjectName}) {
assert(!(subject == null && subjectName == null));
String name = (subject?.name ?? subjectName ?? "").toLowerCase().specialChars().trim();
String category = subject?.category.description.toLowerCase().specialChars() ?? "";
// todo: check for categories
if (RegExp("mate(k|matika)").hasMatch(name) || category == "matematika") {
return SubjectIconData(data: CupertinoIcons.function, name: "function");
} else if (RegExp("magyar nyelv|nyelvtan").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.textformat_alt, name: "textformat.alt");
} else if (RegExp("irodalom").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.book, name: "book");
} else if (RegExp("tor(i|tenelem)").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.compass, name: "safari");
} else if (RegExp("foldrajz").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.map, name: "map");
} else if (RegExp("rajz|muvtori|muveszet|vizualis").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.paintbrush, name: "paintbrush");
} else if (RegExp("fizika").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.lightbulb, name: "lightbulb");
} else if (RegExp("^enek|zene|szolfezs|zongora|korus").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.music_note, name: "music.note");
} else if (RegExp("^tes(i|tneveles)|sport").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.sportscourt, name: "sportscourt");
} else if (RegExp("kemia").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.lab_flask, name: "testtube.2");
} else if (RegExp("biologia").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.paw, name: "pawprint");
} else if (RegExp("kornyezet|termeszet ?(tudomany|ismeret)|hon( es nep)?ismeret").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.arrow_3_trianglepath, name: "arrow.3.trianglepath");
} else if (RegExp("(hit|erkolcs)tan|vallas|etika").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.heart, name: "heart");
} else if (RegExp("penzugy").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.money_dollar, name: "dollarsign");
} else if (RegExp("informatika|szoftver|iroda|digitalis").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.device_laptop, name: "laptopcomputer");
} else if (RegExp("prog").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.chevron_left_slash_chevron_right, name: "chevron.left.forwardslash.chevron.right");
} else if (RegExp("halozat").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.antenna_radiowaves_left_right, name: "antenna.radiowaves.left.and.right");
} else if (RegExp("szinhaz").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.hifispeaker, name: "hifispeaker");
} else if (RegExp("film|media").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.film, name: "film");
} else if (RegExp("elektro(tech)?nika").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.bolt, name: "bolt");
} else if (RegExp("gepesz|mernok|ipar").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.wrench, name: "wrench");
} else if (RegExp("technika").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.hammer, name: "hammer");
} else if (RegExp("tanc").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.music_mic, name: "music.mic");
} else if (RegExp("filozofia").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.bubble_left, name: "bubble.left");
} else if (RegExp("osztaly(fonoki|kozosseg)").hasMatch(name) || name == "ofo") {
return SubjectIconData(data: CupertinoIcons.group, name: "person.3");
} else if (RegExp("gazdasag").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.chart_pie, name: "chart.pie");
} else if (RegExp("szorgalom").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.checkmark_seal, name: "checkmark.seal");
} else if (RegExp("magatartas").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.smiley, name: "face.smiling");
} else if (RegExp("angol|nemet|francia|olasz|orosz|spanyol|latin|kinai|nyelv").hasMatch(name)) {
return SubjectIconData(data: CupertinoIcons.globe, name: "globe");
} else if (RegExp("linux").hasMatch(name)) {
return SubjectIconData(data: FilcIcons.linux);
}
return SubjectIconData();
}
}
class ShortSubject {
static String resolve({Subject? subject, String? subjectName}) {
assert(!(subject == null && subjectName == null));
String name = (subject?.name ?? subjectName ?? "").toLowerCase().specialChars().trim();
// String category = subject?.category.description.toLowerCase().specialChars() ?? "";
if (RegExp("magyar irodalom").hasMatch(name)) {
return "Irodalom";
} else if (RegExp("magyar nyelv").hasMatch(name)) {
return "Nyelvtan";
} else if (RegExp("matematika").hasMatch(name)) {
return "Matek";
} else if (RegExp("digitalis kultura").hasMatch(name)) {
return "Dig. kult.";
} else if (RegExp("testneveles").hasMatch(name)) {
return "Tesi";
} else if (RegExp("tortenelem").hasMatch(name)) {
return "Töri";
} else if (RegExp("(angol|nemet|francia|olasz|orosz|spanyol|latin|kinai) nyelv").hasMatch(name)) {
return (subject?.name ?? subjectName ?? "?").replaceAll(" nyelv", "");
} else if (RegExp("informatika").hasMatch(name)) {
return "Infó";
} else if (RegExp("osztalyfonoki").hasMatch(name)) {
return "Ofő";
}
return subject?.name.capital() ?? subjectName?.capital() ?? "?";
}
}

View File

@ -1,46 +0,0 @@
import 'package:filcnaplo/icons/filc_icons.dart';
import 'package:filcnaplo/utils/format.dart';
import 'package:filcnaplo_kreta_api/models/subject.dart';
import 'package:flutter/material.dart';
class SubjectIcon {
static IconData? lookup({Subject? subject, String? subjectName}) {
assert(!(subject == null && subjectName == null));
String name = (subject?.name ?? subjectName ?? "").toLowerCase().specialChars().trim();
String category = subject?.category.description.toLowerCase().specialChars() ?? "";
// todo: check for categories
if (RegExp("mate(k|matika)").hasMatch(name) || category == "matematika") return Icons.calculate_outlined;
if (RegExp("magyar nyelv|nyelvtan").hasMatch(name)) return Icons.spellcheck_outlined;
if (RegExp("irodalom").hasMatch(name)) return Icons.menu_book_outlined;
if (RegExp("tor(i|tenelem)").hasMatch(name)) return Icons.hourglass_empty_outlined;
if (RegExp("foldrajz").hasMatch(name)) return Icons.public_outlined;
if (RegExp("rajz|muvtori|muveszet|vizualis").hasMatch(name)) return Icons.palette_outlined;
if (RegExp("fizika").hasMatch(name)) return Icons.emoji_objects_outlined;
if (RegExp("^enek|zene|szolfezs|zongora|korus").hasMatch(name)) return Icons.music_note_outlined;
if (RegExp("^tes(i|tneveles)|sport").hasMatch(name)) return Icons.sports_soccer_outlined;
if (RegExp("kemia").hasMatch(name)) return Icons.science_outlined;
if (RegExp("biologia").hasMatch(name)) return Icons.pets_outlined;
if (RegExp("kornyezet|termeszet(tudomany|ismeret)|hon( es nep)?ismeret").hasMatch(name)) return Icons.eco_outlined;
if (RegExp("(hit|erkolcs)tan|vallas|etika").hasMatch(name)) return Icons.favorite_border_outlined;
if (RegExp("penzugy").hasMatch(name)) return Icons.savings_outlined;
if (RegExp("informatika|szoftver|iroda|digitalis").hasMatch(name)) return Icons.computer_outlined;
if (RegExp("prog").hasMatch(name)) return Icons.code_outlined;
if (RegExp("halozat").hasMatch(name)) return Icons.wifi_tethering_outlined;
if (RegExp("szinhaz").hasMatch(name)) return Icons.theater_comedy_outlined;
if (RegExp("film|media").hasMatch(name)) return Icons.theaters_outlined;
if (RegExp("elektro(tech)?nika").hasMatch(name)) return Icons.electrical_services_outlined;
if (RegExp("gepesz|mernok|ipar").hasMatch(name)) return Icons.precision_manufacturing_outlined;
if (RegExp("technika").hasMatch(name)) return Icons.build_outlined;
if (RegExp("tanc").hasMatch(name)) return Icons.speaker_outlined;
if (RegExp("filozofia").hasMatch(name)) return Icons.psychology_outlined;
if (RegExp("osztaly(fonoki|kozosseg)").hasMatch(name) || name == "ofo") return Icons.groups_outlined;
if (RegExp("gazdasag").hasMatch(name)) return Icons.account_balance_outlined;
if (RegExp("szorgalom").hasMatch(name)) return Icons.verified_outlined;
if (RegExp("magatartas").hasMatch(name)) return Icons.emoji_people_outlined;
if (RegExp("angol|nemet|francia|olasz|orosz|spanyol|latin|kinai|nyelv").hasMatch(name)) return Icons.translate_outlined;
if (RegExp("linux").hasMatch(name)) return FilcIcons.linux;
return Icons.widgets_outlined;
}
}

View File

@ -1,7 +1,7 @@
import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/theme/colors/colors.dart';
import 'package:filcnaplo_kreta_api/models/grade.dart';
import 'package:filcnaplo/helpers/subject_icon.dart';
import 'package:filcnaplo/helpers/subject.dart';
import 'package:filcnaplo/utils/format.dart';
import 'package:filcnaplo_mobile_ui/pages/grades/calculator/grade_calculator_provider.dart';
import 'package:filcnaplo_mobile_ui/pages/grades/subject_grades_container.dart';
@ -79,7 +79,11 @@ class GradeTile extends StatelessWidget {
child: Center(
child: Padding(
padding: leadingPadding,
child: Icon(SubjectIcon.lookup(subject: grade.subject), size: 28.0, color: AppColors.of(context).text.withOpacity(.75)),
child: Icon(
SubjectIcon.resolve(subject: grade.subject).data,
size: 28.0,
color: AppColors.of(context).text.withOpacity(.75),
),
),
),
),

View File

@ -48,10 +48,9 @@ dependencies:
flutter_feather_icons: ^2.0.0+1
flutter_foreground_task: ^3.9.0
flutter_local_notifications: ^11.0.0
live_activities: ^1.0.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.1
# flutter_launcher_icons: ^0.9.0
# flutter_native_splash: ^1.2.0

@ -1 +1 @@
Subproject commit f6cc4a0ace62f3c5b3de8e86bfc7005d33faa2b5
Subproject commit 9a396a08423f4a2e2008dcedeff90db18999cfcf