From 026a4dfb27a52eda534ca219bced72d09e174057 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 14 Dec 2024 18:18:13 +0800 Subject: [PATCH] :sparkles: Initial iOS widget target --- ios/Podfile | 7 + ios/Podfile.lock | 6 + ios/Runner.xcodeproj/project.pbxproj | 295 +++++++++++++++++- ios/Runner/AppDelegate.swift | 1 + ios/Runner/Data/User.swift | 20 ++ ios/Runner/Runner.entitlements | 4 + .../SolarNotifyService.entitlements | 10 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 35 +++ ios/SolarWidget/Assets.xcassets/Contents.json | 6 + .../WidgetBackground.colorset/Contents.json | 11 + ios/SolarWidget/CheckInWidget.swift | 98 ++++++ ios/SolarWidget/FeaturedPostWidget.swift | 7 + ios/SolarWidget/Info.plist | 11 + ios/SolarWidget/SolarWidgetBundle.swift | 16 + ios/SolarWidgetExtension.entitlements | 10 + lib/main.dart | 8 + lib/providers/userinfo.dart | 13 +- lib/providers/widget.dart | 32 ++ lib/screens/home.dart | 7 + pubspec.lock | 8 + pubspec.yaml | 1 + 22 files changed, 608 insertions(+), 9 deletions(-) create mode 100644 ios/Runner/Data/User.swift create mode 100644 ios/SolarNotifyService/SolarNotifyService.entitlements create mode 100644 ios/SolarWidget/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 ios/SolarWidget/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 ios/SolarWidget/Assets.xcassets/Contents.json create mode 100644 ios/SolarWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json create mode 100644 ios/SolarWidget/CheckInWidget.swift create mode 100644 ios/SolarWidget/FeaturedPostWidget.swift create mode 100644 ios/SolarWidget/Info.plist create mode 100644 ios/SolarWidget/SolarWidgetBundle.swift create mode 100644 ios/SolarWidgetExtension.entitlements create mode 100644 lib/providers/widget.dart diff --git a/ios/Podfile b/ios/Podfile index ba9304f..e25c293 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -37,6 +37,13 @@ target 'Runner' do end end +target 'SolarWidget' do + use_frameworks! + use_modular_headers! + + pod 'home_widget', :path => '.symlinks/plugins/home_widget/ios' +end + post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 841e29b..2a41fb5 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -163,6 +163,8 @@ PODS: - GoogleUtilities/UserDefaults (8.0.2): - GoogleUtilities/Logger - GoogleUtilities/Privacy + - home_widget (0.0.1): + - Flutter - image_picker_ios (0.0.1): - Flutter - livekit_client (2.3.2): @@ -227,6 +229,7 @@ DEPENDENCIES: - flutter_udid (from `.symlinks/plugins/flutter_udid/ios`) - flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`) - gal (from `.symlinks/plugins/gal/darwin`) + - home_widget (from `.symlinks/plugins/home_widget/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - livekit_client (from `.symlinks/plugins/livekit_client/ios`) - media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`) @@ -291,6 +294,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_webrtc/ios" gal: :path: ".symlinks/plugins/gal/darwin" + home_widget: + :path: ".symlinks/plugins/home_widget/ios" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" livekit_client: @@ -349,6 +354,7 @@ SPEC CHECKSUMS: GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d + home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57 image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 livekit_client: 6108dad8b77db3142bafd4c630f471d0a54335cd media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index d5776ee..37b2c07 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 77; objects = { /* Begin PBXBuildFile section */ @@ -11,6 +11,9 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 738C1EAC2D0D76A400A215F3 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 731B7B6B2D0D6CE000CEB9B7 /* WidgetKit.framework */; }; + 738C1EAD2D0D76A400A215F3 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 731B7B6D2D0D6CE000CEB9B7 /* SwiftUI.framework */; }; + 738C1EB82D0D76A500A215F3 /* SolarWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 738C1EAB2D0D76A400A215F3 /* SolarWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 73DA8A012D05C7620024A03E /* SolarNotifyService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 73DA89FA2D05C7620024A03E /* SolarNotifyService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 8CD0929C27BC410DD5056EAB /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = A2C24C5238FAC44EA2CCF738 /* GoogleService-Info.plist */; }; @@ -28,6 +31,13 @@ remoteGlobalIDString = 97C146ED1CF9000F007C117D; remoteInfo = Runner; }; + 738C1EB62D0D76A500A215F3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 738C1EAA2D0D76A400A215F3; + remoteInfo = SolarWidgetExtension; + }; 73DA89FF2D05C7620024A03E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 97C146E61CF9000F007C117D /* Project object */; @@ -44,6 +54,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + 738C1EB82D0D76A500A215F3 /* SolarWidgetExtension.appex in Embed Foundation Extensions */, 73DA8A012D05C7620024A03E /* SolarNotifyService.appex in Embed Foundation Extensions */, ); name = "Embed Foundation Extensions"; @@ -74,6 +85,10 @@ 64FBE78F9C282712818D6D95 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 72E9279EFA6DAC00BBAC493C /* 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 = ""; }; 73111C212CEE3D5E004CF4B3 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + 731B7B6B2D0D6CE000CEB9B7 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + 731B7B6D2D0D6CE000CEB9B7 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + 738C1EAB2D0D76A400A215F3 /* SolarWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SolarWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 738C1F132D0D7DDC00A215F3 /* SolarWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SolarWidgetExtension.entitlements; sourceTree = ""; }; 73DA89FA2D05C7620024A03E /* SolarNotifyService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SolarNotifyService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -91,7 +106,28 @@ /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ - 73DA8A062D05C7620024A03E /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + 738C1EB92D0D76A500A215F3 /* Exceptions for "SolarWidget" folder in "SolarWidgetExtension" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 738C1EAA2D0D76A400A215F3 /* SolarWidgetExtension */; + }; + 738C1F502D0D91D000A215F3 /* Exceptions for "Data" folder in "Runner" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + User.swift, + ); + target = 97C146ED1CF9000F007C117D /* Runner */; + }; + 738C1F512D0D91D000A215F3 /* Exceptions for "Data" folder in "SolarWidgetExtension" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + User.swift, + ); + target = 738C1EAA2D0D76A400A215F3 /* SolarWidgetExtension */; + }; + 73DA8A062D05C7620024A03E /* Exceptions for "SolarNotifyService" folder in "SolarNotifyService" target */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( Info.plist, @@ -101,10 +137,43 @@ /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ - 73DA89FB2D05C7620024A03E /* SolarNotifyService */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (73DA8A062D05C7620024A03E /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = SolarNotifyService; sourceTree = ""; }; + 738C1EAE2D0D76A400A215F3 /* SolarWidget */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 738C1EB92D0D76A500A215F3 /* Exceptions for "SolarWidget" folder in "SolarWidgetExtension" target */, + ); + path = SolarWidget; + sourceTree = ""; + }; + 738C1F4F2D0D91CC00A215F3 /* Data */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 738C1F502D0D91D000A215F3 /* Exceptions for "Data" folder in "Runner" target */, + 738C1F512D0D91D000A215F3 /* Exceptions for "Data" folder in "SolarWidgetExtension" target */, + ); + path = Data; + sourceTree = ""; + }; + 73DA89FB2D05C7620024A03E /* SolarNotifyService */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 73DA8A062D05C7620024A03E /* Exceptions for "SolarNotifyService" folder in "SolarNotifyService" target */, + ); + path = SolarNotifyService; + sourceTree = ""; + }; /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ + 738C1EA82D0D76A400A215F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 738C1EAD2D0D76A400A215F3 /* SwiftUI.framework in Frameworks */, + 738C1EAC2D0D76A400A215F3 /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 73DA89F72D05C7620024A03E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -136,6 +205,8 @@ children = ( EDF483E994343CDFBF9BA347 /* Pods_Runner.framework */, 26CC8DE2338798EAB472B62D /* Pods_RunnerTests.framework */, + 731B7B6B2D0D6CE000CEB9B7 /* WidgetKit.framework */, + 731B7B6D2D0D6CE000CEB9B7 /* SwiftUI.framework */, ); name = Frameworks; sourceTree = ""; @@ -162,9 +233,11 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( + 738C1F132D0D7DDC00A215F3 /* SolarWidgetExtension.entitlements */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 73DA89FB2D05C7620024A03E /* SolarNotifyService */, + 738C1EAE2D0D76A400A215F3 /* SolarWidget */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, F5165E3BD1F2519F85CD4BE2 /* Pods */, @@ -179,6 +252,7 @@ 97C146EE1CF9000F007C117D /* Runner.app */, 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 73DA89FA2D05C7620024A03E /* SolarNotifyService.appex */, + 738C1EAB2D0D76A400A215F3 /* SolarWidgetExtension.appex */, ); name = Products; sourceTree = ""; @@ -186,6 +260,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 738C1F4F2D0D91CC00A215F3 /* Data */, 73111C212CEE3D5E004CF4B3 /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, @@ -234,6 +309,29 @@ productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 738C1EAA2D0D76A400A215F3 /* SolarWidgetExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 738C1EBA2D0D76A500A215F3 /* Build configuration list for PBXNativeTarget "SolarWidgetExtension" */; + buildPhases = ( + 738C1EA72D0D76A400A215F3 /* Sources */, + 738C1EA82D0D76A400A215F3 /* Frameworks */, + 738C1EA92D0D76A400A215F3 /* Resources */, + 738C1EBE2D0D76C500A215F3 /* Copy Bundle Version */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 738C1EAE2D0D76A400A215F3 /* SolarWidget */, + ); + name = SolarWidgetExtension; + packageProductDependencies = ( + ); + productName = SolarWidgetExtension; + productReference = 738C1EAB2D0D76A400A215F3 /* SolarWidgetExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; 73DA89F92D05C7620024A03E /* SolarNotifyService */ = { isa = PBXNativeTarget; buildConfigurationList = 73DA8A072D05C7620024A03E /* Build configuration list for PBXNativeTarget "SolarNotifyService" */; @@ -276,6 +374,10 @@ ); dependencies = ( 73DA8A002D05C7620024A03E /* PBXTargetDependency */, + 738C1EB72D0D76A500A215F3 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 738C1F4F2D0D91CC00A215F3 /* Data */, ); name = Runner; productName = Runner; @@ -289,7 +391,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 1610; + LastSwiftUpdateCheck = 1620; LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { @@ -297,6 +399,9 @@ CreatedOnToolsVersion = 14.0; TestTargetID = 97C146ED1CF9000F007C117D; }; + 738C1EAA2D0D76A400A215F3 = { + CreatedOnToolsVersion = 16.2; + }; 73DA89F92D05C7620024A03E = { CreatedOnToolsVersion = 16.1; }; @@ -307,7 +412,6 @@ }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -315,6 +419,7 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + preferredProjectObjectVersion = 77; productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -322,6 +427,7 @@ 97C146ED1CF9000F007C117D /* Runner */, 331C8080294A63A400263BE5 /* RunnerTests */, 73DA89F92D05C7620024A03E /* SolarNotifyService */, + 738C1EAA2D0D76A400A215F3 /* SolarWidgetExtension */, ); }; /* End PBXProject section */ @@ -334,6 +440,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 738C1EA92D0D76A400A215F3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 73DA89F82D05C7620024A03E /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -407,6 +520,24 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 738C1EBE2D0D76C500A215F3 /* Copy Bundle Version */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Copy Bundle Version"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "generatedPath=\"$SRCROOT/Flutter/Generated.xcconfig\"\n\n# Read and trim versionNumber and buildNumber\nversionNumber=$(grep FLUTTER_BUILD_NAME \"$generatedPath\" | cut -d '=' -f2 | xargs)\nbuildNumber=$(grep FLUTTER_BUILD_NUMBER \"$generatedPath\" | cut -d '=' -f2 | xargs)\n\ninfoPlistPath=\"$SRCROOT/HomeExampleWidget/Info.plist\"\n\n# Check and add CFBundleVersion if it does not exist\n/usr/libexec/PlistBuddy -c \"Print :CFBundleVersion\" \"$infoPlistPath\" 2>/dev/null\nif [ $? != 0 ]; then\n /usr/libexec/PlistBuddy -c \"Add :CFBundleVersion string $buildNumber\" \"$infoPlistPath\"\nelse\n /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $buildNumber\" \"$infoPlistPath\"\nfi\n\n# Check and add CFBundleShortVersionString if it does not exist\n/usr/libexec/PlistBuddy -c \"Print :CFBundleShortVersionString\" \"$infoPlistPath\" 2>/dev/null\nif [ $? != 0 ]; then\n /usr/libexec/PlistBuddy -c \"Add :CFBundleShortVersionString string $versionNumber\" \"$infoPlistPath\"\nelse\n /usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString $versionNumber\" \"$infoPlistPath\"\nfi\n\n"; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -494,6 +625,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 738C1EA72D0D76A400A215F3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 73DA89F62D05C7620024A03E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -518,6 +656,11 @@ target = 97C146ED1CF9000F007C117D /* Runner */; targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; }; + 738C1EB72D0D76A500A215F3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 738C1EAA2D0D76A400A215F3 /* SolarWidgetExtension */; + targetProxy = 738C1EB62D0D76A500A215F3 /* PBXContainerItemProxy */; + }; 73DA8A002D05C7620024A03E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 73DA89F92D05C7620024A03E /* SolarNotifyService */; @@ -610,6 +753,7 @@ INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Solian; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -629,6 +773,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W7HPZ53V6B; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.RunnerTests; @@ -647,6 +792,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W7HPZ53V6B; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.RunnerTests; @@ -663,6 +809,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W7HPZ53V6B; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.RunnerTests; @@ -672,6 +819,129 @@ }; name = Profile; }; + 738C1EBB2D0D76A500A215F3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + 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_ENTITLEMENTS = SolarWidgetExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W7HPZ53V6B; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = SolarWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = SolarWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolarWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 738C1EBC2D0D76A500A215F3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + 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_ENTITLEMENTS = SolarWidgetExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W7HPZ53V6B; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = SolarWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = SolarWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolarWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 738C1EBD2D0D76A500A215F3 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + 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_ENTITLEMENTS = SolarWidgetExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W7HPZ53V6B; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = SolarWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = SolarWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolarWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Profile; + }; 73DA8A032D05C7620024A03E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -682,6 +952,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = SolarNotifyService/SolarNotifyService.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = W7HPZ53V6B; @@ -722,6 +993,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = SolarNotifyService/SolarNotifyService.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = W7HPZ53V6B; @@ -759,6 +1031,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = SolarNotifyService/SolarNotifyService.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = W7HPZ53V6B; @@ -910,6 +1183,7 @@ INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Solian; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -936,6 +1210,7 @@ INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Solian; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -961,6 +1236,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 738C1EBA2D0D76A500A215F3 /* Build configuration list for PBXNativeTarget "SolarWidgetExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 738C1EBB2D0D76A500A215F3 /* Debug */, + 738C1EBC2D0D76A500A215F3 /* Release */, + 738C1EBD2D0D76A500A215F3 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 73DA8A072D05C7620024A03E /* Build configuration list for PBXNativeTarget "SolarNotifyService" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 6266644..1493a27 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -8,6 +8,7 @@ import UIKit didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } diff --git a/ios/Runner/Data/User.swift b/ios/Runner/Data/User.swift new file mode 100644 index 0000000..40d023c --- /dev/null +++ b/ios/Runner/Data/User.swift @@ -0,0 +1,20 @@ +// +// SolarData.swift +// Runner +// +// Created by LittleSheep on 2024/12/14. +// + +import Foundation + +struct SolarUser: Codable { + let id: Int + let name: String + let nick: String +} + +struct SolarCheckInRecord: Codable { + let id: Int + let resultTier: Int + let createdAt: Date +} diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 29326e3..f7add75 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -6,5 +6,9 @@ development com.apple.developer.usernotifications.communication + com.apple.security.application-groups + + group.solsynth.solian + diff --git a/ios/SolarNotifyService/SolarNotifyService.entitlements b/ios/SolarNotifyService/SolarNotifyService.entitlements new file mode 100644 index 0000000..7121c32 --- /dev/null +++ b/ios/SolarNotifyService/SolarNotifyService.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.solsynth.solian + + + diff --git a/ios/SolarWidget/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/SolarWidget/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/ios/SolarWidget/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/SolarWidget/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/SolarWidget/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/ios/SolarWidget/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/SolarWidget/Assets.xcassets/Contents.json b/ios/SolarWidget/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ios/SolarWidget/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/SolarWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json b/ios/SolarWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/ios/SolarWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/SolarWidget/CheckInWidget.swift b/ios/SolarWidget/CheckInWidget.swift new file mode 100644 index 0000000..96f28fb --- /dev/null +++ b/ios/SolarWidget/CheckInWidget.swift @@ -0,0 +1,98 @@ +// +// SolarWidget.swift +// SolarWidget +// +// Created by LittleSheep on 2024/12/14. +// + +import WidgetKit +import SwiftUI + +struct Provider: TimelineProvider { + func placeholder(in context: Context) -> SimpleEntry { + SimpleEntry(date: Date(), user: nil, checkIn: nil) + } + + func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { + let prefs = UserDefaults(suiteName: "group.solsynth.solian") + + let jsonDecoder = JSONDecoder() + jsonDecoder.dateDecodingStrategy = .iso8601 + jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase + + let userRaw = prefs?.string(forKey: "user") + var user: SolarUser? + if let userRaw = userRaw { + user = try! jsonDecoder.decode(SolarUser.self, from: userRaw.data(using: .utf8)!) + } + + let checkInRaw = prefs?.string(forKey: "today_check_in") + var checkIn: SolarCheckInRecord? + if let checkInRaw = checkInRaw { + checkIn = try! jsonDecoder.decode(SolarCheckInRecord.self, from: checkInRaw.data(using: .utf8)!) + } + + let entry = SimpleEntry( + date: Date(), + user: user, + checkIn: checkIn + ) + completion(entry) + } + + func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { + getSnapshot(in: context) { (entry) in + let timeline = Timeline(entries: [entry], policy: .atEnd) + completion(timeline) + } + } +} + +struct SimpleEntry: TimelineEntry { + let date: Date + let user: SolarUser? + let checkIn: SolarCheckInRecord? +} + +struct SolarWidgetEntryView : View { + var entry: Provider.Entry + + var body: some View { + VStack(alignment: .leading) { + if let user = entry.user { + Text("User") + Text("\(user.name)") + } + } + } +} + +struct CheckInWidget: Widget { + let kind: String = "SolarWidget" + + var body: some WidgetConfiguration { + StaticConfiguration(kind: kind, provider: Provider()) { entry in + if #available(iOS 17.0, *) { + SolarWidgetEntryView(entry: entry) + .containerBackground(.fill.tertiary, for: .widget) + } else { + SolarWidgetEntryView(entry: entry) + .padding() + .background() + } + } + .configurationDisplayName("Solar Overview") + .description("Get Instant Insights on your home screen") + } +} + +#Preview(as: .systemSmall) { + CheckInWidget() +} timeline: { + SimpleEntry(date: .now, user: nil, checkIn: nil) + SimpleEntry( + date: .now, + user: SolarUser(id: 1, name: "demo", nick: "Deemo"), + checkIn: SolarCheckInRecord(id: 1, resultTier: 1, createdAt: Date.now) + ) +} diff --git a/ios/SolarWidget/FeaturedPostWidget.swift b/ios/SolarWidget/FeaturedPostWidget.swift new file mode 100644 index 0000000..7dd3973 --- /dev/null +++ b/ios/SolarWidget/FeaturedPostWidget.swift @@ -0,0 +1,7 @@ +// +// FeaturedPostWidget.swift +// Runner +// +// Created by LittleSheep on 2024/12/14. +// + diff --git a/ios/SolarWidget/Info.plist b/ios/SolarWidget/Info.plist new file mode 100644 index 0000000..0f118fb --- /dev/null +++ b/ios/SolarWidget/Info.plist @@ -0,0 +1,11 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/ios/SolarWidget/SolarWidgetBundle.swift b/ios/SolarWidget/SolarWidgetBundle.swift new file mode 100644 index 0000000..6ef649d --- /dev/null +++ b/ios/SolarWidget/SolarWidgetBundle.swift @@ -0,0 +1,16 @@ +// +// SolarWidgetBundle.swift +// SolarWidget +// +// Created by LittleSheep on 2024/12/14. +// + +import WidgetKit +import SwiftUI + +@main +struct SolarWidgetBundle: WidgetBundle { + var body: some Widget { + CheckInWidget() + } +} diff --git a/ios/SolarWidgetExtension.entitlements b/ios/SolarWidgetExtension.entitlements new file mode 100644 index 0000000..7121c32 --- /dev/null +++ b/ios/SolarWidgetExtension.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.solsynth.solian + + + diff --git a/lib/main.dart b/lib/main.dart index dfee45c..7a4f99a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,6 +10,7 @@ import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import 'package:home_widget/home_widget.dart'; import 'package:provider/provider.dart'; import 'package:relative_time/relative_time.dart'; import 'package:responsive_framework/responsive_framework.dart'; @@ -28,6 +29,7 @@ import 'package:surface/providers/theme.dart'; import 'package:surface/providers/user_directory.dart'; import 'package:surface/providers/userinfo.dart'; import 'package:surface/providers/websocket.dart'; +import 'package:surface/providers/widget.dart'; import 'package:surface/router.dart'; import 'package:surface/types/chat.dart'; import 'package:surface/types/realm.dart'; @@ -87,6 +89,9 @@ class SolianApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => ThemeProvider()), ChangeNotifierProvider(create: (ctx) => NavigationProvider()), + // System extensions layer + Provider(create: (ctx) => HomeWidgetProvider(ctx)), + // Data layer Provider(create: (_) => SnNetworkProvider()), Provider(create: (ctx) => UserDirectoryProvider(ctx)), @@ -159,6 +164,9 @@ class _AppSplashScreenState extends State<_AppSplashScreen> { Future _initialize() async { try { + final home = context.read(); + await home.initialize(); + if (!mounted) return; final sn = context.read(); await sn.initializeUserAgent(); if (!mounted) return; diff --git a/lib/providers/userinfo.dart b/lib/providers/userinfo.dart index dbf8d69..8785435 100644 --- a/lib/providers/userinfo.dart +++ b/lib/providers/userinfo.dart @@ -1,9 +1,11 @@ import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:home_widget/home_widget.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:surface/providers/sn_network.dart'; +import 'package:surface/providers/widget.dart'; import 'package:surface/types/account.dart'; class UserProvider extends ChangeNotifier { @@ -11,16 +13,18 @@ class UserProvider extends ChangeNotifier { SnAccount? user; late final SnNetworkProvider _sn; + late final HomeWidgetProvider _home; + + UserProvider(BuildContext context) { + _sn = context.read(); + _home = context.read(); + } Future get atk async { final prefs = await SharedPreferences.getInstance(); return prefs.getString(kAtkStoreKey); } - UserProvider(BuildContext context) { - _sn = context.read(); - } - Future initialize() async { final prefs = await SharedPreferences.getInstance(); final value = prefs.getString(kAtkStoreKey); @@ -29,6 +33,7 @@ class UserProvider extends ChangeNotifier { refreshUser().then((value) { if (value != null) { log('Logged in as @${value.name}'); + _home.saveWidgetData('user', value.toJson()); } }); } diff --git a/lib/providers/widget.dart b/lib/providers/widget.dart new file mode 100644 index 0000000..d916325 --- /dev/null +++ b/lib/providers/widget.dart @@ -0,0 +1,32 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:home_widget/home_widget.dart'; + +class HomeWidgetProvider { + HomeWidgetProvider(BuildContext context); + + Future initialize() async { + if (kIsWeb || !(Platform.isAndroid || Platform.isIOS)) return; + if (!kIsWeb && Platform.isIOS) { + await HomeWidget.setAppGroupId("group.solsynth.solian"); + } + } + + Future saveWidgetData(String id, dynamic data) async { + if (kIsWeb || !(Platform.isAndroid || Platform.isIOS)) return; + await HomeWidget.saveWidgetData(id, jsonEncode(data)); + } + + Future updateWidget() async { + if (kIsWeb || !(Platform.isAndroid || Platform.isIOS)) return; + await HomeWidget.updateWidget( + name: "SolarWidget", + iOSName: "SolarWidget", + androidName: "com.solsynth.solian.SolarWidget", + qualifiedAndroidName: "group.solsynth.solian.SolarWidget", + ); + } +} diff --git a/lib/screens/home.dart b/lib/screens/home.dart index a107d86..800cabb 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -6,6 +6,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:home_widget/home_widget.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; @@ -19,6 +20,8 @@ import 'package:surface/widgets/app_bar_leading.dart'; import 'package:surface/widgets/dialog.dart'; import 'package:surface/widgets/post/post_item.dart'; +import '../providers/widget.dart'; + class HomeScreenDashEntry { final String name; final Widget child; @@ -140,8 +143,10 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> { setState(() => _isBusy = true); try { final sn = context.read(); + final home = context.read(); final resp = await sn.client.get('/cgi/id/check-in/today'); _todayRecord = SnCheckInRecord.fromJson(resp.data); + home.saveWidgetData('today_check_in', _todayRecord!.toJson()); } finally { setState(() => _isBusy = false); } @@ -151,8 +156,10 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> { setState(() => _isBusy = true); try { final sn = context.read(); + final home = context.read(); final resp = await sn.client.post('/cgi/id/check-in'); _todayRecord = SnCheckInRecord.fromJson(resp.data); + home.saveWidgetData('today_check_in', _todayRecord!.toJson()); } catch (err) { if (!mounted) return; context.showErrorDialog(err); diff --git a/pubspec.lock b/pubspec.lock index 94a1b2c..818cbbb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -842,6 +842,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + home_widget: + dependency: "direct main" + description: + name: home_widget + sha256: b313e3304c0429669fddf1286e1fbf61a64b873f38ba30b3eb890ef0d7560b12 + url: "https://pub.dev" + source: hosted + version: "0.7.0" html: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e66c554..9d0e9ec 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -104,6 +104,7 @@ dependencies: device_info_plus: ^11.2.0 marquee: ^2.3.0 flutter_svg: ^2.0.16 + home_widget: ^0.7.0 dev_dependencies: flutter_test: