feat(Widget): Implement LightChartView for Small FollowerCount

This commit is contained in:
Marcus Kida 2023-01-30 11:21:04 +01:00
parent aeaa3ea3ab
commit 1558579a86
No known key found for this signature in database
GPG Key ID: 19FF64E08013CA40
5 changed files with 149 additions and 25 deletions

View File

@ -25,6 +25,7 @@
2A1FE47C2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1FE47B2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift */; };
2A1FE47E2938C11200784BF1 /* Collection+IsNotEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1FE47D2938C11200784BF1 /* Collection+IsNotEmpty.swift */; };
2A33AB662982C4AF008A7FB1 /* FollowCountWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A33AB652982C4AF008A7FB1 /* FollowCountWidgetView.swift */; };
2A33AB6D2987C2B3008A7FB1 /* LightChart in Frameworks */ = {isa = PBXBuildFile; productRef = 2A33AB6C2987C2B3008A7FB1 /* LightChart */; };
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 */; };
@ -1196,6 +1197,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2A33AB6D2987C2B3008A7FB1 /* LightChart in Frameworks */,
2A72813B297EC6F7004138C5 /* MastodonSDKDynamic in Frameworks */,
2A728124297EA9D7004138C5 /* SwiftUI.framework in Frameworks */,
2A728122297EA9D7004138C5 /* WidgetKit.framework in Frameworks */,
@ -2958,6 +2960,7 @@
name = WidgetExtension;
packageProductDependencies = (
2A72813A297EC6F7004138C5 /* MastodonSDKDynamic */,
2A33AB6C2987C2B3008A7FB1 /* LightChart */,
);
productName = WidgetExtensionExtension;
productReference = 2A728120297EA9D7004138C5 /* WidgetExtension.appex */;
@ -3171,6 +3174,7 @@
);
mainGroup = DB427DC925BAA00100D1B89D;
packageReferences = (
2A33AB6B2987C2B3008A7FB1 /* XCRemoteSwiftPackageReference "LightChart" */,
);
productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
projectDirPath = "";
@ -5242,7 +5246,23 @@
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
2A33AB6B2987C2B3008A7FB1 /* XCRemoteSwiftPackageReference "LightChart" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/pichukov/LightChart.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
2A33AB6C2987C2B3008A7FB1 /* LightChart */ = {
isa = XCSwiftPackageProductDependency;
package = 2A33AB6B2987C2B3008A7FB1 /* XCRemoteSwiftPackageReference "LightChart" */;
productName = LightChart;
};
2A72813A297EC6F7004138C5 /* MastodonSDKDynamic */ = {
isa = XCSwiftPackageProductDependency;
productName = MastodonSDKDynamic;

View File

@ -73,6 +73,15 @@
"version": "4.2.2"
}
},
{
"package": "LightChart",
"repositoryURL": "https://github.com/pichukov/LightChart.git",
"state": {
"branch": null,
"revision": "206fe7ab50620891c89531e2598e36e965678a1a",
"version": "1.0.3"
}
},
{
"package": "MetaTextKit",
"repositoryURL": "https://github.com/TwidereProject/MetaTextKit.git",

View File

@ -7,6 +7,10 @@ import MastodonSDK
import MastodonLocalization
class FollowersCountIntentHandler: INExtension, FollowersCountIntentHandling {
func resolveShowChart(for intent: FollowersCountIntent) async -> INBooleanResolutionResult {
return .success(with: intent.showChart?.boolValue ?? false)
}
func resolveAccount(for intent: FollowersCountIntent) async -> INStringResolutionResult {
.confirmationRequired(with: intent.account)
}

View File

@ -9,7 +9,7 @@
<key>INIntentDefinitionNamespace</key>
<string>88xZPY</string>
<key>INIntentDefinitionSystemVersion</key>
<string>22C65</string>
<string>22D49</string>
<key>INIntentDefinitionToolsBuildVersion</key>
<string>14C18</string>
<key>INIntentDefinitionToolsVersion</key>
@ -28,7 +28,7 @@
<key>INIntentIneligibleForSuggestions</key>
<true/>
<key>INIntentLastParameterTag</key>
<integer>5</integer>
<integer>7</integer>
<key>INIntentName</key>
<string>FollowersCount</string>
<key>INIntentParameters</key>
@ -69,26 +69,6 @@
<key>INIntentParameterPromptDialogType</key>
<string>Primary</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogFormatString</key>
<string>There are ${count} options matching ${account}.</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>ceymMR</string>
<key>INIntentParameterPromptDialogType</key>
<string>DisambiguationIntroduction</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogFormatString</key>
<string>Just to confirm, you wanted ${account}?</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>z8tfVG</string>
<key>INIntentParameterPromptDialogType</key>
<string>Confirmation</string>
</dict>
</array>
<key>INIntentParameterSupportsDynamicEnumeration</key>
<true/>
@ -99,6 +79,54 @@
<key>INIntentParameterType</key>
<string>String</string>
</dict>
<dict>
<key>INIntentParameterConfigurable</key>
<true/>
<key>INIntentParameterDisplayName</key>
<string>Show chart</string>
<key>INIntentParameterDisplayNameID</key>
<string>xVtyec</string>
<key>INIntentParameterDisplayPriority</key>
<integer>2</integer>
<key>INIntentParameterMetadata</key>
<dict>
<key>INIntentParameterMetadataFalseDisplayName</key>
<string>No</string>
<key>INIntentParameterMetadataFalseDisplayNameID</key>
<string>jg9D5P</string>
<key>INIntentParameterMetadataTrueDisplayName</key>
<string>Yes</string>
<key>INIntentParameterMetadataTrueDisplayNameID</key>
<string>82L4Nj</string>
</dict>
<key>INIntentParameterName</key>
<string>showChart</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>Should the Widget show a chart?</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>zeJo4f</string>
<key>INIntentParameterPromptDialogType</key>
<string>Primary</string>
</dict>
</array>
<key>INIntentParameterSupportsResolution</key>
<true/>
<key>INIntentParameterTag</key>
<integer>7</integer>
<key>INIntentParameterType</key>
<string>Boolean</string>
</dict>
</array>
<key>INIntentResponse</key>
<dict>

View File

@ -2,6 +2,8 @@
import SwiftUI
import WidgetKit
import LightChart
import MastodonAsset
struct FollowCountWidgetView: View {
@Environment(\.widgetFamily) var family
@ -12,7 +14,11 @@ struct FollowCountWidgetView: View {
if let account = entry.account {
switch family {
case .systemSmall:
viewForSmallWidget(account)
if let showChart = entry.configuration.showChart?.boolValue, showChart {
viewForSmallWidgetYesChart(account)
} else {
viewForSmallWidgetNoChart(account)
}
case .accessoryRectangular:
viewForAccessoryRectangular(account)
case .accessoryCircular:
@ -28,7 +34,7 @@ struct FollowCountWidgetView: View {
}
}
private func viewForSmallWidget(_ account: FollowersEntryAccountable) -> some View {
private func viewForSmallWidgetNoChart(_ account: FollowersEntryAccountable) -> some View {
HStack {
VStack(alignment: .leading, spacing: 0) {
if let avatarImage = account.avatarImage {
@ -56,11 +62,68 @@ struct FollowCountWidgetView: View {
.truncationMode(.tail)
}
.padding(.leading, 20)
.padding([.top, .bottom], 16)
.padding(.vertical, 16)
Spacer()
}
}
private func viewForSmallWidgetYesChart(_ account: FollowersEntryAccountable) -> some View {
VStack(alignment: .leading, spacing: 0) {
HStack {
if let avatarImage = account.avatarImage {
Image(uiImage: avatarImage)
.resizable()
.frame(width: 23, height: 23)
.cornerRadius(5)
}
VStack(alignment: .leading) {
Text(account.displayNameWithFallback)
.font(.caption)
.lineLimit(1)
.truncationMode(.tail)
Text("@\(account.acct)")
.font(.caption2)
.foregroundColor(.secondary)
.lineLimit(1)
.truncationMode(.tail)
}
Spacer()
}
.padding(.leading, 20)
ZStack {
LightChartView(
data: [200, 205, 208, 213, 210, 211, 212],
type: .line,
visualType: .filled(color: Asset.Colors.Brand.blurple.swiftUIColor, lineWidth: 2),
offset: 0.8 /// this is the positive offset from the bottom edge of the graph (~80% above bottom level)
)
HStack {
VStack(alignment: .leading, spacing: 0) {
Spacer()
Text("+4 followers today")
.font(.system(size: 12))
.foregroundColor(.secondary)
.lineLimit(1)
.truncationMode(.tail)
Text(account.followersCount.asAbbreviatedCountString())
.font(.largeTitle)
.lineLimit(1)
.truncationMode(.tail)
}
Spacer()
}
.padding(.bottom, 16)
.padding(.leading, 20)
}
}
.padding(.top, 16)
}
private func viewForAccessoryRectangular(_ account :FollowersEntryAccountable) -> some View {
HStack(spacing: 0) {
VStack(alignment: .leading, spacing: 0) {