feat(sharing): hidden-profile toggle + hide non-sharing group members
- UserProfile decodes directory_hidden; updateProfile() sends it; Settings has a "hide my profile" toggle (excludes you from share/group pickers). - GroupMember decodes shares_calendar; the group filter list now only shows members who actually share a calendar (no phantom empty rows). - Robust custom decoders (decodeIfPresent) for the new fields. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -217,7 +217,9 @@ struct CalendarFilterSheet: View {
|
||||
if let g = groupDetail {
|
||||
List {
|
||||
Section(header: Label(g.name, systemImage: GroupIcons.symbol(g.icon))) {
|
||||
ForEach(g.members ?? []) { m in
|
||||
// Only members who actually share a calendar into the group —
|
||||
// avoids phantom empty rows for members who share nothing.
|
||||
ForEach((g.members ?? []).filter { $0.sharesCalendar }) { m in
|
||||
groupRow(name: m.displayName ?? "—",
|
||||
colorHex: m.color ?? "#4285f4",
|
||||
key: CalendarStore.groupMemberKey(m.id))
|
||||
|
||||
@@ -32,6 +32,7 @@ struct SettingsView: View {
|
||||
@State private var privateVisibility = "busy"
|
||||
@State private var groupVisibleId = 0 // 0 = none
|
||||
@State private var ownLocalCals: [LocalCalendar] = []
|
||||
@State private var directoryHidden = false
|
||||
@State private var profileMsg = ""
|
||||
|
||||
var body: some View {
|
||||
@@ -102,6 +103,13 @@ struct SettingsView: View {
|
||||
.keyboardType(.emailAddress)
|
||||
.autocapitalization(.none)
|
||||
}
|
||||
Toggle(isOn: $directoryHidden) {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(L10n.t("settings.directory_hidden", appLang))
|
||||
Text(L10n.t("settings.directory_hidden.desc", appLang))
|
||||
.font(.caption).foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
Button(L10n.t("event.save", appLang)) { Task { await saveProfile() } }
|
||||
if !profileMsg.isEmpty {
|
||||
Text(profileMsg).font(.caption).foregroundStyle(.secondary)
|
||||
@@ -188,6 +196,7 @@ struct SettingsView: View {
|
||||
displayName = p.displayName ?? p.username
|
||||
loginName = p.username
|
||||
email = p.email ?? ""
|
||||
directoryHidden = p.directoryHidden
|
||||
}
|
||||
if let s = try? await api.getSettings() {
|
||||
privateVisibility = s.privateEventVisibility
|
||||
@@ -202,7 +211,8 @@ struct SettingsView: View {
|
||||
do {
|
||||
_ = try await api.updateProfile(displayName: displayName.isEmpty ? nil : displayName,
|
||||
username: nil,
|
||||
email: email.isEmpty ? "" : email)
|
||||
email: email.isEmpty ? "" : email,
|
||||
directoryHidden: directoryHidden)
|
||||
UserDefaults.standard.set(displayName, forKey: "displayName")
|
||||
profileMsg = L10n.t("settings.saved", appLang)
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user