mirror of
https://github.com/yattee/yattee.git
synced 2026-10-30 08:27:17 +00:00
Let Subscribe On know its memberships and refuse a doomed destination
MAC5: membership lives in an observable loader started from ChannelView's task, outside the NSMenu content SwiftUI never runs lifecycle for; rows are Toggles so the mark renders on macOS, and writes toast Subscribed or Unsubscribed with the destination name. MAC13: a destination whose context fails validation is disabled, the same gate the plain Subscribe button uses.
This commit is contained in:
@@ -34,6 +34,10 @@ struct ChannelView: View {
|
||||
/// previous one is dropped instead of answering for the channel on screen.
|
||||
@State private var subscriptionGeneration = 0
|
||||
@State private var showingUnsubscribeConfirmation = false
|
||||
/// What the destination rows know, kept here rather than inside the menu:
|
||||
/// nothing in a platform menu's content is ever given a lifecycle to load
|
||||
/// from.
|
||||
@State private var destinationMembership = SubscriptionDestinationMembershipLoader()
|
||||
#if os(tvOS)
|
||||
@State private var showingSubscriptionDestinations = false
|
||||
#endif
|
||||
@@ -192,6 +196,15 @@ struct ChannelView: View {
|
||||
.task {
|
||||
await loadChannel()
|
||||
}
|
||||
// Asked for here, where the answers arrive before the menu is built:
|
||||
// the rows themselves live inside a platform menu, which runs no
|
||||
// lifecycle of its own, and a mark that is not known by the time the
|
||||
// menu opens is a mark the user never sees.
|
||||
.task(id: channelToSubscribe?.id) {
|
||||
guard let channelToSubscribe,
|
||||
SubscriptionDestinations.areOffered(in: appEnvironment) else { return }
|
||||
await destinationMembership.load(for: channelToSubscribe, in: appEnvironment)
|
||||
}
|
||||
.onAppear {
|
||||
// Update Handoff activity for this specific channel
|
||||
appEnvironment?.handoffManager.updateActivity(for: .channel(channelID, source))
|
||||
@@ -825,7 +838,10 @@ struct ChannelView: View {
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.fullScreenCover(isPresented: $showingSubscriptionDestinations) {
|
||||
SubscriptionDestinationPicker(channel: channelToSubscribe) { context, subscribed in
|
||||
SubscriptionDestinationPicker(
|
||||
channel: channelToSubscribe,
|
||||
membership: destinationMembership
|
||||
) { context, subscribed in
|
||||
destinationDidToggle(context, subscribed: subscribed)
|
||||
}
|
||||
}
|
||||
@@ -1249,7 +1265,10 @@ struct ChannelView: View {
|
||||
// never presented there.
|
||||
#if !os(tvOS)
|
||||
if let channelToSubscribe {
|
||||
SubscriptionDestinationMenu(channel: channelToSubscribe) { context, subscribed in
|
||||
SubscriptionDestinationMenu(
|
||||
channel: channelToSubscribe,
|
||||
membership: destinationMembership
|
||||
) { context, subscribed in
|
||||
destinationDidToggle(context, subscribed: subscribed)
|
||||
}
|
||||
}
|
||||
@@ -1275,6 +1294,7 @@ struct ChannelView: View {
|
||||
} label: {
|
||||
Image(systemName: channelMenuIcon)
|
||||
}
|
||||
.accessibilityLabel(Text(String(localized: "channel.menu.title")))
|
||||
}
|
||||
|
||||
// MARK: - Subscription Actions
|
||||
|
||||
Reference in New Issue
Block a user