Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion WooCommerce/Resources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@
<key>NSPhotoLibraryUsageDescription</key>
<string>To save photos from camera for Product images, or to add photos or videos to your Products or support tickets.</string>
<key>NSUserActivityTypes</key>
<array/>
<array>
<string>StoreWidgetsConfigIntent</string>
</array>
<key>UIAppFonts</key>
<array>
<string>Noticons.ttf</string>
Expand Down
28 changes: 28 additions & 0 deletions WooCommerce/StoreWidgets/StatsTimeRange.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// Represents the time range for an Order Stats v4 model.
/// This is a local property and not in the remote response.
///
/// - today: hourly data starting midnight today until now.
/// - thisWeek: daily data starting Sunday of this week until now.
/// - thisMonth: daily data starting 1st of this month until now.
/// - thisYear: monthly data starting January of this year until now.
enum StatsTimeRange: String {
case today
case thisWeek
case thisMonth
case thisYear
}

extension StatsTimeRange {
init(_ timeRange: IntentTimeRange) {
switch timeRange {
case .unknown, .today:
self = .today
case .thisWeek:
self = .thisWeek
case .thisMonth:
self = .thisMonth
case .thisYear:
self = .thisYear
}
}
}
6 changes: 3 additions & 3 deletions WooCommerce/StoreWidgets/StoreInfoDataService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ final class StoreInfoDataService {
///
private var orderStatsRemoteV4: OrderStatsRemoteV4

/// Visitors remoute source
/// Visitors remote source
///
private var siteVisitStatsRemote: SiteVisitStatsRemote

Expand All @@ -31,9 +31,9 @@ final class StoreInfoDataService {
siteVisitStatsRemote = SiteVisitStatsRemote(network: network)
}

/// Async function that fetches todays stats data.
/// Async function that fetches stats data for given time range.
///
func fetchTodayStats(for storeID: Int64) async throws -> Stats {
func fetchStats(for storeID: Int64, timeRange: StatsTimeRange) async throws -> Stats {
// Prepare them to run in parallel
async let revenueAndOrdersRequest = fetchTodaysRevenueAndOrders(for: storeID)
async let visitorsRequest = fetchTodaysVisitors(for: storeID)
Expand Down
8 changes: 4 additions & 4 deletions WooCommerce/StoreWidgets/StoreInfoProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct StoreInfoData {

/// Type that provides data entries to the widget system.
///
final class StoreInfoProvider: TimelineProvider {
final class StoreInfoProvider: IntentTimelineProvider {

/// Holds a reference to the service while a network request is being performed.
///
Expand All @@ -75,13 +75,13 @@ final class StoreInfoProvider: TimelineProvider {

/// Quick Snapshot. Required when previewing the widget.
///
func getSnapshot(in context: Context, completion: @escaping (StoreInfoEntry) -> Void) {
func getSnapshot(for configuration: StoreWidgetsConfigIntent, in context: Context, completion: @escaping (StoreInfoEntry) -> Void) {
completion(placeholder(in: context))
}

/// Real data widget.
///
func getTimeline(in context: Context, completion: @escaping (Timeline<StoreInfoEntry>) -> Void) {
func getTimeline(for configuration: StoreWidgetsConfigIntent, in context: Context, completion: @escaping (Timeline<StoreInfoEntry>) -> Void) {
guard let dependencies = Self.fetchDependencies() else {
return completion(Timeline<StoreInfoEntry>(entries: [StoreInfoEntry.notConnected], policy: .never))
}
Expand All @@ -90,7 +90,7 @@ final class StoreInfoProvider: TimelineProvider {
networkService = strongService
Task {
do {
let todayStats = try await strongService.fetchTodayStats(for: dependencies.storeID)
let todayStats = try await strongService.fetchStats(for: dependencies.storeID, timeRange: StatsTimeRange(configuration.timeRange))
let entry = Self.dataEntry(for: todayStats, with: dependencies)
let reloadDate = Date(timeIntervalSinceNow: reloadInterval)
let timeline = Timeline<StoreInfoEntry>(entries: [entry], policy: .after(reloadDate))
Expand Down
2 changes: 1 addition & 1 deletion WooCommerce/StoreWidgets/StoreInfoWidget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct StoreInfoWidget: Widget {
}

var body: some WidgetConfiguration {
StaticConfiguration(kind: WooConstants.storeInfoWidgetKind, provider: StoreInfoProvider()) { entry in
IntentConfiguration(kind: WooConstants.storeInfoWidgetKind, intent: StoreWidgetsConfigIntent.self, provider: StoreInfoProvider()) { entry in
StoreInfoWidgetEntryView(entry: entry)
}
.configurationDisplayName(Localization.title)
Expand Down
176 changes: 171 additions & 5 deletions WooCommerce/StoreWidgets/StoreWidgets.intentdefinition
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,185 @@
<plist version="1.0">
<dict>
<key>INEnums</key>
<array/>
<array>
<dict>
<key>INEnumDisplayName</key>
<string>Time Range</string>
<key>INEnumDisplayNameID</key>
<string>pG2KCr</string>
<key>INEnumGeneratesHeader</key>
<true/>
<key>INEnumName</key>
<string>IntentTimeRange</string>
<key>INEnumType</key>
<string>Regular</string>
<key>INEnumValues</key>
<array>
<dict>
<key>INEnumValueDisplayName</key>
<string>unknown</string>
<key>INEnumValueDisplayNameID</key>
<string>whdG6s</string>
<key>INEnumValueName</key>
<string>unknown</string>
</dict>
<dict>
<key>INEnumValueDisplayName</key>
<string>Today</string>
<key>INEnumValueDisplayNameID</key>
<string>Jj2AK7</string>
<key>INEnumValueIndex</key>
<integer>1</integer>
<key>INEnumValueName</key>
<string>today</string>
</dict>
<dict>
<key>INEnumValueDisplayName</key>
<string>This Week</string>
<key>INEnumValueDisplayNameID</key>
<string>jzdldh</string>
<key>INEnumValueIndex</key>
<integer>2</integer>
<key>INEnumValueName</key>
<string>thisWeek</string>
</dict>
<dict>
<key>INEnumValueDisplayName</key>
<string>This Month</string>
<key>INEnumValueDisplayNameID</key>
<string>1HCLUn</string>
<key>INEnumValueIndex</key>
<integer>3</integer>
<key>INEnumValueName</key>
<string>thisMonth</string>
</dict>
<dict>
<key>INEnumValueDisplayName</key>
<string>This Year</string>
<key>INEnumValueDisplayNameID</key>
<string>rkviBd</string>
<key>INEnumValueIndex</key>
<integer>4</integer>
<key>INEnumValueName</key>
<string>thisYear</string>
</dict>
</array>
</dict>
</array>
<key>INIntentDefinitionModelVersion</key>
<string>1.2</string>
<key>INIntentDefinitionNamespace</key>
<string>88xZPY</string>
<key>INIntentDefinitionSystemVersion</key>
<string>21G83</string>
<string>21G115</string>
<key>INIntentDefinitionToolsBuildVersion</key>
<string>13F100</string>
<string>14A309</string>
<key>INIntentDefinitionToolsVersion</key>
<string>13.4.1</string>
<string>14.0</string>
<key>INIntents</key>
<array/>
<array>
<dict>
<key>INIntentCategory</key>
<string>information</string>
<key>INIntentDescriptionID</key>
<string>vsIoMZ</string>
<key>INIntentEligibleForWidgets</key>
<true/>
<key>INIntentIneligibleForSuggestions</key>
<true/>
<key>INIntentLastParameterTag</key>
<integer>2</integer>
<key>INIntentName</key>
<string>StoreWidgetsConfig</string>
<key>INIntentParameters</key>
<array>
<dict>
<key>INIntentParameterConfigurable</key>
<true/>
<key>INIntentParameterDisplayName</key>
<string>Time Range</string>
<key>INIntentParameterDisplayNameID</key>
<string>Piwru2</string>
<key>INIntentParameterDisplayPriority</key>
<integer>1</integer>
<key>INIntentParameterEnumType</key>
<string>IntentTimeRange</string>
<key>INIntentParameterEnumTypeNamespace</key>
<string>88xZPY</string>
<key>INIntentParameterMetadata</key>
<dict>
<key>INIntentParameterMetadataDefaultValue</key>
<string>today</string>
</dict>
<key>INIntentParameterName</key>
<string>timeRange</string>
<key>INIntentParameterPromptDialogs</key>
<array>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogType</key>
<string>Configuration</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogType</key>
<string>Primary</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogFormatString</key>
<string>There are ${count} options matching ‘${timeRange}’.</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>8m39ih</string>
<key>INIntentParameterPromptDialogType</key>
<string>DisambiguationIntroduction</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogFormatString</key>
<string>Just to confirm, you wanted ‘${timeRange}’?</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>SEcvUI</string>
<key>INIntentParameterPromptDialogType</key>
<string>Confirmation</string>
</dict>
</array>
<key>INIntentParameterTag</key>
<integer>2</integer>
<key>INIntentParameterType</key>
<string>Integer</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>Store Widgets Config</string>
<key>INIntentTitleID</key>
<string>lYFT2L</string>
<key>INIntentType</key>
<string>Custom</string>
<key>INIntentVerb</key>
<string>View</string>
</dict>
</array>
<key>INTypes</key>
<array/>
</dict>
Expand Down
4 changes: 4 additions & 0 deletions WooCommerce/WooCommerce.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,7 @@
AEA622B2274669D3002A9B57 /* AddOrderCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA622B1274669D3002A9B57 /* AddOrderCoordinator.swift */; };
AEA622B427466B78002A9B57 /* BottomSheetOrderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA622B327466B78002A9B57 /* BottomSheetOrderType.swift */; };
AEA622B727468790002A9B57 /* AddOrderCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA622B627468790002A9B57 /* AddOrderCoordinatorTests.swift */; };
AEA7840428FEE82A000485FC /* StatsTimeRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA7840328FEE82A000485FC /* StatsTimeRange.swift */; };
AEACCB6D2785FF4A000D01F0 /* NavigationRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEACCB6C2785FF4A000D01F0 /* NavigationRow.swift */; };
AEB73C0C25CD734200A8454A /* AttributePickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEB73C0B25CD734200A8454A /* AttributePickerViewModel.swift */; };
AEB73C1725CD8E5800A8454A /* AttributePickerViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEB73C1625CD8E5800A8454A /* AttributePickerViewModelTests.swift */; };
Expand Down Expand Up @@ -3046,6 +3047,7 @@
AEA622B1274669D3002A9B57 /* AddOrderCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOrderCoordinator.swift; sourceTree = "<group>"; };
AEA622B327466B78002A9B57 /* BottomSheetOrderType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomSheetOrderType.swift; sourceTree = "<group>"; };
AEA622B627468790002A9B57 /* AddOrderCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOrderCoordinatorTests.swift; sourceTree = "<group>"; };
AEA7840328FEE82A000485FC /* StatsTimeRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatsTimeRange.swift; sourceTree = "<group>"; };
AEACCB6C2785FF4A000D01F0 /* NavigationRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRow.swift; sourceTree = "<group>"; };
AEB73C0B25CD734200A8454A /* AttributePickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributePickerViewModel.swift; sourceTree = "<group>"; };
AEB73C1625CD8E5800A8454A /* AttributePickerViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributePickerViewModelTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5378,6 +5380,7 @@
265C99E028B9BA43005E6117 /* StoreInfoWidget.swift */,
265C99E328B9C834005E6117 /* StoreInfoProvider.swift */,
260DE20828CA7CE2009ECD7C /* StoreInfoDataService.swift */,
AEA7840328FEE82A000485FC /* StatsTimeRange.swift */,
265C99E528B9CB8E005E6117 /* StoreInfoViewModifiers.swift */,
3F1FA84728B60125009E246C /* StoreWidgets.intentdefinition */,
3F1FA84828B60126009E246C /* Assets.xcassets */,
Expand Down Expand Up @@ -9395,6 +9398,7 @@
AED9012D28E5F517002B4572 /* AppLinkWidget.swift in Sources */,
2608C50728C941D600C9DFC0 /* UserDefaults+Woo.swift in Sources */,
265C99E628B9CB8E005E6117 /* StoreInfoViewModifiers.swift in Sources */,
AEA7840428FEE82A000485FC /* StatsTimeRange.swift in Sources */,
2608C50628C93AB700C9DFC0 /* WooConstants.swift in Sources */,
260DE20A28CA7CFE009ECD7C /* StoreInfoDataService.swift in Sources */,
AE56E73428E76CDB00A1292B /* StoreInfoInlineWidget.swift in Sources */,
Expand Down