Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Flipcash/Core/Screens/Conversation/ConversationGate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ struct ConversationGate: Equatable {
/// unless it equals the viewer, so an unknown creator fails closed. Staff get no bypass: only an
/// explicit `.staff` rule looks at staff standing.
///
/// `rules` is nil for every non-group chat and for a group whose metadata hasn't
/// hydrated yet; both are open, as is an empty rule list — the contract
/// documents empty as "anyone can". `rates` is `RatesController.cachedRates`,
/// `rules` is nil for most DMs and for a group whose metadata hasn't hydrated
/// yet; both are open, as is an empty rule list — the contract documents empty
/// as "anyone can". Some DMs do carry rules (the Flipcash account's DM has a
/// `never` speaker rule), and they are evaluated the same way. `rates` is `RatesController.cachedRates`,
/// needed only to restate a requirement the server denominated in something
/// other than USD.
///
Expand Down
15 changes: 11 additions & 4 deletions Flipcash/Core/Screens/Conversation/ConversationScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,18 @@ struct ConversationScreen: View {
}

/// The chat's participation rules weighed against the signed-in user: what the bottom of the
/// screen draws, and whether the transcript is readable at all. `.open` for every DM and for a
/// group with no rules.
/// screen draws, and whether the transcript is readable at all. `.open` for a chat with no rules.
///
/// Not limited to groups: the server sends rules on some DMs too — the Flipcash account's DM
/// carries a `never` speaker rule — and a DM participant is always a member, so its speaker
/// rules close the composer the same way a group's do.
///
/// Recomputed on each observation tick rather than cached, so a balance that crosses the
/// requirement — or a rate that finally loads — opens the chat without a reopen.
private var gate: ConversationGatePresentation {
guard let conversation = groupConversation else {
guard let conversationID,
let conversation = conversationController.conversation(withID: conversationID)
else {
return awaitingMetadata ? .undetermined : .open
}
return conversationGatePresentation(gateVerdicts, isMember: conversationController.isMember(of: conversation))
Expand Down Expand Up @@ -301,7 +306,9 @@ struct ConversationScreen: View {
/// advertised listener rule (``ConversationGate/headline``) whether or not the viewer is short
/// of it, and the presentation only ever carries something unmet.
private var gateVerdicts: ConversationGate {
guard let conversation = groupConversation else { return .open }
guard let conversationID,
let conversation = conversationController.conversation(withID: conversationID)
else { return .open }
return conversationGate(
session: session,
rules: conversation.rules,
Expand Down
Loading