Skip to content

Commit b1ce696

Browse files
authored
Improve widgets UI and add snapshot tests (#3452)
1 parent 0c02e9f commit b1ce696

File tree

155 files changed

+622
-157
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+622
-157
lines changed

HomeAssistant.xcodeproj/project.pbxproj

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,10 @@
568568
420E2AE72C474718004921D8 /* WidgetBasicViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420E2AE22C4746BB004921D8 /* WidgetBasicViewModel.swift */; };
569569
420E2AE82C47471B004921D8 /* WidgetBasicSizeStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420E2AE42C4746CD004921D8 /* WidgetBasicSizeStyle.swift */; };
570570
420E2AE92C474729004921D8 /* WidgetCircularView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4008F0252C2D0A1A00E24001 /* WidgetCircularView.swift */; };
571+
420E64BA2D676A5800A31E86 /* WidgetsSnapshot.test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420E64B82D676A5800A31E86 /* WidgetsSnapshot.test.swift */; };
572+
420E64BD2D676B2400A31E86 /* InlineSnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 420E64BC2D676B2400A31E86 /* InlineSnapshotTesting */; };
573+
420E64BF2D676B2400A31E86 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 420E64BE2D676B2400A31E86 /* SnapshotTesting */; };
574+
420E64C12D676B2400A31E86 /* SnapshotTestingCustomDump in Frameworks */ = {isa = PBXBuildFile; productRef = 420E64C02D676B2400A31E86 /* SnapshotTestingCustomDump */; };
571575
420F53E52C4E67FC003C8415 /* MockLocalNotificationDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420F53E42C4E67FC003C8415 /* MockLocalNotificationDispatcher.swift */; };
572576
420F53EA2C4E9D54003C8415 /* WidgetsKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420F53E72C4E9AEE003C8415 /* WidgetsKind.swift */; };
573577
420F53EB2C4E9D55003C8415 /* WidgetsKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420F53E72C4E9AEE003C8415 /* WidgetsKind.swift */; };
@@ -611,6 +615,11 @@
611615
4235075D2CDB756800A19902 /* HAServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4235075C2CDB756800A19902 /* HAServices.swift */; };
612616
4235075E2CDB756800A19902 /* HAServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4235075C2CDB756800A19902 /* HAServices.swift */; };
613617
4239D1832C4FFCCE003497FC /* WatchUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4239D1802C4FFB75003497FC /* WatchUserDefaults.swift */; };
618+
423B5E092D67781A0000CB95 /* WidgetBasicContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115560E027010D8400A8F818 /* WidgetBasicContainerView.swift */; };
619+
423B5E0A2D6778370000CB95 /* WidgetBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 424A7F452B188946008C8DF3 /* WidgetBackground.swift */; };
620+
423B5E0B2D677B9B0000CB95 /* WidgetCustom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4223688A2D40F9B7005911E4 /* WidgetCustom.swift */; };
621+
423B5E0C2D677BA70000CB95 /* WidgetCustomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4223688D2D40FB00005911E4 /* WidgetCustomTimelineProvider.swift */; };
622+
423B5E0D2D677BB90000CB95 /* WidgetContentMargin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 424A7F472B188BF3008C8DF3 /* WidgetContentMargin.swift */; };
614623
423F44F02C17238200766A99 /* ChatBubbleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 423F44EF2C17238200766A99 /* ChatBubbleView.swift */; };
615624
423F44FF2C186E4500766A99 /* WatchCommunicatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 423F44FE2C186E4500766A99 /* WatchCommunicatorService.swift */; };
616625
423F45212C19D89100766A99 /* AssistDefaultComplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 423F45202C19D89100766A99 /* AssistDefaultComplication.swift */; };
@@ -1904,6 +1913,7 @@
19041913
420D5AE22C5A860900624A08 /* LocationPermissionSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPermissionSensor.swift; sourceTree = "<group>"; };
19051914
420E2AE22C4746BB004921D8 /* WidgetBasicViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBasicViewModel.swift; sourceTree = "<group>"; };
19061915
420E2AE42C4746CD004921D8 /* WidgetBasicSizeStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBasicSizeStyle.swift; sourceTree = "<group>"; };
1916+
420E64B82D676A5800A31E86 /* WidgetsSnapshot.test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetsSnapshot.test.swift; sourceTree = "<group>"; };
19071917
420F53E22C4E61C1003C8415 /* LocalNotificationDispatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotificationDispatcher.swift; sourceTree = "<group>"; };
19081918
420F53E42C4E67FC003C8415 /* MockLocalNotificationDispatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockLocalNotificationDispatcher.swift; sourceTree = "<group>"; };
19091919
420F53E72C4E9AEE003C8415 /* WidgetsKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetsKind.swift; sourceTree = "<group>"; };
@@ -2733,6 +2743,9 @@
27332743
isa = PBXFrameworksBuildPhase;
27342744
buildActionMask = 2147483647;
27352745
files = (
2746+
420E64C12D676B2400A31E86 /* SnapshotTestingCustomDump in Frameworks */,
2747+
420E64BF2D676B2400A31E86 /* SnapshotTesting in Frameworks */,
2748+
420E64BD2D676B2400A31E86 /* InlineSnapshotTesting in Frameworks */,
27362749
165955E006864CFE23355451 /* Pods_Tests_App.framework in Frameworks */,
27372750
);
27382751
runOnlyForDeploymentPostprocessing = 0;
@@ -2859,6 +2872,7 @@
28592872
111501A82528414000DCFA94 /* Tests */ = {
28602873
isa = PBXGroup;
28612874
children = (
2875+
420E64B72D676A4200A31E86 /* Widgets */,
28622876
B657A8FF1CA646EB00121384 /* App */,
28632877
D03D894320E0BC1800D4F28D /* Shared */,
28642878
B657A90A1CA646EB00121384 /* UI */,
@@ -3755,6 +3769,14 @@
37553769
path = Tables;
37563770
sourceTree = "<group>";
37573771
};
3772+
420E64B72D676A4200A31E86 /* Widgets */ = {
3773+
isa = PBXGroup;
3774+
children = (
3775+
420E64B82D676A5800A31E86 /* WidgetsSnapshot.test.swift */,
3776+
);
3777+
path = Widgets;
3778+
sourceTree = "<group>";
3779+
};
37583780
420F53E62C4E9AA9003C8415 /* Action */ = {
37593781
isa = PBXGroup;
37603782
children = (
@@ -5988,6 +6010,9 @@
59886010
bg,
59896011
);
59906012
mainGroup = B657A8DD1CA646EB00121384;
6013+
packageReferences = (
6014+
420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */,
6015+
);
59916016
productRefGroup = B657A8E71CA646EB00121384 /* Products */;
59926017
projectDirPath = "";
59936018
projectRoot = "";
@@ -6978,6 +7003,7 @@
69787003
isa = PBXSourcesBuildPhase;
69797004
buildActionMask = 2147483647;
69807005
files = (
7006+
423B5E0B2D677B9B0000CB95 /* WidgetCustom.swift in Sources */,
69817007
115F9D7025F4B7B700CC6A45 /* TemplateSection.swift in Sources */,
69827008
403AE92A2C2F3A9200D48147 /* IntentServerAppEntitiy.swift in Sources */,
69837009
1101568524D770B2009424C9 /* NFCReader.swift in Sources */,
@@ -6994,6 +7020,7 @@
69947020
42FCCFFE2B9B1C310057783F /* ThreadCredentialsSharing+build.swift in Sources */,
69957021
425573E92B58396600145217 /* HAEntity+CarPlay.swift in Sources */,
69967022
B68EDD05215F12C900DD6B28 /* NotificationActionConfigurator.swift in Sources */,
7023+
423B5E0D2D677BB90000CB95 /* WidgetContentMargin.swift in Sources */,
69977024
B616B299227ED68E00828165 /* Bonjour.swift in Sources */,
69987025
420E2AE62C474710004921D8 /* WidgetBasicButtonView.swift in Sources */,
69997026
11A48D7F24CA7E820021BDD9 /* Action+Observation.swift in Sources */,
@@ -7075,6 +7102,8 @@
70757102
11F20BC5274B06C100DFB163 /* ServerSelectRow.swift in Sources */,
70767103
42EF0ACD2D4CDC0C0088C91E /* ResetAllCustomWidgetConfirmationAppIntent.swift in Sources */,
70777104
1130F532253A1E7400F371BE /* ComplicationListViewController.swift in Sources */,
7105+
423B5E0A2D6778370000CB95 /* WidgetBackground.swift in Sources */,
7106+
423B5E092D67781A0000CB95 /* WidgetBasicContainerView.swift in Sources */,
70787107
B6B2E6A5216ACE4400D39A26 /* ActionConfigurator.swift in Sources */,
70797108
42EFFAEC2C8882DD002F10FC /* CarPlayConfigurationView.swift in Sources */,
70807109
420C1BB52CF7DC1400AF22E7 /* ClientEventsLogViewModel.swift in Sources */,
@@ -7112,6 +7141,7 @@
71127141
1185DF96271FBB9800ED7D9A /* OnboardingAuthLogin.swift in Sources */,
71137142
425573E62B5838B600145217 /* MaterialDesignIcons+CarPlay.swift in Sources */,
71147143
42790C422C4806A700E31B38 /* ImprovFailureView.swift in Sources */,
7144+
423B5E0C2D677BA70000CB95 /* WidgetCustomTimelineProvider.swift in Sources */,
71157145
42AA4C842C2DACAD00EA2E99 /* UIImage+Circle.swift in Sources */,
71167146
42F1DA612B4D4F31002729BC /* CarPlayNoServerAlert.swift in Sources */,
71177147
11C590ED24A832CA0066085D /* YamlSection.swift in Sources */,
@@ -7259,6 +7289,7 @@
72597289
11A71C9124A598AB00D9565F /* ZoneManagerProcessor.test.swift in Sources */,
72607290
11ED439827265B9C00B5FD45 /* OnboardingAuthStepNotify.test.swift in Sources */,
72617291
42A818E72BBEAAE80083D045 /* MockAssistService.swift in Sources */,
7292+
420E64BA2D676A5800A31E86 /* WidgetsSnapshot.test.swift in Sources */,
72627293
11EFD3C327264306000AF78B /* UIAlertAction+Additions.swift in Sources */,
72637294
11A71C8F24A5946B00D9565F /* FakeCLLocationManager.swift in Sources */,
72647295
11EF62DA24C3687D00BABB64 /* ZoneManagerRegionFilter.test.swift in Sources */,
@@ -9491,7 +9522,33 @@
94919522
};
94929523
/* End XCConfigurationList section */
94939524

9525+
/* Begin XCRemoteSwiftPackageReference section */
9526+
420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = {
9527+
isa = XCRemoteSwiftPackageReference;
9528+
repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing";
9529+
requirement = {
9530+
kind = exactVersion;
9531+
version = 1.18.1;
9532+
};
9533+
};
9534+
/* End XCRemoteSwiftPackageReference section */
9535+
94949536
/* Begin XCSwiftPackageProductDependency section */
9537+
420E64BC2D676B2400A31E86 /* InlineSnapshotTesting */ = {
9538+
isa = XCSwiftPackageProductDependency;
9539+
package = 420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */;
9540+
productName = InlineSnapshotTesting;
9541+
};
9542+
420E64BE2D676B2400A31E86 /* SnapshotTesting */ = {
9543+
isa = XCSwiftPackageProductDependency;
9544+
package = 420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */;
9545+
productName = SnapshotTesting;
9546+
};
9547+
420E64C02D676B2400A31E86 /* SnapshotTestingCustomDump */ = {
9548+
isa = XCSwiftPackageProductDependency;
9549+
package = 420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */;
9550+
productName = SnapshotTestingCustomDump;
9551+
};
94959552
427692E22B98B82500F24321 /* SharedPush */ = {
94969553
isa = XCSwiftPackageProductDependency;
94979554
productName = SharedPush;

HomeAssistant.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/App/Settings/ActionConfigurator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ struct WidgetPreviewView: View {
383383
backgroundColor: Color(uiColor: .init(hex: action.BackgroundColor)),
384384
useCustomColors: action.useCustomColors
385385
),
386-
sizeStyle: .condensed,
386+
sizeStyle: .compact,
387387
tinted: false
388388
)
389389
.padding()

Sources/Extensions/Widgets/Common/WidgetBasicButtonView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct WidgetBasicButtonView: WidgetBasicViewProtocol {
6767
VStack(alignment: .leading) {
6868
Group {
6969
switch sizeStyle {
70-
case .regular, .condensed, .compressed:
70+
case .regular, .compact, .compressed:
7171
HStack(alignment: .center, spacing: Spaces.oneAndHalf) {
7272
icon
7373
VStack(alignment: .leading, spacing: .zero) {

Sources/Extensions/Widgets/Common/WidgetBasicContainerView.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,46 @@ struct WidgetBasicContainerView: View {
2323
self.showLastUpdate = showLastUpdate
2424
}
2525

26+
var body: some View {
27+
WidgetBasicContainerWrapperView(
28+
emptyViewGenerator: emptyViewGenerator,
29+
contents: contents,
30+
type: type,
31+
showLastUpdate: showLastUpdate,
32+
family: family
33+
)
34+
}
35+
}
36+
37+
/// This wrapper only exists so it can be snapshot tested with the proper family size which is not possible with the
38+
/// `WidgetBasicContainerView` and the environment variable
39+
struct WidgetBasicContainerWrapperView: View {
40+
let emptyViewGenerator: () -> AnyView
41+
let contents: [WidgetBasicViewModel]
42+
let type: WidgetType
43+
let showLastUpdate: Bool
44+
let family: WidgetFamily
45+
46+
init(
47+
emptyViewGenerator: @escaping () -> AnyView,
48+
contents: [WidgetBasicViewModel],
49+
type: WidgetType,
50+
showLastUpdate: Bool = false,
51+
family: WidgetFamily
52+
) {
53+
self.emptyViewGenerator = emptyViewGenerator
54+
self.contents = contents
55+
self.type = type
56+
self.showLastUpdate = showLastUpdate
57+
self.family = family
58+
}
59+
2660
var body: some View {
2761
VStack {
2862
if contents.isEmpty {
2963
emptyViewGenerator()
3064
} else {
31-
content(for: contents)
65+
content(for: Array(contents.prefix(WidgetFamilySizes.size(for: family))))
3266
}
3367
if showLastUpdate, !contents.isEmpty {
3468
Group {

Sources/Extensions/Widgets/Common/WidgetBasicSensorView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct WidgetBasicSensorView: WidgetBasicViewProtocol {
6464
VStack(alignment: .leading) {
6565
Group {
6666
switch sizeStyle {
67-
case .regular, .condensed, .compressed:
67+
case .regular, .compact, .compressed:
6868
HStack(alignment: .center, spacing: Spaces.oneAndHalf) {
6969
VStack(alignment: .leading, spacing: .zero) {
7070
subtext

Sources/Extensions/Widgets/Common/WidgetBasicSizeStyle.swift

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import Foundation
22
import Shared
33
import SwiftUI
44

5-
public enum WidgetBasicSizeStyle {
5+
public enum WidgetBasicSizeStyle: CaseIterable {
66
case single
77
case expanded
8-
case condensed
8+
case compact
99
/// Minimum size possible for widget, removing padding and borders as well
1010
case compressed
1111
case regular
@@ -14,17 +14,21 @@ public enum WidgetBasicSizeStyle {
1414
switch self {
1515
case .single, .expanded:
1616
return .subheadline
17-
case .condensed, .regular, .compressed:
17+
case .compact, .regular:
1818
return .footnote
19+
case .compressed:
20+
return .caption
1921
}
2022
}
2123

2224
var subtextFont: Font {
2325
switch self {
2426
case .single, .expanded:
2527
return .footnote
26-
case .regular, .condensed, .compressed:
27-
return .system(size: 12)
28+
case .regular, .compact:
29+
return .caption
30+
case .compressed:
31+
return .caption2
2832
}
2933
}
3034

@@ -36,8 +40,10 @@ public enum WidgetBasicSizeStyle {
3640
size = 32
3741
case .expanded:
3842
size = 28
39-
case .regular, .condensed, .compressed:
43+
case .regular, .compact:
4044
size = 20
45+
case .compressed:
46+
size = 15
4147
}
4248

4349
return .custom(MaterialDesignIcons.familyName, size: size)
@@ -50,8 +56,10 @@ public enum WidgetBasicSizeStyle {
5056
return .init(width: 48, height: 48)
5157
case .expanded:
5258
return .init(width: 42, height: 42)
53-
case .regular, .condensed, .compressed:
59+
case .regular, .compact:
5460
return .init(width: 38, height: 38)
61+
case .compressed:
62+
return .init(width: 30, height: 30)
5563
}
5664
}
5765
}

0 commit comments

Comments
 (0)