diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift index 5d7e582259c6..be5246d1dfe2 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift @@ -33,5 +33,6 @@ struct LockScreenStatsWidget: Widget { .configurationDisplayName(config.displayName) .description(config.description) .supportedFamilies(config.supportFamilies) + .iOS17ContentMarginsDisabled() /// Temporarily disable additional iOS17 margins for widgets } } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenMultiStatView.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenMultiStatView.swift index cdb3f6869efb..2ddcc195588b 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenMultiStatView.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenMultiStatView.swift @@ -31,9 +31,11 @@ struct LockScreenMultiStatView: View { Spacer() } } + .removableWidgetBackground() .accessibilityElement(children: .combine) } else { Text("Not implemented for widget family \(family.debugDescription)") + .removableWidgetBackground() } } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenSingleStatView.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenSingleStatView.swift index d78d8f74339c..c9b82721c27d 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenSingleStatView.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenSingleStatView.swift @@ -17,9 +17,11 @@ struct LockScreenSingleStatView: View { Spacer() } } + .removableWidgetBackground() .accessibilityElement(children: .combine) } else { Text("Not implemented for widget family \(family.debugDescription)") + .removableWidgetBackground() } } } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenUnconfiguredView.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenUnconfiguredView.swift index dd651b5cd16a..89f9310e5522 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenUnconfiguredView.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Views/LockScreenUnconfiguredView.swift @@ -14,8 +14,10 @@ struct LockScreenUnconfiguredView: View { .minimumScaleFactor(0.8) .multilineTextAlignment(.center) } + .removableWidgetBackground() } else { Text("Not implemented for widget family \(family.debugDescription)") + .removableWidgetBackground() } } } diff --git a/WordPress/JetpackStatsWidgets/Views/Cards/LockScreenFlexibleCard.swift b/WordPress/JetpackStatsWidgets/Views/Cards/LockScreenFlexibleCard.swift new file mode 100644 index 000000000000..47a48ec05dcc --- /dev/null +++ b/WordPress/JetpackStatsWidgets/Views/Cards/LockScreenFlexibleCard.swift @@ -0,0 +1,44 @@ +import SwiftUI + +/// A card with a title and a string value that is shown on LockScreen without background +struct LockScreenFlexibleCard: View { + let title: LocalizedString + let description: LocalizedString + let lineLimit: Int + + init(title: LocalizedString, description: LocalizedString, lineLimit: Int = 1) { + self.title = title + self.description = description + self.lineLimit = lineLimit + } + + var body: some View { + VStack(alignment: .leading) { + HStack(alignment: .firstTextBaseline, spacing: 4) { + Image("icon-jetpack") + .resizable() + .frame(width: 14, height: 14) + Text(description) + .font(Appearance.textFont) + .fontWeight(Appearance.textFontWeight) + .foregroundColor(Appearance.textColor) + .lineLimit(lineLimit) + } + Text(title) + .font(Appearance.titleFont) + .foregroundColor(Appearance.titleColor) + } + } +} + +// MARK: - Appearance +extension LockScreenFlexibleCard { + private enum Appearance { + static let textFont = Font.headline + static let textFontWeight = Font.Weight.semibold + static let textColor = Color(.label) + + static let titleFont = Font.subheadline + static let titleColor = Color(.secondaryLabel) + } +} diff --git a/WordPress/JetpackStatsWidgets/Views/Cards/LockScreenVerticalCard.swift b/WordPress/JetpackStatsWidgets/Views/Cards/LockScreenVerticalCard.swift new file mode 100644 index 000000000000..752c31c24d84 --- /dev/null +++ b/WordPress/JetpackStatsWidgets/Views/Cards/LockScreenVerticalCard.swift @@ -0,0 +1,39 @@ +import SwiftUI + +/// A card with a title and a value stacked vertically shown on LockScreen without background +struct LockScreenVerticalCard: View { + let title: LocalizedString + let value: Int + + private var accessibilityLabel: Text { + // The colon makes VoiceOver pause between elements + Text(title) + Text(": ") + Text(value.abbreviatedString()) + } + + var body: some View { + VStack(alignment: .leading) { + StatsValueView(value: value, + font: Appearance.extraLargeTextFont, + fontWeight: .heavy, + foregroundColor: Appearance.textColor, + lineLimit: nil) + .accessibility(label: accessibilityLabel) + Text(title) + .font(Appearance.titleFont) + .fontWeight(Appearance.titleFontWeight) + .foregroundColor(Appearance.titleColor) + .accessibility(hidden: true) + } + } +} + +// MARK: - Appearance +extension LockScreenVerticalCard { + private enum Appearance { + static let titleFont = Font.headline + static let titleFontWeight = Font.Weight.semibold + static let titleColor = Color(UIColor.label) + static let extraLargeTextFont = Font.system(size: 48, weight: .bold) + static let textColor = Color(UIColor.label) + } +} diff --git a/WordPress/JetpackStatsWidgets/Views/Cards/StatsValueView.swift b/WordPress/JetpackStatsWidgets/Views/Cards/StatsValueView.swift index 3436559bd445..324ced823334 100644 --- a/WordPress/JetpackStatsWidgets/Views/Cards/StatsValueView.swift +++ b/WordPress/JetpackStatsWidgets/Views/Cards/StatsValueView.swift @@ -30,5 +30,6 @@ struct StatsValueView: View { .fontWeight(fontWeight) .foregroundColor(foregroundColor) .lineLimit(lineLimit) + .minimumScaleFactor(0.5) } } diff --git a/WordPress/JetpackStatsWidgets/Views/Cards/VerticalCard.swift b/WordPress/JetpackStatsWidgets/Views/Cards/VerticalCard.swift index afef33c3743a..b9fb75193e2f 100644 --- a/WordPress/JetpackStatsWidgets/Views/Cards/VerticalCard.swift +++ b/WordPress/JetpackStatsWidgets/Views/Cards/VerticalCard.swift @@ -6,6 +6,8 @@ struct VerticalCard: View { let value: Int let largeText: Bool + @Environment(\.showsWidgetContainerBackground) var showsWidgetContainerBackground: Bool + private var titleFont: Font { largeText ? Appearance.largeTextFont : Appearance.textFont } @@ -17,18 +19,31 @@ struct VerticalCard: View { var body: some View { VStack(alignment: .leading) { - Text(title) - .font(Appearance.titleFont) - .fontWeight(Appearance.titleFontWeight) - .foregroundColor(Appearance.titleColor) - .accessibility(hidden: true) - StatsValueView(value: value, - font: titleFont, - fontWeight: .regular, - foregroundColor: Appearance.textColor, - lineLimit: nil) - .accessibility(label: accessibilityLabel) - + if showsWidgetContainerBackground { + Text(title) + .font(Appearance.titleFont) + .fontWeight(Appearance.titleFontWeight) + .foregroundColor(Appearance.titleColor) + .accessibility(hidden: true) + StatsValueView(value: value, + font: titleFont, + fontWeight: .regular, + foregroundColor: Appearance.textColor, + lineLimit: nil) + .accessibility(label: accessibilityLabel) + } else { + StatsValueView(value: value, + font: Appearance.extraLargeTextFont, + fontWeight: .heavy, + foregroundColor: Appearance.textColor, + lineLimit: nil) + .accessibility(label: accessibilityLabel) + Text(title) + .font(Appearance.titleFont) + .fontWeight(Appearance.titleFontWeight) + .foregroundColor(Appearance.titleColor) + .accessibility(hidden: true) + } } } } @@ -43,6 +58,7 @@ extension VerticalCard { static let titleColor = Color(UIColor.primary) static let largeTextFont = Font.largeTitle + static let extraLargeTextFont = Font.system(size: 48, weight: .bold) static let textFont = Font.title static let textColor = Color(.label) } diff --git a/WordPress/JetpackStatsWidgets/Views/Helpers/iOS17WidgetAPIs.swift b/WordPress/JetpackStatsWidgets/Views/Helpers/iOS17WidgetAPIs.swift new file mode 100644 index 000000000000..01e4ea037c92 --- /dev/null +++ b/WordPress/JetpackStatsWidgets/Views/Helpers/iOS17WidgetAPIs.swift @@ -0,0 +1,24 @@ +import SwiftUI +import WidgetKit + +extension View { + func removableWidgetBackground(_ backgroundView: some View = EmptyView()) -> some View { + if #available(iOSApplicationExtension 17.0, *) { + return containerBackground(for: .widget) { + backgroundView + } + } else { + return background(backgroundView) + } + } +} + +extension WidgetConfiguration { + func iOS17ContentMarginsDisabled() -> some WidgetConfiguration { + if #available(iOSApplicationExtension 17.0, *) { + return contentMarginsDisabled() + } else { + return self + } + } +} diff --git a/WordPress/JetpackStatsWidgets/Views/ListStatsView.swift b/WordPress/JetpackStatsWidgets/Views/ListStatsView.swift index 3f6424cbbac0..6dcc94a67657 100644 --- a/WordPress/JetpackStatsWidgets/Views/ListStatsView.swift +++ b/WordPress/JetpackStatsWidgets/Views/ListStatsView.swift @@ -34,6 +34,7 @@ struct ListStatsView: View { } } } + .removableWidgetBackground() } } diff --git a/WordPress/JetpackStatsWidgets/Views/MultiStatsView.swift b/WordPress/JetpackStatsWidgets/Views/MultiStatsView.swift index 86b86be89bdc..07dcb61ad517 100644 --- a/WordPress/JetpackStatsWidgets/Views/MultiStatsView.swift +++ b/WordPress/JetpackStatsWidgets/Views/MultiStatsView.swift @@ -23,6 +23,7 @@ Spacer() } } + .removableWidgetBackground() } /// Constructs a two-card column for the medium size Today widget diff --git a/WordPress/JetpackStatsWidgets/Views/SingleStatView.swift b/WordPress/JetpackStatsWidgets/Views/SingleStatView.swift index 580d755823b2..f606543d2121 100644 --- a/WordPress/JetpackStatsWidgets/Views/SingleStatView.swift +++ b/WordPress/JetpackStatsWidgets/Views/SingleStatView.swift @@ -1,19 +1,59 @@ import SwiftUI +import WidgetKit struct SingleStatView: View { + let title: String + let description: String + let valueTitle: String + let value: Int - let viewData: GroupedViewData + @Environment(\.showsWidgetContainerBackground) var showsWidgetContainerBackground: Bool + + init(viewData: GroupedViewData) { + self.title = viewData.widgetTitle + self.description = viewData.siteName + self.valueTitle = viewData.upperLeftTitle + self.value = viewData.upperLeftValue + } + + init(title: String, description: String, valueTitle: String, value: Int) { + self.title = title + self.description = description + self.valueTitle = valueTitle + self.value = value + } var body: some View { HStack { - VStack(alignment: .leading) { - FlexibleCard(axis: .vertical, title: viewData.widgetTitle, value: .description(viewData.siteName), lineLimit: 2) - - Spacer() - VerticalCard(title: viewData.upperLeftTitle, value: viewData.upperLeftValue, largeText: true) + if showsWidgetContainerBackground { + VStack(alignment: .leading) { + FlexibleCard(axis: .vertical, title: title, value: .description(description), lineLimit: 2) + Spacer() + VerticalCard(title: valueTitle, value: value, largeText: true) + } + .padding() + } else { + VStack(alignment: .leading) { + Spacer() + LockScreenFlexibleCard(title: title, description: description, lineLimit: 2) + Spacer().frame(height: 4) + LockScreenVerticalCard(title: valueTitle, value: value) + Spacer() + } } Spacer() } + .removableWidgetBackground() + } +} + +@available(iOS 16.0, *) +struct SingleStatView_Previews: PreviewProvider { + static var previews: some View { + SingleStatView(title: "Today", description: "My WordPress Site", valueTitle: "Views", value: 124909) + .previewContext( + WidgetPreviewContext(family: .systemSmall) + ) } } diff --git a/WordPress/JetpackStatsWidgets/Views/StatsWidgetsView.swift b/WordPress/JetpackStatsWidgets/Views/StatsWidgetsView.swift index 56c3d720865f..4428961b9b08 100644 --- a/WordPress/JetpackStatsWidgets/Views/StatsWidgetsView.swift +++ b/WordPress/JetpackStatsWidgets/Views/StatsWidgetsView.swift @@ -27,7 +27,6 @@ struct StatsWidgetsView: View { case .systemSmall: SingleStatView(viewData: viewData) .widgetURL(viewData.statsURL?.appendingSource(.homeScreenWidget)) - .padding() case .systemMedium: MultiStatsView(viewData: viewData) diff --git a/WordPress/JetpackStatsWidgets/Views/UnconfiguredView.swift b/WordPress/JetpackStatsWidgets/Views/UnconfiguredView.swift index f515edd8008b..9145b392d1be 100644 --- a/WordPress/JetpackStatsWidgets/Views/UnconfiguredView.swift +++ b/WordPress/JetpackStatsWidgets/Views/UnconfiguredView.swift @@ -3,13 +3,15 @@ import SwiftUI struct UnconfiguredView: View { var timelineEntry: StatsWidgetEntry + @Environment(\.showsWidgetContainerBackground) var showsWidgetContainerBackground: Bool var body: some View { Text(unconfiguredMessage) .font(.footnote) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(showsWidgetContainerBackground ? Color(.secondaryLabel) : Color(.label)) .multilineTextAlignment(.center) .padding() + .removableWidgetBackground() } var unconfiguredMessage: LocalizedString { diff --git a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift index 6c0fdd588372..0bbe43f5e0f6 100644 --- a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift +++ b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift @@ -27,5 +27,6 @@ struct HomeWidgetAllTime: Widget { .configurationDisplayName(LocalizableStrings.allTimeWidgetTitle) .description(LocalizableStrings.allTimePreviewDescription) .supportedFamilies([.systemSmall, .systemMedium]) + .iOS17ContentMarginsDisabled() /// Temporarily disable additional iOS17 margins for widgets } } diff --git a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift index 32e17fe7dd86..f48f4ebb6479 100644 --- a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift +++ b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift @@ -48,5 +48,6 @@ struct HomeWidgetThisWeek: Widget { .configurationDisplayName(LocalizableStrings.thisWeekWidgetTitle) .description(LocalizableStrings.thisWeekPreviewDescription) .supportedFamilies([.systemMedium, .systemLarge]) + .iOS17ContentMarginsDisabled() /// Temporarily disable additional iOS17 margins for widgets } } diff --git a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift index be7dfb66ad36..93225f77cc33 100644 --- a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift +++ b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift @@ -28,5 +28,6 @@ struct HomeWidgetToday: Widget { .configurationDisplayName(LocalizableStrings.todayWidgetTitle) .description(LocalizableStrings.todayPreviewDescription) .supportedFamilies([.systemSmall, .systemMedium]) + .iOS17ContentMarginsDisabled() /// Temporarily disable additional iOS17 margins for widgets for StandBy } } diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 1f6db2fafbf3..042088b33b09 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -193,6 +193,8 @@ 0188FE4C2AA62F800093EDA5 /* LockScreenTodayLikesCommentsStatWidgetConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0188FE4A2AA62F800093EDA5 /* LockScreenTodayLikesCommentsStatWidgetConfig.swift */; }; 0189AF052ACAD89700F63393 /* ShoppingCartService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0189AF042ACAD89700F63393 /* ShoppingCartService.swift */; }; 0189AF062ACAD89700F63393 /* ShoppingCartService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0189AF042ACAD89700F63393 /* ShoppingCartService.swift */; }; + 018FF1352AE6771A00F301C3 /* LockScreenVerticalCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 018FF1342AE6771A00F301C3 /* LockScreenVerticalCard.swift */; }; + 018FF1372AE67C2600F301C3 /* LockScreenFlexibleCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 018FF1362AE67C2600F301C3 /* LockScreenFlexibleCard.swift */; }; 019D699E2A5EA963003B676D /* RootViewCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019D699D2A5EA963003B676D /* RootViewCoordinatorTests.swift */; }; 019D69A02A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019D699F2A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift */; }; 019D69A12A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019D699F2A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift */; }; @@ -227,6 +229,7 @@ 01E258032ACC36FA00F09666 /* PlanStep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E258012ACC36FA00F09666 /* PlanStep.swift */; }; 01E258052ACC373800F09666 /* PlanWizardContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E258042ACC373800F09666 /* PlanWizardContent.swift */; }; 01E258062ACC373800F09666 /* PlanWizardContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E258042ACC373800F09666 /* PlanWizardContent.swift */; }; + 01E258092ACC3AA000F09666 /* iOS17WidgetAPIs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E258082ACC3AA000F09666 /* iOS17WidgetAPIs.swift */; }; 01E2580B2ACDC72C00F09666 /* PlanWizardContentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E2580A2ACDC72C00F09666 /* PlanWizardContentViewModel.swift */; }; 01E2580C2ACDC72C00F09666 /* PlanWizardContentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E2580A2ACDC72C00F09666 /* PlanWizardContentViewModel.swift */; }; 01E2580E2ACDC88100F09666 /* PlanWizardContentViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E2580D2ACDC88100F09666 /* PlanWizardContentViewModelTests.swift */; }; @@ -5874,6 +5877,8 @@ 0188FE472AA62D080093EDA5 /* LockScreenMultiStatWidgetViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenMultiStatWidgetViewProvider.swift; sourceTree = ""; }; 0188FE4A2AA62F800093EDA5 /* LockScreenTodayLikesCommentsStatWidgetConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenTodayLikesCommentsStatWidgetConfig.swift; sourceTree = ""; }; 0189AF042ACAD89700F63393 /* ShoppingCartService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCartService.swift; sourceTree = ""; }; + 018FF1342AE6771A00F301C3 /* LockScreenVerticalCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenVerticalCard.swift; sourceTree = ""; }; + 018FF1362AE67C2600F301C3 /* LockScreenFlexibleCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenFlexibleCard.swift; sourceTree = ""; }; 019D699D2A5EA963003B676D /* RootViewCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewCoordinatorTests.swift; sourceTree = ""; }; 019D699F2A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressAuthenticatorProtocol.swift; sourceTree = ""; }; 01A8508A2A8A126400BD8A97 /* support_chat_widget.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = support_chat_widget.css; sourceTree = ""; }; @@ -5892,6 +5897,7 @@ 01DBFD8629BDCBF200F3720F /* JetpackNativeConnectionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JetpackNativeConnectionService.swift; sourceTree = ""; }; 01E258012ACC36FA00F09666 /* PlanStep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanStep.swift; sourceTree = ""; }; 01E258042ACC373800F09666 /* PlanWizardContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanWizardContent.swift; sourceTree = ""; }; + 01E258082ACC3AA000F09666 /* iOS17WidgetAPIs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOS17WidgetAPIs.swift; sourceTree = ""; }; 01E2580A2ACDC72C00F09666 /* PlanWizardContentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanWizardContentViewModel.swift; sourceTree = ""; }; 01E2580D2ACDC88100F09666 /* PlanWizardContentViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanWizardContentViewModelTests.swift; sourceTree = ""; }; 01E78D1C296EA54F00FB6863 /* StatsPeriodHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsPeriodHelperTests.swift; sourceTree = ""; }; @@ -9901,6 +9907,14 @@ path = Plan; sourceTree = ""; }; + 01E258072ACC3A9000F09666 /* Helpers */ = { + isa = PBXGroup; + children = ( + 01E258082ACC3AA000F09666 /* iOS17WidgetAPIs.swift */, + ); + path = Helpers; + sourceTree = ""; + }; 027AC51F2278982D0033E56E /* DomainCredit */ = { isa = PBXGroup; children = ( @@ -11603,6 +11617,7 @@ 3F526D2B2539F9D60069706C /* Views */ = { isa = PBXGroup; children = ( + 01E258072ACC3A9000F09666 /* Helpers */, 3FCF66E825CAF8C50047F337 /* ListStatsView.swift */, 3F5689FF25420DE80048A9E4 /* MultiStatsView.swift */, 3F5689EF254209790048A9E4 /* SingleStatView.swift */, @@ -11637,7 +11652,9 @@ 3FCF66FA25CAF8E00047F337 /* ListRow.swift */, 3F568A2E254216550048A9E4 /* FlexibleCard.swift */, 3F568A1E254213B60048A9E4 /* VerticalCard.swift */, + 018FF1342AE6771A00F301C3 /* LockScreenVerticalCard.swift */, 3FA59B99258289E30073772F /* StatsValueView.swift */, + 018FF1362AE67C2600F301C3 /* LockScreenFlexibleCard.swift */, ); path = Cards; sourceTree = ""; @@ -20926,10 +20943,12 @@ 0107E0BA28F97D5000DE87DB /* TodayWidgetStats.swift in Sources */, C9B477AD29CC15D9008CBF49 /* WidgetDataReader.swift in Sources */, C9FE384129C2A3D200D39841 /* LockScreenTodayViewsStatWidgetConfig.swift in Sources */, + 01E258092ACC3AA000F09666 /* iOS17WidgetAPIs.swift in Sources */, 0188FE402AA613850093EDA5 /* LockScreenMultiStatView.swift in Sources */, 0107E16128FFE99300DE87DB /* WidgetConfiguration.swift in Sources */, 0107E0BB28F97D5000DE87DB /* StatsWidgetsService.swift in Sources */, C9B477B729CD2EF7008CBF49 /* LockScreenUnconfiguredView.swift in Sources */, + 018FF1372AE67C2600F301C3 /* LockScreenFlexibleCard.swift in Sources */, 0107E0BC28F97D5000DE87DB /* StatsWidgetsView.swift in Sources */, 01D2FF6B2AA782720038E040 /* LockScreenAllTimePostsBestViewsStatWidgetConfig.swift in Sources */, 0107E0BD28F97D5000DE87DB /* AppLocalizedString.swift in Sources */, @@ -20972,6 +20991,7 @@ 01D2FF652AA77F790038E040 /* LockScreenTodayViewsVisitorsStatWidgetConfig.swift in Sources */, 0107E0D528F97D5000DE87DB /* HomeWidgetTodayData.swift in Sources */, 0107E0D628F97D5000DE87DB /* AllTimeWidgetStats.swift in Sources */, + 018FF1352AE6771A00F301C3 /* LockScreenVerticalCard.swift in Sources */, 0107E0D728F97D5000DE87DB /* Sites.intentdefinition in Sources */, 0107E0D828F97D5000DE87DB /* LocalizableStrings.swift in Sources */, C9FE383229C2053300D39841 /* LockScreenSingleStatView.swift in Sources */,