- Channels tab is now a drill-down on iPhone: ChannelBrowserView lists top-level
channels; ChannelDetailView shows the people in a channel, its sub-channels, and
an explicit Join button (with password prompt). iPad split view unchanged.
- Extract self-contained UserRow (context menu + sheets) from UserListView so admin
actions are reused in the drill-down.
- Fix off-screen chat compose box: pin VoiceControlsView via per-tab
.safeAreaInset(edge: .bottom) instead of a floating overlay, so it reserves layout
space above the tab bar (keeping the compose box visible, cooperating with keyboard
avoidance) without covering the tab bar buttons.
- Collapse Activity into Chat like macOS/Windows: ChatView renders a merged,
time-sorted timeline of messages + activity (activity rows in gray); remove the
Activity tab and ActivityLogView.
- Label the RPSystemBroadcastPickerView inner UIButton for VoiceOver
("Share/Stop sharing screen audio") instead of relying on an outer SwiftUI label.
27 lines
777 B
Swift
27 lines
777 B
Swift
import SwiftUI
|
|
import VoiceCatCore
|
|
|
|
struct UserListView: View {
|
|
@Bindable var session: SessionState
|
|
|
|
var body: some View {
|
|
let channelUsers = session.currentChannelId == 0
|
|
? session.users
|
|
: session.users.filter { $0.channelId == session.currentChannelId }
|
|
|
|
List(channelUsers) { user in
|
|
UserRow(user: user, session: session)
|
|
}
|
|
.listStyle(.plain)
|
|
.overlay {
|
|
if channelUsers.isEmpty {
|
|
ContentUnavailableView(
|
|
"No Users",
|
|
systemImage: "person.slash",
|
|
description: Text(session.currentChannelId == 0 ? "Join a channel to see users." : "No one else here yet.")
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|