diff --git a/Packages/App/Sources/AppUIMain/Views/App/ProfileRowView.swift b/Packages/App/Sources/AppUIMain/Views/App/ProfileRowView.swift index 2da78bf59..036b74a5d 100644 --- a/Packages/App/Sources/AppUIMain/Views/App/ProfileRowView.swift +++ b/Packages/App/Sources/AppUIMain/Views/App/ProfileRowView.swift @@ -121,6 +121,10 @@ private struct MarkerView: View { ZStack { ThemeImage(profileId == nextProfileId ? .pending : tunnel.statusImageName) .opaque(requiredFeatures == nil && (profileId == nextProfileId || profileId == tunnel.currentProfile?.id)) + + if let requiredFeatures { + PurchaseRequiredView(features: requiredFeatures) + } } .frame(width: 24) } diff --git a/Packages/App/Sources/AppUIMain/Views/Profile/macOS/ModuleListView+macOS.swift b/Packages/App/Sources/AppUIMain/Views/Profile/macOS/ModuleListView+macOS.swift index 149a3b2bd..bd72a5284 100644 --- a/Packages/App/Sources/AppUIMain/Views/Profile/macOS/ModuleListView+macOS.swift +++ b/Packages/App/Sources/AppUIMain/Views/Profile/macOS/ModuleListView+macOS.swift @@ -51,8 +51,13 @@ struct ModuleListView: View, Routable { var body: some View { List(selection: $selectedModuleId) { Section { - NavigationLink(Strings.Global.Nouns.general, value: ProfileSplitView.Detail.general) - .tag(Self.generalModuleId) + NavigationLink(value: ProfileSplitView.Detail.general) { + HStack { + Text(Strings.Global.Nouns.general) + PurchaseRequiredView(features: requiredGeneralFeatures) + } + } + .tag(Self.generalModuleId) } Group { ForEach(profileEditor.modules, id: \.id) { module in @@ -116,6 +121,17 @@ private extension ModuleListView { } private extension ModuleListView { + var requiredGeneralFeatures: Set { + var features: Set = [] + if profileEditor.isShared { + features.insert(.sharing) + } + if profileEditor.isAvailableForTV { + features.insert(.appleTV) + } + return features + } + func moveModules(from offsets: IndexSet, to newOffset: Int) { profileEditor.moveModules(from: offsets, to: newOffset) // XXX: selection is lost after move, reset as a workaround