Skip to content

Commit be398e8

Browse files
authored
Revert watch changes for watchOS 26 and adapt notifications and UI in a different way (#3881)
1 parent 619511c commit be398e8

15 files changed

+580
-521
lines changed

HomeAssistant.xcodeproj/project.pbxproj

Lines changed: 30 additions & 16 deletions
Large diffs are not rendered by default.

Sources/Extensions/Watch/ExtensionDelegate.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import UserNotifications
66
import WatchKit
77
import XCGLogger
88

9-
class ExtensionDelegate: NSObject, WKApplicationDelegate {
9+
class ExtensionDelegate: NSObject, WKExtensionDelegate {
1010
// MARK: Fileprivate
1111

1212
fileprivate var watchConnectivityBackgroundPromise: Guarantee<Void>
@@ -20,7 +20,7 @@ class ExtensionDelegate: NSObject, WKApplicationDelegate {
2020
super.init()
2121
}
2222

23-
// MARK: - WKApplicationDelegate -
23+
// MARK: - WKExtensionDelegate -
2424

2525
func applicationDidFinishLaunching() {
2626
// Perform any final initialization of your application.
@@ -31,7 +31,7 @@ class ExtensionDelegate: NSObject, WKApplicationDelegate {
3131

3232
let options: UNAuthorizationOptions = [.alert, .badge, .sound, .criticalAlert, .providesAppNotificationSettings]
3333

34-
WKApplication.shared().registerForRemoteNotifications()
34+
WKExtension.shared().registerForRemoteNotifications()
3535

3636
UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
3737
Current.Log.verbose("Requested notifications access \(granted), \(String(describing: error))")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#if os(watchOS)
2+
import Shared
3+
import SwiftUI
4+
5+
private struct CircularGlassOrLegacyBackgroundModifier: ViewModifier {
6+
func body(content: Content) -> some View {
7+
Group {
8+
if #available(watchOS 26.0, *) {
9+
content
10+
.frame(width: 30, height: 30)
11+
.padding(DesignSystem.Spaces.half)
12+
.glassEffect(.clear.interactive(), in: .circle)
13+
} else {
14+
content
15+
.padding(DesignSystem.Spaces.half)
16+
.background(.black)
17+
.clipShape(.circle)
18+
}
19+
}
20+
}
21+
}
22+
23+
extension View {
24+
/// Applies a circular glass effect on watchOS 26+, otherwise falls back to padding + black background.
25+
func circularGlassOrLegacyBackground() -> some View {
26+
modifier(CircularGlassOrLegacyBackgroundModifier())
27+
}
28+
}
29+
30+
#endif

Sources/Extensions/Watch/Home/WatchHomeView.swift

Lines changed: 41 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct WatchHomeView: View {
88

99
var body: some View {
1010
navigation
11+
._statusBarHidden(true)
1112
.onReceive(NotificationCenter.default.publisher(for: AssistDefaultComplication.launchNotification)) { _ in
1213
showAssist = true
1314
}
@@ -53,15 +54,6 @@ struct WatchHomeView: View {
5354
NavigationStack {
5455
content
5556
.persistentSystemOverlays(.hidden)
56-
.toolbar {
57-
reloadToolbarButton
58-
if viewModel.showAssist {
59-
assistToolbarButton
60-
}
61-
if viewModel.isLoading {
62-
toolbarLoadingState
63-
}
64-
}
6557
}
6658
}
6759

@@ -74,12 +66,21 @@ struct WatchHomeView: View {
7466
@ViewBuilder
7567
private var content: some View {
7668
List {
77-
inlineLoader
69+
listHeader
7870
listContent
7971
footer
8072
}
73+
// Removing the safe area so our fake navigation bar buttons (header) can be place correctly
74+
.ignoresSafeArea([.all], edges: .top)
8175
.id(viewModel.refreshListID)
8276
.navigationTitle("")
77+
.modify { view in
78+
if #available(watchOS 11.0, *) {
79+
view.toolbarVisibility(.hidden, for: .navigationBar)
80+
} else {
81+
view
82+
}
83+
}
8384
}
8485

8586
@ViewBuilder
@@ -93,19 +94,21 @@ struct WatchHomeView: View {
9394
}
9495

9596
@ViewBuilder
96-
private var inlineReloadButton: some View {
97-
if viewModel.watchConfig.items.isEmpty || viewModel.showError {
98-
reloadButton
99-
}
100-
}
101-
102-
@ViewBuilder
103-
private var inlineLoader: some View {
104-
// Loader is displayed in list when watchOS 10 is not available
105-
if viewModel.isLoading, #unavailable(watchOS 10.0) {
106-
loadingState
107-
.listRowBackground(Color.clear)
97+
private var listHeader: some View {
98+
HStack {
99+
navReloadButton
100+
Spacer()
101+
if viewModel.isLoading {
102+
toolbarLoadingState
103+
}
104+
if viewModel.showAssist {
105+
Spacer()
106+
assistHeaderButton
107+
} else {
108+
Spacer()
109+
}
108110
}
111+
.listRowBackground(Color.clear)
109112
}
110113

111114
@ViewBuilder
@@ -122,35 +125,24 @@ struct WatchHomeView: View {
122125

123126
@ViewBuilder
124127
private var mainContent: some View {
125-
assistButtonForOlderDevices
126128
ForEach(viewModel.watchConfig.items, id: \.serverUniqueId) { item in
127129
WatchMagicViewRow(
128130
item: item,
129131
itemInfo: viewModel.info(for: item)
130132
)
131133
}
132-
reloadButton
133134
}
134135

135-
@available(watchOS 10, *)
136-
private var reloadToolbarButton: some ToolbarContent {
137-
ToolbarItem(placement: .topBarLeading) {
138-
navReloadButton
139-
}
140-
}
141-
142-
@available(watchOS 10, *)
143-
private var assistToolbarButton: some ToolbarContent {
144-
ToolbarItem(placement: .topBarTrailing) {
145-
assistButton
146-
.modify { view in
147-
if #available(watchOS 11, *) {
148-
view.handGestureShortcut(.primaryAction)
149-
} else {
150-
view
151-
}
136+
private var assistHeaderButton: some View {
137+
assistButton
138+
.modify { view in
139+
if #available(watchOS 11, *) {
140+
view.handGestureShortcut(.primaryAction)
141+
} else {
142+
view
152143
}
153-
}
144+
}
145+
.circularGlassOrLegacyBackground()
154146
}
155147

156148
private var assistButton: some View {
@@ -169,6 +161,7 @@ struct WatchHomeView: View {
169161
color: color
170162
))
171163
})
164+
.buttonStyle(.plain)
172165
.modify { view in
173166
if #available(watchOS 26.0, *) {
174167
view
@@ -179,30 +172,19 @@ struct WatchHomeView: View {
179172
}
180173
}
181174

182-
@available(watchOS 10, *)
183175
private var navReloadButton: some View {
184176
Button {
185177
viewModel.requestConfig()
186178
} label: {
187-
Image(systemSymbol: .arrowCirclepath)
179+
Image(systemSymbol: .arrowCounterclockwise)
188180
}
181+
.buttonStyle(.plain)
182+
.circularGlassOrLegacyBackground()
189183
}
190184

191-
@available(watchOS 10, *)
192-
private var toolbarLoadingState: some ToolbarContent {
193-
ToolbarItem(placement: .bottomBar) {
194-
loadingState
195-
.modify { view in
196-
if #available(watchOS 26.0, *) {
197-
view
198-
.glassEffect(in: .circle)
199-
} else {
200-
view
201-
.padding()
202-
.background(.black)
203-
}
204-
}
205-
}
185+
private var toolbarLoadingState: some View {
186+
loadingState
187+
.circularGlassOrLegacyBackground()
206188
}
207189

208190
private var loadingState: some View {
@@ -238,35 +220,4 @@ struct WatchHomeView: View {
238220
.foregroundStyle(.secondary.opacity(0.5))
239221
}
240222
}
241-
242-
@ViewBuilder
243-
private var reloadButton: some View {
244-
// When watchOS 10 is available, reload is on toolbar
245-
if #unavailable(watchOS 10.0) {
246-
Button {
247-
viewModel.requestConfig()
248-
} label: {
249-
Group {
250-
if #available(watchOS 10.0, *) {
251-
Label(L10n.reloadLabel, systemSymbol: .arrowCirclepath)
252-
} else {
253-
Label(L10n.reloadLabel, systemSymbol: .arrowTriangle2CirclepathCircle)
254-
}
255-
}
256-
.frame(maxWidth: .infinity, alignment: .center)
257-
.font(.footnote)
258-
}
259-
.listRowBackground(Color.clear)
260-
}
261-
}
262-
263-
@ViewBuilder
264-
private var assistButtonForOlderDevices: some View {
265-
if #unavailable(watchOS 10),
266-
viewModel.watchConfig.assist.showAssist,
267-
!viewModel.watchConfig.assist.serverId.isEmpty,
268-
!viewModel.watchConfig.assist.pipelineId.isEmpty {
269-
assistButton
270-
}
271-
}
272223
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Foundation
2+
import Shared
3+
import SwiftUI
4+
5+
final class HostingController: WKHostingController<WatchHomeView> {
6+
override init() {
7+
super.init()
8+
MaterialDesignIcons.register()
9+
}
10+
11+
override var body: WatchHomeView {
12+
WatchHomeView()
13+
}
14+
}

0 commit comments

Comments
 (0)