Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve widgets UI and add snapshot tests #3452

Merged
merged 5 commits into from
Feb 20, 2025
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
57 changes: 57 additions & 0 deletions HomeAssistant.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,10 @@
420E2AE72C474718004921D8 /* WidgetBasicViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420E2AE22C4746BB004921D8 /* WidgetBasicViewModel.swift */; };
420E2AE82C47471B004921D8 /* WidgetBasicSizeStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420E2AE42C4746CD004921D8 /* WidgetBasicSizeStyle.swift */; };
420E2AE92C474729004921D8 /* WidgetCircularView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4008F0252C2D0A1A00E24001 /* WidgetCircularView.swift */; };
420E64BA2D676A5800A31E86 /* WidgetsSnapshot.test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420E64B82D676A5800A31E86 /* WidgetsSnapshot.test.swift */; };
420E64BD2D676B2400A31E86 /* InlineSnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 420E64BC2D676B2400A31E86 /* InlineSnapshotTesting */; };
420E64BF2D676B2400A31E86 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 420E64BE2D676B2400A31E86 /* SnapshotTesting */; };
420E64C12D676B2400A31E86 /* SnapshotTestingCustomDump in Frameworks */ = {isa = PBXBuildFile; productRef = 420E64C02D676B2400A31E86 /* SnapshotTestingCustomDump */; };
420F53E52C4E67FC003C8415 /* MockLocalNotificationDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420F53E42C4E67FC003C8415 /* MockLocalNotificationDispatcher.swift */; };
420F53EA2C4E9D54003C8415 /* WidgetsKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420F53E72C4E9AEE003C8415 /* WidgetsKind.swift */; };
420F53EB2C4E9D55003C8415 /* WidgetsKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420F53E72C4E9AEE003C8415 /* WidgetsKind.swift */; };
Expand Down Expand Up @@ -611,6 +615,11 @@
4235075D2CDB756800A19902 /* HAServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4235075C2CDB756800A19902 /* HAServices.swift */; };
4235075E2CDB756800A19902 /* HAServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4235075C2CDB756800A19902 /* HAServices.swift */; };
4239D1832C4FFCCE003497FC /* WatchUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4239D1802C4FFB75003497FC /* WatchUserDefaults.swift */; };
423B5E092D67781A0000CB95 /* WidgetBasicContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115560E027010D8400A8F818 /* WidgetBasicContainerView.swift */; };
423B5E0A2D6778370000CB95 /* WidgetBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 424A7F452B188946008C8DF3 /* WidgetBackground.swift */; };
423B5E0B2D677B9B0000CB95 /* WidgetCustom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4223688A2D40F9B7005911E4 /* WidgetCustom.swift */; };
423B5E0C2D677BA70000CB95 /* WidgetCustomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4223688D2D40FB00005911E4 /* WidgetCustomTimelineProvider.swift */; };
423B5E0D2D677BB90000CB95 /* WidgetContentMargin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 424A7F472B188BF3008C8DF3 /* WidgetContentMargin.swift */; };
423F44F02C17238200766A99 /* ChatBubbleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 423F44EF2C17238200766A99 /* ChatBubbleView.swift */; };
423F44FF2C186E4500766A99 /* WatchCommunicatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 423F44FE2C186E4500766A99 /* WatchCommunicatorService.swift */; };
423F45212C19D89100766A99 /* AssistDefaultComplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 423F45202C19D89100766A99 /* AssistDefaultComplication.swift */; };
Expand Down Expand Up @@ -1904,6 +1913,7 @@
420D5AE22C5A860900624A08 /* LocationPermissionSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPermissionSensor.swift; sourceTree = "<group>"; };
420E2AE22C4746BB004921D8 /* WidgetBasicViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBasicViewModel.swift; sourceTree = "<group>"; };
420E2AE42C4746CD004921D8 /* WidgetBasicSizeStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBasicSizeStyle.swift; sourceTree = "<group>"; };
420E64B82D676A5800A31E86 /* WidgetsSnapshot.test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetsSnapshot.test.swift; sourceTree = "<group>"; };
420F53E22C4E61C1003C8415 /* LocalNotificationDispatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotificationDispatcher.swift; sourceTree = "<group>"; };
420F53E42C4E67FC003C8415 /* MockLocalNotificationDispatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockLocalNotificationDispatcher.swift; sourceTree = "<group>"; };
420F53E72C4E9AEE003C8415 /* WidgetsKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetsKind.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2733,6 +2743,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
420E64C12D676B2400A31E86 /* SnapshotTestingCustomDump in Frameworks */,
420E64BF2D676B2400A31E86 /* SnapshotTesting in Frameworks */,
420E64BD2D676B2400A31E86 /* InlineSnapshotTesting in Frameworks */,
165955E006864CFE23355451 /* Pods_Tests_App.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -2859,6 +2872,7 @@
111501A82528414000DCFA94 /* Tests */ = {
isa = PBXGroup;
children = (
420E64B72D676A4200A31E86 /* Widgets */,
B657A8FF1CA646EB00121384 /* App */,
D03D894320E0BC1800D4F28D /* Shared */,
B657A90A1CA646EB00121384 /* UI */,
Expand Down Expand Up @@ -3755,6 +3769,14 @@
path = Tables;
sourceTree = "<group>";
};
420E64B72D676A4200A31E86 /* Widgets */ = {
isa = PBXGroup;
children = (
420E64B82D676A5800A31E86 /* WidgetsSnapshot.test.swift */,
);
path = Widgets;
sourceTree = "<group>";
};
420F53E62C4E9AA9003C8415 /* Action */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -5988,6 +6010,9 @@
bg,
);
mainGroup = B657A8DD1CA646EB00121384;
packageReferences = (
420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */,
);
productRefGroup = B657A8E71CA646EB00121384 /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down Expand Up @@ -6978,6 +7003,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
423B5E0B2D677B9B0000CB95 /* WidgetCustom.swift in Sources */,
115F9D7025F4B7B700CC6A45 /* TemplateSection.swift in Sources */,
403AE92A2C2F3A9200D48147 /* IntentServerAppEntitiy.swift in Sources */,
1101568524D770B2009424C9 /* NFCReader.swift in Sources */,
Expand All @@ -6994,6 +7020,7 @@
42FCCFFE2B9B1C310057783F /* ThreadCredentialsSharing+build.swift in Sources */,
425573E92B58396600145217 /* HAEntity+CarPlay.swift in Sources */,
B68EDD05215F12C900DD6B28 /* NotificationActionConfigurator.swift in Sources */,
423B5E0D2D677BB90000CB95 /* WidgetContentMargin.swift in Sources */,
B616B299227ED68E00828165 /* Bonjour.swift in Sources */,
420E2AE62C474710004921D8 /* WidgetBasicButtonView.swift in Sources */,
11A48D7F24CA7E820021BDD9 /* Action+Observation.swift in Sources */,
Expand Down Expand Up @@ -7075,6 +7102,8 @@
11F20BC5274B06C100DFB163 /* ServerSelectRow.swift in Sources */,
42EF0ACD2D4CDC0C0088C91E /* ResetAllCustomWidgetConfirmationAppIntent.swift in Sources */,
1130F532253A1E7400F371BE /* ComplicationListViewController.swift in Sources */,
423B5E0A2D6778370000CB95 /* WidgetBackground.swift in Sources */,
423B5E092D67781A0000CB95 /* WidgetBasicContainerView.swift in Sources */,
B6B2E6A5216ACE4400D39A26 /* ActionConfigurator.swift in Sources */,
42EFFAEC2C8882DD002F10FC /* CarPlayConfigurationView.swift in Sources */,
420C1BB52CF7DC1400AF22E7 /* ClientEventsLogViewModel.swift in Sources */,
Expand Down Expand Up @@ -7112,6 +7141,7 @@
1185DF96271FBB9800ED7D9A /* OnboardingAuthLogin.swift in Sources */,
425573E62B5838B600145217 /* MaterialDesignIcons+CarPlay.swift in Sources */,
42790C422C4806A700E31B38 /* ImprovFailureView.swift in Sources */,
423B5E0C2D677BA70000CB95 /* WidgetCustomTimelineProvider.swift in Sources */,
42AA4C842C2DACAD00EA2E99 /* UIImage+Circle.swift in Sources */,
42F1DA612B4D4F31002729BC /* CarPlayNoServerAlert.swift in Sources */,
11C590ED24A832CA0066085D /* YamlSection.swift in Sources */,
Expand Down Expand Up @@ -7259,6 +7289,7 @@
11A71C9124A598AB00D9565F /* ZoneManagerProcessor.test.swift in Sources */,
11ED439827265B9C00B5FD45 /* OnboardingAuthStepNotify.test.swift in Sources */,
42A818E72BBEAAE80083D045 /* MockAssistService.swift in Sources */,
420E64BA2D676A5800A31E86 /* WidgetsSnapshot.test.swift in Sources */,
11EFD3C327264306000AF78B /* UIAlertAction+Additions.swift in Sources */,
11A71C8F24A5946B00D9565F /* FakeCLLocationManager.swift in Sources */,
11EF62DA24C3687D00BABB64 /* ZoneManagerRegionFilter.test.swift in Sources */,
Expand Down Expand Up @@ -9491,7 +9522,33 @@
};
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing";
requirement = {
kind = exactVersion;
version = 1.18.1;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
420E64BC2D676B2400A31E86 /* InlineSnapshotTesting */ = {
isa = XCSwiftPackageProductDependency;
package = 420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */;
productName = InlineSnapshotTesting;
};
420E64BE2D676B2400A31E86 /* SnapshotTesting */ = {
isa = XCSwiftPackageProductDependency;
package = 420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */;
productName = SnapshotTesting;
};
420E64C02D676B2400A31E86 /* SnapshotTestingCustomDump */ = {
isa = XCSwiftPackageProductDependency;
package = 420E64BB2D676B2400A31E86 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */;
productName = SnapshotTestingCustomDump;
};
427692E22B98B82500F24321 /* SharedPush */ = {
isa = XCSwiftPackageProductDependency;
productName = SharedPush;
Expand Down
43 changes: 43 additions & 0 deletions HomeAssistant.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"object": {
"pins": [
{
"package": "swift-custom-dump",
"repositoryURL": "https://github.com/pointfreeco/swift-custom-dump",
"state": {
"branch": null,
"revision": "82645ec760917961cfa08c9c0c7104a57a0fa4b1",
"version": "1.3.3"
}
},
{
"package": "swift-snapshot-testing",
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing",
"state": {
"branch": null,
"revision": "b2d4cb30735f4fbc3a01963a9c658336dd21e9ba",
"version": "1.18.1"
}
},
{
"package": "swift-syntax",
"repositoryURL": "https://github.com/swiftlang/swift-syntax",
"state": {
"branch": null,
"revision": "0687f71944021d616d34d922343dcef086855920",
"version": "600.0.1"
}
},
{
"package": "xctest-dynamic-overlay",
"repositoryURL": "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state": {
"branch": null,
"revision": "b444594f79844b0d6d76d70fbfb3f7f71728f938",
"version": "1.5.1"
}
}
]
},
"version": 1
}
2 changes: 1 addition & 1 deletion Sources/App/Settings/ActionConfigurator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ struct WidgetPreviewView: View {
backgroundColor: Color(uiColor: .init(hex: action.BackgroundColor)),
useCustomColors: action.useCustomColors
),
sizeStyle: .condensed,
sizeStyle: .compact,
tinted: false
)
.padding()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct WidgetBasicButtonView: WidgetBasicViewProtocol {
VStack(alignment: .leading) {
Group {
switch sizeStyle {
case .regular, .condensed, .compressed:
case .regular, .compact, .compressed:
HStack(alignment: .center, spacing: Spaces.oneAndHalf) {
icon
VStack(alignment: .leading, spacing: .zero) {
Expand Down
36 changes: 35 additions & 1 deletion Sources/Extensions/Widgets/Common/WidgetBasicContainerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,46 @@ struct WidgetBasicContainerView: View {
self.showLastUpdate = showLastUpdate
}

var body: some View {
WidgetBasicContainerWrapperView(
emptyViewGenerator: emptyViewGenerator,
contents: contents,
type: type,
showLastUpdate: showLastUpdate,
family: family
)
}
}

/// This wrapper only exists so it can be snapshot tested with the proper family size which is not possible with the
/// `WidgetBasicContainerView` and the environment variable
struct WidgetBasicContainerWrapperView: View {
let emptyViewGenerator: () -> AnyView
let contents: [WidgetBasicViewModel]
let type: WidgetType
let showLastUpdate: Bool
let family: WidgetFamily

init(
emptyViewGenerator: @escaping () -> AnyView,
contents: [WidgetBasicViewModel],
type: WidgetType,
showLastUpdate: Bool = false,
family: WidgetFamily
) {
self.emptyViewGenerator = emptyViewGenerator
self.contents = contents
self.type = type
self.showLastUpdate = showLastUpdate
self.family = family
}

var body: some View {
VStack {
if contents.isEmpty {
emptyViewGenerator()
} else {
content(for: contents)
content(for: Array(contents.prefix(WidgetFamilySizes.size(for: family))))
}
if showLastUpdate, !contents.isEmpty {
Group {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct WidgetBasicSensorView: WidgetBasicViewProtocol {
VStack(alignment: .leading) {
Group {
switch sizeStyle {
case .regular, .condensed, .compressed:
case .regular, .compact, .compressed:
HStack(alignment: .center, spacing: Spaces.oneAndHalf) {
VStack(alignment: .leading, spacing: .zero) {
subtext
Expand Down
22 changes: 15 additions & 7 deletions Sources/Extensions/Widgets/Common/WidgetBasicSizeStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import Foundation
import Shared
import SwiftUI

public enum WidgetBasicSizeStyle {
public enum WidgetBasicSizeStyle: CaseIterable {
case single
case expanded
case condensed
case compact
/// Minimum size possible for widget, removing padding and borders as well
case compressed
case regular
Expand All @@ -14,17 +14,21 @@ public enum WidgetBasicSizeStyle {
switch self {
case .single, .expanded:
return .subheadline
case .condensed, .regular, .compressed:
case .compact, .regular:
return .footnote
case .compressed:
return .caption
}
}

var subtextFont: Font {
switch self {
case .single, .expanded:
return .footnote
case .regular, .condensed, .compressed:
return .system(size: 12)
case .regular, .compact:
return .caption
case .compressed:
return .caption2
}
}

Expand All @@ -36,8 +40,10 @@ public enum WidgetBasicSizeStyle {
size = 32
case .expanded:
size = 28
case .regular, .condensed, .compressed:
case .regular, .compact:
size = 20
case .compressed:
size = 15
}

return .custom(MaterialDesignIcons.familyName, size: size)
Expand All @@ -50,8 +56,10 @@ public enum WidgetBasicSizeStyle {
return .init(width: 48, height: 48)
case .expanded:
return .init(width: 42, height: 42)
case .regular, .condensed, .compressed:
case .regular, .compact:
return .init(width: 38, height: 38)
case .compressed:
return .init(width: 30, height: 30)
}
}
}
Loading
Loading