From a64104eaabb6bbdd6f6ecdade01b237a0aa87afb Mon Sep 17 00:00:00 2001 From: Joel Hawksley Date: Wed, 25 Feb 2026 11:05:06 -0700 Subject: [PATCH] fix navigation bug --- .../Watch/Home/MagicItemRow/WatchFolderRow.swift | 12 +----------- .../Watch/Home/WatchFolderContentView.swift | 9 --------- Sources/Extensions/Watch/Home/WatchHomeView.swift | 15 ++------------- .../Watch/Home/WatchHomeViewModel.swift | 5 ----- Sources/Shared/MagicItem/MagicItem.swift | 14 ++++++++++++++ 5 files changed, 17 insertions(+), 38 deletions(-) diff --git a/Sources/Extensions/Watch/Home/MagicItemRow/WatchFolderRow.swift b/Sources/Extensions/Watch/Home/MagicItemRow/WatchFolderRow.swift index db3c53eee..7116ad763 100644 --- a/Sources/Extensions/Watch/Home/MagicItemRow/WatchFolderRow.swift +++ b/Sources/Extensions/Watch/Home/MagicItemRow/WatchFolderRow.swift @@ -7,12 +7,8 @@ struct WatchFolderRow: View { let itemInfo: MagicItem.Info let destination: () -> Destination - @State private var isActive = false - var body: some View { - Button { - isActive = true - } label: { + NavigationLink(destination: destination) { HStack(spacing: DesignSystem.Spaces.one) { iconView Text(item.name(info: itemInfo)) @@ -26,12 +22,6 @@ struct WatchFolderRow: View { .frame(maxWidth: .infinity) } .frame(maxWidth: .infinity) - .background( - NavigationLink(isActive: $isActive, destination: destination) { - EmptyView() - } - .hidden() - ) .modify { view in if #available(watchOS 26.0, *) { if let backgroundForWatchItem { diff --git a/Sources/Extensions/Watch/Home/WatchFolderContentView.swift b/Sources/Extensions/Watch/Home/WatchFolderContentView.swift index c8d59b88e..b1e99ba98 100644 --- a/Sources/Extensions/Watch/Home/WatchFolderContentView.swift +++ b/Sources/Extensions/Watch/Home/WatchFolderContentView.swift @@ -15,14 +15,5 @@ struct WatchFolderContentView: View { } } .navigationTitle(folder.displayText ?? L10n.Watch.Configuration.Folder.defaultName) - .modify { view in - if #available(watchOS 11.0, *) { - view.toolbarVisibility(.visible, for: .navigationBar) - } else if #available(watchOS 9.0, *) { - view.toolbar(.visible, for: .navigationBar) - } else { - view.navigationBarHidden(false) - } - } } } diff --git a/Sources/Extensions/Watch/Home/WatchHomeView.swift b/Sources/Extensions/Watch/Home/WatchHomeView.swift index 0f043b5ce..bc70f8270 100644 --- a/Sources/Extensions/Watch/Home/WatchHomeView.swift +++ b/Sources/Extensions/Watch/Home/WatchHomeView.swift @@ -55,19 +55,8 @@ struct WatchHomeView: View { } // Removing the safe area so our fake navigation bar buttons (header) can be place correctly .ignoresSafeArea([.all], edges: .top) - .id(viewModel.refreshListID) .navigationTitle("") - .modify { view in - if #available(watchOS 11.0, *) { - view.toolbarVisibility(.hidden, for: .navigationBar) - } else if #available(watchOS 9.0, *) { - view - .toolbar(.hidden, for: .navigationBar) - } else { - view - .navigationBarHidden(true) - } - } + .navigationBarBackButtonHidden(true) } @ViewBuilder @@ -105,7 +94,7 @@ struct WatchHomeView: View { @ViewBuilder private var mainContent: some View { - ForEach(viewModel.watchConfig.items, id: \.serverUniqueId) { item in + ForEach(viewModel.watchConfig.items, id: \.viewIdentity) { item in if item.type == .folder { WatchFolderRow(item: item, itemInfo: viewModel.info(for: item)) { WatchFolderContentView(folder: item, viewModel: viewModel) diff --git a/Sources/Extensions/Watch/Home/WatchHomeViewModel.swift b/Sources/Extensions/Watch/Home/WatchHomeViewModel.swift index d99e5afff..c1adca6ac 100644 --- a/Sources/Extensions/Watch/Home/WatchHomeViewModel.swift +++ b/Sources/Extensions/Watch/Home/WatchHomeViewModel.swift @@ -22,10 +22,6 @@ final class WatchHomeViewModel: ObservableObject { @Published var watchConfig: WatchConfig = .init() @Published var magicItemsInfo: [MagicItem.Info] = [] - // If the watchConfig items are the same but it's customization properties - // are different, the list won't refresh. This is a workaround to force a refresh - @Published var refreshListID: UUID = .init() - @MainActor func fetchNetworkInfo() async { let networkInformation = await Current.networkInformation @@ -211,7 +207,6 @@ final class WatchHomeViewModel: ObservableObject { } else { self?.showAssist = false } - self?.refreshListID = UUID() } } diff --git a/Sources/Shared/MagicItem/MagicItem.swift b/Sources/Shared/MagicItem/MagicItem.swift index c4053ae43..82410077b 100644 --- a/Sources/Shared/MagicItem/MagicItem.swift +++ b/Sources/Shared/MagicItem/MagicItem.swift @@ -27,6 +27,20 @@ public struct MagicItem: Codable, Equatable, Hashable { "\(serverId)-\(id)" } + /// Identity string that includes customization so SwiftUI re-renders when visual properties change. + /// ``serverUniqueId`` alone is not enough because ``Equatable`` only compares id+serverId. + public var viewIdentity: String { + var parts = [serverUniqueId] + if let c = customization { + parts.append(c.iconColor ?? "") + parts.append(c.textColor ?? "") + parts.append(c.backgroundColor ?? "") + parts.append(c.icon ?? "") + } + parts.append(displayText ?? "") + return parts.joined(separator: "|") + } + /// Domain retrieved from id when item is entity else nil public var domain: Domain? { if let domainString = id.split(separator: ".").first, let domain = Domain(rawValue: String(domainString)) {