From e05a8602d57684c66a2d0a113b2687158bb87a31 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 31 Jan 2023 11:43:45 +0100 Subject: [PATCH] feat(Widget): Reorganize and rename FollowersCountWidget code --- Mastodon.xcodeproj/project.pbxproj | 40 ++-- .../FollowersCountWidget.swift} | 26 +-- .../FollowersCountWidgetView.swift} | 4 +- .../WidgetExtension.intentdefinition | 213 +++++++++++++++++- WidgetExtension/WidgetExtensionBundle.swift | 2 +- 5 files changed, 252 insertions(+), 33 deletions(-) rename WidgetExtension/{FollowersWidgetExtension.swift => Variants/FollowersCount/FollowersCountWidget.swift} (86%) rename WidgetExtension/{WidgetViews/FollowCountWidgetView.swift => Variants/FollowersCount/FollowersCountWidgetView.swift} (98%) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index d1e0fc798..5e2370938 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -31,7 +31,7 @@ 2A33063929880835001D4C51 /* CurvedChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A33063329880834001D4C51 /* CurvedChart.swift */; }; 2A33063A29880835001D4C51 /* LightChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A33063429880834001D4C51 /* LightChart.swift */; }; 2A33063B29880835001D4C51 /* ChartType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A33063529880834001D4C51 /* ChartType.swift */; }; - 2A33AB662982C4AF008A7FB1 /* FollowCountWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A33AB652982C4AF008A7FB1 /* FollowCountWidgetView.swift */; }; + 2A33AB662982C4AF008A7FB1 /* FollowersCountWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A33AB652982C4AF008A7FB1 /* FollowersCountWidgetView.swift */; }; 2A3F6FE3292ECB5E002E6DA7 /* FollowedTagsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */; }; 2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */; }; 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; }; @@ -44,7 +44,7 @@ 2A728122297EA9D7004138C5 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A728121297EA9D7004138C5 /* WidgetKit.framework */; }; 2A728124297EA9D7004138C5 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A728123297EA9D7004138C5 /* SwiftUI.framework */; }; 2A728127297EA9D7004138C5 /* WidgetExtensionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A728126297EA9D7004138C5 /* WidgetExtensionBundle.swift */; }; - 2A72812B297EA9D7004138C5 /* FollowersWidgetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A72812A297EA9D7004138C5 /* FollowersWidgetExtension.swift */; }; + 2A72812B297EA9D7004138C5 /* FollowersCountWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A72812A297EA9D7004138C5 /* FollowersCountWidget.swift */; }; 2A72812E297EA9D8004138C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2A72812D297EA9D8004138C5 /* Assets.xcassets */; }; 2A728130297EA9D8004138C5 /* WidgetExtension.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 2A72812C297EA9D7004138C5 /* WidgetExtension.intentdefinition */; }; 2A728131297EA9D8004138C5 /* WidgetExtension.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 2A72812C297EA9D7004138C5 /* WidgetExtension.intentdefinition */; }; @@ -620,7 +620,7 @@ 2A33063429880834001D4C51 /* LightChart.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LightChart.swift; sourceTree = ""; }; 2A33063529880834001D4C51 /* ChartType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartType.swift; sourceTree = ""; }; 2A33625329759B4200481A90 /* OpenInActionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OpenInActionExtension.entitlements; sourceTree = ""; }; - 2A33AB652982C4AF008A7FB1 /* FollowCountWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowCountWidgetView.swift; sourceTree = ""; }; + 2A33AB652982C4AF008A7FB1 /* FollowersCountWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowersCountWidgetView.swift; sourceTree = ""; }; 2A3F6FE2292ECB5E002E6DA7 /* FollowedTagsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewModel.swift; sourceTree = ""; }; 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsTableViewCell.swift; sourceTree = ""; }; 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = ""; }; @@ -635,7 +635,7 @@ 2A728121297EA9D7004138C5 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 2A728123297EA9D7004138C5 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 2A728126297EA9D7004138C5 /* WidgetExtensionBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetExtensionBundle.swift; sourceTree = ""; }; - 2A72812A297EA9D7004138C5 /* FollowersWidgetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowersWidgetExtension.swift; sourceTree = ""; }; + 2A72812A297EA9D7004138C5 /* FollowersCountWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowersCountWidget.swift; sourceTree = ""; }; 2A72812C297EA9D7004138C5 /* WidgetExtension.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = WidgetExtension.intentdefinition; sourceTree = ""; }; 2A72812D297EA9D8004138C5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2A72812F297EA9D8004138C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1409,14 +1409,6 @@ path = Charts; sourceTree = ""; }; - 2A33AB642982C4A3008A7FB1 /* WidgetViews */ = { - isa = PBXGroup; - children = ( - 2A33AB652982C4AF008A7FB1 /* FollowCountWidgetView.swift */, - ); - path = WidgetViews; - sourceTree = ""; - }; 2A506CF2292CD83B00059C37 /* FollowedTags */ = { isa = PBXGroup; children = ( @@ -1444,11 +1436,10 @@ isa = PBXGroup; children = ( 2A33062E29880834001D4C51 /* LightChart */, - 2A33AB642982C4A3008A7FB1 /* WidgetViews */, + 2A86A14329892700007F1062 /* Variants */, 2AE202A9297FDDF500F66E55 /* WidgetExtension.entitlements */, 2A72813E297EC762004138C5 /* WidgetExtension.swift */, 2A728126297EA9D7004138C5 /* WidgetExtensionBundle.swift */, - 2A72812A297EA9D7004138C5 /* FollowersWidgetExtension.swift */, 2A33062C2987DBFA001D4C51 /* FollowersCountHistory.swift */, 2A72812C297EA9D7004138C5 /* WidgetExtension.intentdefinition */, 2A72812D297EA9D8004138C5 /* Assets.xcassets */, @@ -1457,6 +1448,23 @@ path = WidgetExtension; sourceTree = ""; }; + 2A86A14329892700007F1062 /* Variants */ = { + isa = PBXGroup; + children = ( + 2A86A14429892709007F1062 /* FollowersCount */, + ); + path = Variants; + sourceTree = ""; + }; + 2A86A14429892709007F1062 /* FollowersCount */ = { + isa = PBXGroup; + children = ( + 2A72812A297EA9D7004138C5 /* FollowersCountWidget.swift */, + 2A33AB652982C4AF008A7FB1 /* FollowersCountWidgetView.swift */, + ); + path = FollowersCount; + sourceTree = ""; + }; 2D152A8A25C295B8009AA50C /* Content */ = { isa = PBXGroup; children = ( @@ -3481,9 +3489,9 @@ 2A33063A29880835001D4C51 /* LightChart.swift in Sources */, 2A33063B29880835001D4C51 /* ChartType.swift in Sources */, 2A33063629880835001D4C51 /* Math.swift in Sources */, - 2A33AB662982C4AF008A7FB1 /* FollowCountWidgetView.swift in Sources */, + 2A33AB662982C4AF008A7FB1 /* FollowersCountWidgetView.swift in Sources */, 2A728127297EA9D7004138C5 /* WidgetExtensionBundle.swift in Sources */, - 2A72812B297EA9D7004138C5 /* FollowersWidgetExtension.swift in Sources */, + 2A72812B297EA9D7004138C5 /* FollowersCountWidget.swift in Sources */, 2A33063929880835001D4C51 /* CurvedChart.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/WidgetExtension/FollowersWidgetExtension.swift b/WidgetExtension/Variants/FollowersCount/FollowersCountWidget.swift similarity index 86% rename from WidgetExtension/FollowersWidgetExtension.swift rename to WidgetExtension/Variants/FollowersCount/FollowersCountWidget.swift index 4b00106a9..3cdff147a 100644 --- a/WidgetExtension/FollowersWidgetExtension.swift +++ b/WidgetExtension/Variants/FollowersCount/FollowersCountWidget.swift @@ -5,34 +5,34 @@ import SwiftUI import Intents import MastodonSDK -struct FollowersProvider: IntentTimelineProvider { +struct FollowersCountWidgetProvider: IntentTimelineProvider { private let followersHistory = FollowersCountHistory.shared - func placeholder(in context: Context) -> FollowersEntry { + func placeholder(in context: Context) -> FollowersCountEntry { .placeholder } - func getSnapshot(for configuration: FollowersCountIntent, in context: Context, completion: @escaping (FollowersEntry) -> ()) { + func getSnapshot(for configuration: FollowersCountIntent, in context: Context, completion: @escaping (FollowersCountEntry) -> ()) { guard !context.isPreview else { return completion(.placeholder) } loadCurrentEntry(for: configuration, in: context, completion: completion) } - func getTimeline(for configuration: FollowersCountIntent, in context: Context, completion: @escaping (Timeline) -> ()) { + func getTimeline(for configuration: FollowersCountIntent, in context: Context, completion: @escaping (Timeline) -> ()) { loadCurrentEntry(for: configuration, in: context) { entry in completion(Timeline(entries: [entry], policy: .after(.now))) } } } -struct FollowersEntry: TimelineEntry { +struct FollowersCountEntry: TimelineEntry { let date: Date let account: FollowersEntryAccountable? let configuration: FollowersCountIntent static var placeholder: Self { - FollowersEntry( + FollowersCountEntry( date: .now, account: FollowersEntryAccount( followersCount: 99_900, @@ -46,7 +46,7 @@ struct FollowersEntry: TimelineEntry { } static var unconfigured: Self { - FollowersEntry( + FollowersCountEntry( date: .now, account: nil, configuration: FollowersCountIntent() @@ -54,7 +54,7 @@ struct FollowersEntry: TimelineEntry { } } -struct FollowersWidgetExtension: Widget { +struct FollowersCountWidget: Widget { private var availableFamilies: [WidgetFamily] { if #available(iOS 16, *) { return [.systemSmall, .accessoryRectangular, .accessoryCircular] @@ -63,8 +63,8 @@ struct FollowersWidgetExtension: Widget { } var body: some WidgetConfiguration { - IntentConfiguration(kind: "Followers", intent: FollowersCountIntent.self, provider: FollowersProvider()) { entry in - FollowCountWidgetView(entry: entry) + IntentConfiguration(kind: "Followers", intent: FollowersCountIntent.self, provider: FollowersCountWidgetProvider()) { entry in + FollowersCountWidgetView(entry: entry) } .configurationDisplayName("Followers") .description("Show number of followers.") @@ -72,8 +72,8 @@ struct FollowersWidgetExtension: Widget { } } -private extension FollowersProvider { - func loadCurrentEntry(for configuration: FollowersCountIntent, in context: Context, completion: @escaping (FollowersEntry) -> Void) { +private extension FollowersCountWidgetProvider { + func loadCurrentEntry(for configuration: FollowersCountIntent, in context: Context, completion: @escaping (FollowersCountEntry) -> Void) { Task { guard let authBox = WidgetExtension.appContext @@ -102,7 +102,7 @@ private extension FollowersProvider { let imageData = try await URLSession.shared.data(from: resultingAccount.avatarImageURLWithFallback(domain: authBox.domain)).0 - let entry = FollowersEntry( + let entry = FollowersCountEntry( date: Date(), account: FollowersEntryAccount.from( mastodonAccount: resultingAccount, diff --git a/WidgetExtension/WidgetViews/FollowCountWidgetView.swift b/WidgetExtension/Variants/FollowersCount/FollowersCountWidgetView.swift similarity index 98% rename from WidgetExtension/WidgetViews/FollowCountWidgetView.swift rename to WidgetExtension/Variants/FollowersCount/FollowersCountWidgetView.swift index d4bc2a86a..41648805d 100644 --- a/WidgetExtension/WidgetViews/FollowCountWidgetView.swift +++ b/WidgetExtension/Variants/FollowersCount/FollowersCountWidgetView.swift @@ -4,12 +4,12 @@ import SwiftUI import WidgetKit import MastodonAsset -struct FollowCountWidgetView: View { +struct FollowersCountWidgetView: View { private let followersHistory = FollowersCountHistory.shared @Environment(\.widgetFamily) var family - var entry: FollowersProvider.Entry + var entry: FollowersCountWidgetProvider.Entry var body: some View { if let account = entry.account { diff --git a/WidgetExtension/WidgetExtension.intentdefinition b/WidgetExtension/WidgetExtension.intentdefinition index bf1619332..a010349a7 100644 --- a/WidgetExtension/WidgetExtension.intentdefinition +++ b/WidgetExtension/WidgetExtension.intentdefinition @@ -174,8 +174,219 @@ INIntentVerb View + + INIntentCategory + information + INIntentDescriptionID + B9KyhZ + INIntentEligibleForWidgets + + INIntentIneligibleForSuggestions + + INIntentLastParameterTag + 5 + INIntentName + MultiFollowCountSmall + INIntentParameters + + + INIntentParameterArraySizes + + + INIntentParameterArraySizeSize + 3 + INIntentParameterArraySizeSizeClass + Small + + + INIntentParameterArraySizeSize + 6 + INIntentParameterArraySizeSizeClass + Medium + + + INIntentParameterArraySizeSize + 6 + INIntentParameterArraySizeSizeClass + Large + + + INIntentParameterArraySizeSize + 6 + INIntentParameterArraySizeSizeClass + ExtraLarge + + + INIntentParameterArraySizeSize + 1 + INIntentParameterArraySizeSizeClass + AccessoryInline + + + INIntentParameterArraySizeSize + 1 + INIntentParameterArraySizeSizeClass + AccessoryCorner + + + INIntentParameterArraySizeSize + 1 + INIntentParameterArraySizeSizeClass + AccessoryCircular + + + INIntentParameterArraySizeSize + 1 + INIntentParameterArraySizeSizeClass + AccessoryRectangular + + + INIntentParameterConfigurable + + INIntentParameterDisplayName + Accounts + INIntentParameterDisplayNameID + fovmPX + INIntentParameterDisplayPriority + 1 + INIntentParameterFixedSizeArray + 1 + INIntentParameterName + accounts + INIntentParameterObjectType + MultiFollowAccountsSmall + INIntentParameterObjectTypeNamespace + 88xZPY + INIntentParameterPromptDialogs + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogType + Configuration + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogType + Primary + + + INIntentParameterSupportsMultipleValues + + INIntentParameterTag + 5 + INIntentParameterType + Object + + + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + Multi Follow Count Small + INIntentTitleID + e0W2wo + INIntentType + Custom + INIntentVerb + View + INTypes - + + + INTypeDisplayName + Account + INTypeDisplayNameID + LUrJ3D + INTypeLastPropertyTag + 101 + INTypeName + MultiFollowAccountsSmall + INTypeProperties + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 1 + INTypePropertyName + identifier + INTypePropertyTag + 1 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 2 + INTypePropertyName + displayString + INTypePropertyTag + 2 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 3 + INTypePropertyName + pronunciationHint + INTypePropertyTag + 3 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 4 + INTypePropertyName + alternativeSpeakableMatches + INTypePropertySupportsMultipleValues + + INTypePropertyTag + 4 + INTypePropertyType + SpeakableString + + + INTypePropertyDisplayName + username + INTypePropertyDisplayNameID + TQNJZz + INTypePropertyDisplayPriority + 5 + INTypePropertyName + property + INTypePropertySupportsMultipleValues + + INTypePropertyTag + 101 + INTypePropertyType + String + + + + diff --git a/WidgetExtension/WidgetExtensionBundle.swift b/WidgetExtension/WidgetExtensionBundle.swift index d94557d88..5c5ea71ba 100644 --- a/WidgetExtension/WidgetExtensionBundle.swift +++ b/WidgetExtension/WidgetExtensionBundle.swift @@ -6,6 +6,6 @@ import SwiftUI @main struct WidgetExtensionBundle: WidgetBundle { var body: some Widget { - FollowersWidgetExtension() + FollowersCountWidget() } }