import SwiftUI import VoiceCatCore /// The drilled-into view for a single channel: a Join control, the people currently in the /// channel, and any sub-channels (each drilling deeper via a nested `ChannelDetailView`). struct ChannelDetailView: View { let channel: Channel @Bindable var session: SessionState @State private var showPasswordPrompt = false @State private var password = "" private var isCurrent: Bool { session.currentChannelId == channel.id } private var people: [User] { session.users.filter { $0.channelId == channel.id } } private var subchannels: [Channel] { session.channels.filter { $0.parentId == channel.id }.sorted { $0.name < $1.name } } var body: some View { List { Section { if isCurrent { Label("You're here", systemImage: "checkmark.circle.fill") .foregroundStyle(.green) .accessibilityLabel("You are in this channel") } else { Button { join() } label: { Label("Join Channel", systemImage: "arrow.right.circle.fill") } .accessibilityLabel("Join \(channel.name)") } } Section("People") { if people.isEmpty { Text("No one here yet.") .foregroundStyle(.secondary) } else { ForEach(people) { user in UserRow(user: user, session: session) } } } if !subchannels.isEmpty { Section("Channels") { ForEach(subchannels) { sub in NavigationLink { ChannelDetailView(channel: sub, session: session) } label: { ChannelRow(channel: sub, session: session) } .swipeActions(edge: .trailing) { if session.permissions.isAdmin { Button(role: .destructive) { session.deleteChannel(sub.id) } label: { Label("Delete", systemImage: "trash") } } } } } } } .navigationTitle(channel.name) .navigationBarTitleDisplayMode(.inline) .alert("Channel Password", isPresented: $showPasswordPrompt) { SecureField("Password", text: $password) .accessibilityLabel("Channel password") Button("Join") { session.joinChannel(channel.id, password: password) password = "" } Button("Cancel", role: .cancel) { password = "" } } } private func join() { if channel.passwordProtected { showPasswordPrompt = true } else { session.joinChannel(channel.id) } } }