feat(Widget): Implement LightChartView for Small FollowerCount
This commit is contained in:
parent
aeaa3ea3ab
commit
1558579a86
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue