eleven / messenger Public

mac: members sheet — don't offer un-accepted invitees; Mac-assed add button (#355)

Two fixes to "View members":
- The ADD PEOPLE list offered members who hadn't accepted their invite yet.
  Adding someone wraps the thread key to their public key, and a pending invitee
  has none — the web filters these out; now the native sheet does too.
- The "Add N to group" button was an iOS-style full-width bar in a hard-coded
  classic-light purple (wrong in dark mode and under other themes). Now a
  compact, bold push button at the sheet's bottom-right (the dialog idiom, à la
  Ivory's Post), default-action key equivalent, tinted with the user's actual
  theme accent resolved for light/dark. Invite + Rename sheets get the same
  resolved tint.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Paul Campbell 75d32f5af895a59f6a009b9d12f44e68ea8415f9 parent 1adba68
1 file changed, +48 −20
  • ios/LChatMac/GroupSheets.swift +48 −20
diff --git a/ios/LChatMac/GroupSheets.swift b/ios/LChatMac/GroupSheets.swift
index a7ba13b..7dfe6c6 100644
--- a/ios/LChatMac/GroupSheets.swift
+++ b/ios/LChatMac/GroupSheets.swift
@@ -18,7 +18,12 @@ struct MembersSheet: View {
thread.members.compactMap { id in store.roster.first { $0.user_id == id } }
}
private var others: [RosterEntry] {
- store.roster.filter { !thread.members.contains($0.user_id) && !$0.label.isEmpty }
+ // Only people who have ACCEPTED their invite: adding someone wraps the
+ // thread key to their public key, so an entry without one (invite minted,
+ // not yet redeemed) can't be added — the web applies the same filter.
+ store.roster.filter {
+ !thread.members.contains($0.user_id) && !$0.label.isEmpty && !$0.public_key.isEmpty
+ }
}
var body: some View {
@@ -49,31 +54,44 @@ struct MembersSheet: View {
Text(note).font(.system(size: 12)).foregroundStyle(.secondary)
}
if !selected.isEmpty {
- Button {
- busy = true
- Task {
- let added = await store.addMembers(thread, userIDs: Array(selected))
- busy = false
- selected = []
- note = added.isEmpty ? "Couldn't add anyone — try again."
- : "Added \(added.count)."
- }
- } label: {
- if busy {
- ProgressView().controlSize(.small).frame(maxWidth: .infinity)
- } else {
- Text("Add \(selected.count) to group").frame(maxWidth: .infinity)
+ // Mac-assed action placement: a compact, bold push button at the
+ // sheet's bottom-right (dialog idiom), not an iOS full-width bar.
+ HStack {
+ Spacer()
+ Button {
+ busy = true
+ Task {
+ let added = await store.addMembers(thread, userIDs: Array(selected))
+ busy = false
+ selected = []
+ note = added.isEmpty ? "Couldn't add anyone — try again."
+ : "Added \(added.count)."
+ }
+ } label: {
+ if busy {
+ ProgressView().controlSize(.small)
+ } else {
+ Text(selected.count == 1 ? "Add to Group" : "Add \(selected.count) to Group")
+ .fontWeight(.semibold)
+ }
}
+ .buttonStyle(.borderedProminent)
+ .keyboardShortcut(.defaultAction)
+ .disabled(busy)
}
- .buttonStyle(.borderedProminent)
- .disabled(busy)
}
}
.padding(14)
.frame(width: 300)
- .tint(ChatTheme.classic.accent.light)
+ .tint(accent)
}
+ // The user's chosen theme accent, resolved for light/dark — the hard-coded
+ // classic-light purple read as a random colour in dark mode / other themes.
+ @AppStorage("nativeTheme") private var themeName = "classic"
+ @Environment(\.colorScheme) private var scheme
+ private var accent: Color { ChatTheme.named(themeName).accent.resolved(scheme) }
+
private func row(_ person: RosterEntry, selectable: Bool) -> some View {
Button {
guard selectable else { return }
@@ -166,9 +184,14 @@ struct InviteSomeoneSheet: View {
}
.padding(14)
.frame(width: 340)
- .tint(ChatTheme.classic.accent.light)
+ .tint(accent)
}
+ // Theme accent resolved for light/dark (see MembersSheet.accent).
+ @AppStorage("nativeTheme") private var themeName = "classic"
+ @Environment(\.colorScheme) private var scheme
+ private var accent: Color { ChatTheme.named(themeName).accent.resolved(scheme) }
+
private func create() {
let trimmed = name.trimmingCharacters(in: .whitespaces)
guard !trimmed.isEmpty, !busy else { return }
@@ -209,9 +232,14 @@ struct RenameGroupSheet: View {
.padding(14)
.frame(width: 300)
.onAppear { name = thread.title }
- .tint(ChatTheme.classic.accent.light)
+ .tint(accent)
}
+ // Theme accent resolved for light/dark (see MembersSheet.accent).
+ @AppStorage("nativeTheme") private var themeName = "classic"
+ @Environment(\.colorScheme) private var scheme
+ private var accent: Color { ChatTheme.named(themeName).accent.resolved(scheme) }
+
private func save() {
let trimmed = name.trimmingCharacters(in: .whitespaces)
guard !trimmed.isEmpty else { return }