#26 new: ios home widget

This commit is contained in:
lollipopkit
2023-07-16 22:46:32 +08:00
parent 814e9c853a
commit 0ee55d4873
12 changed files with 683 additions and 99 deletions

View File

@@ -13,9 +13,27 @@
9234EA956D1225D388A01660 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C1EB3935F9285537B0516 /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
E33A3E372A626DCD009744AB /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E33A3E362A626DCD009744AB /* WidgetKit.framework */; };
E33A3E392A626DCD009744AB /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E33A3E382A626DCD009744AB /* SwiftUI.framework */; };
E33A3E3C2A626DCE009744AB /* StatusWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A3E3B2A626DCE009744AB /* StatusWidgetBundle.swift */; };
E33A3E402A626DCE009744AB /* StatusWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A3E3F2A626DCE009744AB /* StatusWidget.swift */; };
E33A3E432A626DD0009744AB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E33A3E422A626DD0009744AB /* Assets.xcassets */; };
E33A3E452A626DD0009744AB /* StatusWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = E33A3E412A626DCE009744AB /* StatusWidget.intentdefinition */; };
E33A3E462A626DD0009744AB /* StatusWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = E33A3E412A626DCE009744AB /* StatusWidget.intentdefinition */; };
E33A3E492A626DD0009744AB /* StatusWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = E33A3E352A626DCD009744AB /* StatusWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
E3DB67ED2A31FE200027B8CB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E3DB67EB2A31FE200027B8CB /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
E33A3E472A626DD0009744AB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = E33A3E342A626DCD009744AB;
remoteInfo = StatusWidgetExtension;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
@@ -27,6 +45,17 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
E33A3E4A2A626DD0009744AB /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
E33A3E492A626DD0009744AB /* StatusWidgetExtension.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
@@ -46,6 +75,14 @@
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9C5314B89F1F73A1900CCAFD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
A775F241DEE026555178AC01 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
E33A3E352A626DCD009744AB /* StatusWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = StatusWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
E33A3E362A626DCD009744AB /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
E33A3E382A626DCD009744AB /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
E33A3E3B2A626DCE009744AB /* StatusWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusWidgetBundle.swift; sourceTree = "<group>"; };
E33A3E3F2A626DCE009744AB /* StatusWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusWidget.swift; sourceTree = "<group>"; };
E33A3E412A626DCE009744AB /* StatusWidget.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = StatusWidget.intentdefinition; sourceTree = "<group>"; };
E33A3E422A626DD0009744AB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
E33A3E442A626DD0009744AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E398BF6A29BDB34500FE4FD5 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
E3DB67EC2A31FE200027B8CB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -59,6 +96,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
E33A3E322A626DCD009744AB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E33A3E392A626DCD009744AB /* SwiftUI.framework in Frameworks */,
E33A3E372A626DCD009744AB /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -88,6 +134,7 @@
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
E33A3E3A2A626DCE009744AB /* StatusWidget */,
97C146EF1CF9000F007C117D /* Products */,
65C40392B90925608A0465EE /* Pods */,
D242A20E381A343934B6A7B6 /* Frameworks */,
@@ -98,6 +145,7 @@
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
E33A3E352A626DCD009744AB /* StatusWidgetExtension.appex */,
);
name = Products;
sourceTree = "<group>";
@@ -122,10 +170,24 @@
isa = PBXGroup;
children = (
278C1EB3935F9285537B0516 /* Pods_Runner.framework */,
E33A3E362A626DCD009744AB /* WidgetKit.framework */,
E33A3E382A626DCD009744AB /* SwiftUI.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
E33A3E3A2A626DCE009744AB /* StatusWidget */ = {
isa = PBXGroup;
children = (
E33A3E3B2A626DCE009744AB /* StatusWidgetBundle.swift */,
E33A3E3F2A626DCE009744AB /* StatusWidget.swift */,
E33A3E412A626DCE009744AB /* StatusWidget.intentdefinition */,
E33A3E422A626DD0009744AB /* Assets.xcassets */,
E33A3E442A626DD0009744AB /* Info.plist */,
);
path = StatusWidget;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -141,22 +203,42 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
AA0A1FF2F3246F84EB0D91F2 /* [CP] Embed Pods Frameworks */,
E33A3E4A2A626DD0009744AB /* Embed Foundation Extensions */,
);
buildRules = (
);
dependencies = (
E33A3E482A626DD0009744AB /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
E33A3E342A626DCD009744AB /* StatusWidgetExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = E33A3E4E2A626DD0009744AB /* Build configuration list for PBXNativeTarget "StatusWidgetExtension" */;
buildPhases = (
E33A3E312A626DCD009744AB /* Sources */,
E33A3E322A626DCD009744AB /* Frameworks */,
E33A3E332A626DCD009744AB /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = StatusWidgetExtension;
productName = StatusWidgetExtension;
productReference = E33A3E352A626DCD009744AB /* StatusWidgetExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1430;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
@@ -164,6 +246,9 @@
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
E33A3E342A626DCD009744AB = {
CreatedOnToolsVersion = 14.3;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
@@ -180,6 +265,7 @@
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
E33A3E342A626DCD009744AB /* StatusWidgetExtension */,
);
};
/* End PBXProject section */
@@ -196,6 +282,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
E33A3E332A626DCD009744AB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E33A3E432A626DD0009744AB /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -278,11 +372,30 @@
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
E33A3E462A626DD0009744AB /* StatusWidget.intentdefinition in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E33A3E312A626DCD009744AB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E33A3E402A626DCE009744AB /* StatusWidget.swift in Sources */,
E33A3E452A626DD0009744AB /* StatusWidget.intentdefinition in Sources */,
E33A3E3C2A626DCE009744AB /* StatusWidgetBundle.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
E33A3E482A626DD0009744AB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = E33A3E342A626DCD009744AB /* StatusWidgetExtension */;
targetProxy = E33A3E472A626DD0009744AB /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
@@ -357,10 +470,11 @@
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 = 373;
CURRENT_PROJECT_VERSION = 376;
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -368,7 +482,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.373;
MARKETING_VERSION = 1.0.376;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -488,10 +602,11 @@
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 = 373;
CURRENT_PROJECT_VERSION = 376;
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -499,7 +614,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.373;
MARKETING_VERSION = 1.0.376;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -513,10 +628,11 @@
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 = 373;
CURRENT_PROJECT_VERSION = 376;
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -524,7 +640,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.373;
MARKETING_VERSION = 1.0.376;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -533,6 +649,117 @@
};
name = Release;
};
E33A3E4B2A626DD0009744AB /* 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = StatusWidget/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = StatusWidget;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
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 = com.lollipopkit.toolbox.StatusWidget;
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;
};
E33A3E4C2A626DD0009744AB /* 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = StatusWidget/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = StatusWidget;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
E33A3E4D2A626DD0009744AB /* 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = StatusWidget/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = StatusWidget;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Profile;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -556,6 +783,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E33A3E4E2A626DD0009744AB /* Build configuration list for PBXNativeTarget "StatusWidgetExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E33A3E4B2A626DD0009744AB /* Debug */,
E33A3E4C2A626DD0009744AB /* Release */,
E33A3E4D2A626DD0009744AB /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;

View File

@@ -1,68 +1,72 @@
<?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>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>zh</string>
</array>
<key>CFBundleName</key>
<string>ServerBox</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSBonjourServices</key>
<array>
<string>_dartobservatory._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>ServerBox needs to access your local network to discover and connect to your server.</string>
</dict>
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>zh</string>
</array>
<key>CFBundleName</key>
<string>ServerBox</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSBonjourServices</key>
<array>
<string>_dartobservatory._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>ServerBox needs to access your local network to discover and connect to your server.</string>
<key>NSUserActivityTypes</key>
<array>
<string>ConfigurationIntent</string>
</array>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

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,118 @@
<?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>22F82</string>
<key>INIntentDefinitionToolsBuildVersion</key>
<string>14E222b</string>
<key>INIntentDefinitionToolsVersion</key>
<string>14.3</string>
<key>INIntents</key>
<array>
<dict>
<key>INIntentCategory</key>
<string>information</string>
<key>INIntentDescription</key>
<string>Config for home status widget</string>
<key>INIntentDescriptionID</key>
<string>tVvJ9c</string>
<key>INIntentEligibleForWidgets</key>
<true/>
<key>INIntentIneligibleForSuggestions</key>
<true/>
<key>INIntentLastParameterTag</key>
<integer>2</integer>
<key>INIntentName</key>
<string>Configuration</string>
<key>INIntentParameters</key>
<array>
<dict>
<key>INIntentParameterConfigurable</key>
<true/>
<key>INIntentParameterDisplayName</key>
<string>Url</string>
<key>INIntentParameterDisplayNameID</key>
<string>5QiOUM</string>
<key>INIntentParameterDisplayPriority</key>
<integer>1</integer>
<key>INIntentParameterMetadata</key>
<dict>
<key>INIntentParameterMetadataCapitalization</key>
<string>Characters</string>
<key>INIntentParameterMetadataDefaultValue</key>
<string>https://push.lolli.tech</string>
<key>INIntentParameterMetadataDefaultValueID</key>
<string>wwvqC2</string>
<key>INIntentParameterMetadataDisableAutocorrect</key>
<true/>
<key>INIntentParameterMetadataDisableSmartDashes</key>
<true/>
<key>INIntentParameterMetadataDisableSmartQuotes</key>
<true/>
</dict>
<key>INIntentParameterName</key>
<string>url</string>
<key>INIntentParameterPromptDialogs</key>
<array>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogType</key>
<string>Configuration</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogFormatString</key>
<string>Server monitor url</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>j41owf</string>
<key>INIntentParameterPromptDialogType</key>
<string>Primary</string>
</dict>
</array>
<key>INIntentParameterSupportsResolution</key>
<true/>
<key>INIntentParameterTag</key>
<integer>1</integer>
<key>INIntentParameterType</key>
<string>String</string>
</dict>
</array>
<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>StatusWidgetConf</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,207 @@
//
// StatusWidget.swift
// StatusWidget
//
// Created by lolli on 2023/7/15.
//
import WidgetKit
import SwiftUI
import Intents
struct Status {
let name: String
let cpu: String
let mem: String
let disk: String
let net: String
}
let demoStatus = Status(name: "Server Name", cpu: "31.7%", mem: "1.3g / 1.9g", disk: "7.1g / 30.0g", net: "712.3k / 1.2m")
let domain = "com.lollipopkit.toolbox"
var url: String?
struct Provider: IntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationIntent(), data: demoStatus, state: .normal)
}
func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), configuration: configuration, data: demoStatus, state: .normal)
completion(entry)
}
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
url = configuration.url
let currentDate = Date()
let refreshDate = Calendar.current.date(byAdding: .minute, value: 30, to: currentDate)!
StatusLoader.fetch { result in
let entry: SimpleEntry
switch result {
case .success(let status):
entry = SimpleEntry(
date: currentDate,
configuration: configuration,
data: status,
state: .normal
)
case .failure(let err):
entry = SimpleEntry(date: currentDate, configuration: configuration, data: demoStatus, state: .error(err.localizedDescription))
}
let timeline = Timeline(entries: [entry], policy: .after(refreshDate))
completion(timeline)
}
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationIntent
let data: Status
let state: ContentState
}
struct StatusWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
switch entry.state {
case .loading:
ProgressView().padding()
case .error(let descriotion):
Text(descriotion)
case .normal:
VStack(alignment: .leading, spacing: 5.7) {
Text(entry.data.name).font(.system(.title3))
Spacer()
DetailItem(icon: "cpu", text: entry.data.cpu, color: .primary.opacity(0.7))
DetailItem(icon: "memorychip", text: entry.data.mem, color: .primary.opacity(0.7))
DetailItem(icon: "externaldrive", text: entry.data.disk, color: .primary.opacity(0.7))
Spacer()
DetailItem(icon: "clock", text: date2String(entry.date, dateFormat: "HH:mm"), color: .primary.opacity(0.7))
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
.padding()
}
}
}
struct StatusWidget: Widget {
let kind: String = "StatusWidget"
var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
StatusWidgetEntryView(entry: entry)
}
.configurationDisplayName("Status")
.description("Status of your servers.")
.supportedFamilies([.systemSmall])
}
}
struct StatusWidget_Previews: PreviewProvider {
static var previews: some View {
StatusWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent(), data: demoStatus, state: .normal))
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}
struct StatusLoader {
static func fetch(completion: @escaping (Result<Status, Error>) -> Void) {
if url == nil || url == "" {
completion(.failure(NSError(domain: domain, code: 1, userInfo: [NSLocalizedDescriptionKey: "Please longpress it to config first."])))
return
}
let URL = URL(string: url!)!
let task = URLSession.shared.dataTask(with: URL) { (data, response, error) in
guard error == nil else {
completion(.failure(error!))
return
}
guard data != nil else {
completion(.failure(NSError(domain: domain, code: 2, userInfo: [NSLocalizedDescriptionKey: "empty network data."])))
return
}
let result = getStatus(fromData: data!)
switch result {
case .success(let status):
completion(.success(status))
case .failure(let error):
completion(.failure(error))
}
}
task.resume()
}
static func getStatus(fromData data: Foundation.Data) -> Result<Status, Error> {
let jsonAll = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
let code = jsonAll["code"] as! Int
if (code != 0) {
switch (code) {
default:
let msg = jsonAll["msg"] as! String? ?? ""
return .failure(NSError(domain: domain, code: code, userInfo: [NSLocalizedDescriptionKey: msg]))
}
}
let json = jsonAll["data"] as! [String: Any]
let name = json["name"] as! String
let disk = json["disk"] as! String
let cpu = json["cpu"] as! String
let mem = json["mem"] as! String
let net = json["net"] as! String
return .success(Status(name: name, cpu: cpu, mem: mem, disk: disk, net: net))
}
}
private func dynamicUIColor(color: DynamicColor) -> UIColor {
if #available(iOS 13, *) { // 13
return UIColor { (traitCollection: UITraitCollection) -> UIColor in
return traitCollection.userInterfaceStyle == UIUserInterfaceStyle.dark ?
color.dark : color.light
}
}
return color.light
}
struct DynamicColor {
let dark: UIColor
let light: UIColor
}
let bgColor = DynamicColor(dark: UIColor(.black), light: UIColor(.white))
let textColor = DynamicColor(dark: UIColor(.white), light: UIColor(.black))
private func dynamicColor(color: DynamicColor) -> Color {
return Color.init(dynamicUIColor(color: color))
}
struct DetailItem: View {
let icon: String
let text: String
let color: Color
var body: some View {
HStack(spacing: 5.7) {
Image(systemName: icon).resizable().foregroundColor(color).frame(width: 11, height: 11, alignment: .center)
Text(text)
.font(.system(.caption2))
.foregroundColor(color)
}
}
}
func date2String(_ date:Date, dateFormat:String = "yyyy-MM-dd HH:mm:ss") -> String {
let formatter = DateFormatter()
formatter.locale = Locale.init(identifier: "zh_CN")
formatter.dateFormat = dateFormat
let date = formatter.string(from: date)
return date
}
enum ContentState {
case loading
case error(String)
case normal
}

View File

@@ -0,0 +1,16 @@
//
// StatusWidgetBundle.swift
// StatusWidget
//
// Created by lolli on 2023/7/15.
//
import WidgetKit
import SwiftUI
@main
struct StatusWidgetBundle: WidgetBundle {
var body: some Widget {
StatusWidget()
}
}

View File

@@ -53,8 +53,8 @@ extension OrderX<T> on Order<T> {
}
/// order: ['d', 'b', 'e']\
/// items: ['a', 'b', 'c', 'd']\
/// result: ['b', 'd', 'a', 'c']\
/// this: ['a', 'b', 'c', 'd']\
/// result: ['d', 'b', 'a', 'c']\
/// return: ['e']
List<String> reorder({
required List<String> order,

View File

@@ -45,22 +45,14 @@ class ServerProvider extends BusyProvider {
}
final serverOrder_ = _settingStore.serverOrder.fetch();
if (serverOrder_ != null) {
_serverOrder.addAll(serverOrder_.toSet());
if (_serverOrder.length != spis.length) {
final missed = spis
.where(
(e) => !_serverOrder.contains(e.id),
)
.map((e) => e.id);
_serverOrder.addAll(missed);
}
spis.reorder(
order: serverOrder_,
finder: (n, id) => n.id == id,
);
_serverOrder.addAll(spis.map((e) => e.id));
} else {
_serverOrder.addAll(_servers.keys);
}
final surplus = _serverOrder.where(
(e) => !_servers.containsKey(e),
);
_serverOrder.removeWhere((element) => surplus.contains(element));
_settingStore.serverOrder.put(_serverOrder);
_updateTags();
setBusyState(false);

View File

@@ -24,7 +24,7 @@ class SnippetProvider extends BusyProvider {
if (order != null) {
final surplus = _snippets.reorder(
order: order,
finder: (order, name) => order.name == name,
finder: (n, name) => n.name == name,
);
order.removeWhere((e) => surplus.any((ele) => ele == e));
_setting.snippetOrder.put(order);

View File

@@ -2,8 +2,8 @@
class BuildData {
static const String name = "ServerBox";
static const int build = 375;
static const int build = 376;
static const String engine = "3.10.5";
static const String buildAt = "2023-07-08 14:54:40.994903";
static const int modifications = 12;
static const String buildAt = "2023-07-08 15:09:08.542818";
static const int modifications = 2;
}

View File

@@ -126,10 +126,9 @@ class _ServerPageState extends State<ServerPage>
);
}),
itemBuilder: (_, index) => FadeIn(
key: ValueKey('$_tag${filtered[index]}'),
child: _buildEachServerCard(
pro.servers[filtered[index]],
)),
key: ValueKey('$_tag${filtered[index]}'),
child: _buildEachServerCard(pro.servers[filtered[index]]),
),
itemCount: filtered.length,
);
},

View File

@@ -475,9 +475,9 @@
baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 373;
CURRENT_PROJECT_VERSION = 376;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.373;
MARKETING_VERSION = 1.0.376;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
@@ -490,9 +490,9 @@
baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 373;
CURRENT_PROJECT_VERSION = 376;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.373;
MARKETING_VERSION = 1.0.376;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
@@ -505,9 +505,9 @@
baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 373;
CURRENT_PROJECT_VERSION = 376;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.373;
MARKETING_VERSION = 1.0.376;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;