feat: disable typing and message requests in open groups if you don’t have "write" permission
This commit is contained in:
parent
570883e28a
commit
30e0e40ffa
|
@ -158,6 +158,7 @@
|
|||
7BA68909272A27BE00EFC32F /* SessionCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA68908272A27BE00EFC32F /* SessionCall.swift */; };
|
||||
7BA6890D27325CCC00EFC32F /* SessionCallManager+CXCallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA6890C27325CCC00EFC32F /* SessionCallManager+CXCallController.swift */; };
|
||||
7BA6890F27325CE300EFC32F /* SessionCallManager+CXProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA6890E27325CE300EFC32F /* SessionCallManager+CXProvider.swift */; };
|
||||
7BAA7B6628D2DE4700AE1489 /* _009_OpenGroupPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAA7B6528D2DE4700AE1489 /* _009_OpenGroupPermission.swift */; };
|
||||
7BAADFCC27B0EF23007BCF92 /* CallVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAADFCB27B0EF23007BCF92 /* CallVideoView.swift */; };
|
||||
7BAADFCE27B215FE007BCF92 /* UIView+Draggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAADFCD27B215FE007BCF92 /* UIView+Draggable.swift */; };
|
||||
7BAF54CF27ACCEEC003D12F8 /* GlobalSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54CC27ACCEEC003D12F8 /* GlobalSearchViewController.swift */; };
|
||||
|
@ -166,8 +167,8 @@
|
|||
7BAF54D427ACCF01003D12F8 /* SAEScreenLockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54D227ACCF01003D12F8 /* SAEScreenLockViewController.swift */; };
|
||||
7BAF54D827ACD0E3003D12F8 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54D527ACD0E2003D12F8 /* ReusableView.swift */; };
|
||||
7BAF54DC27ACD12B003D12F8 /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54DB27ACD12B003D12F8 /* UIColor+Extensions.swift */; };
|
||||
7BBBDC462875600700747E59 /* DocumentTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */; };
|
||||
7BBBDC44286EAD2D00747E59 /* TappableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBBDC43286EAD2D00747E59 /* TappableLabel.swift */; };
|
||||
7BBBDC462875600700747E59 /* DocumentTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */; };
|
||||
7BC01A3E241F40AB00BC7C55 /* NotificationServiceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC01A3D241F40AB00BC7C55 /* NotificationServiceExtension.swift */; };
|
||||
7BC01A42241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 7BC01A3B241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
7BC707F227290ACB002817AD /* SessionCallManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC707F127290ACB002817AD /* SessionCallManager.swift */; };
|
||||
|
@ -1203,6 +1204,7 @@
|
|||
7BA68908272A27BE00EFC32F /* SessionCall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionCall.swift; sourceTree = "<group>"; };
|
||||
7BA6890C27325CCC00EFC32F /* SessionCallManager+CXCallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionCallManager+CXCallController.swift"; sourceTree = "<group>"; };
|
||||
7BA6890E27325CE300EFC32F /* SessionCallManager+CXProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionCallManager+CXProvider.swift"; sourceTree = "<group>"; };
|
||||
7BAA7B6528D2DE4700AE1489 /* _009_OpenGroupPermission.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _009_OpenGroupPermission.swift; sourceTree = "<group>"; };
|
||||
7BAADFCB27B0EF23007BCF92 /* CallVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallVideoView.swift; sourceTree = "<group>"; };
|
||||
7BAADFCD27B215FE007BCF92 /* UIView+Draggable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Draggable.swift"; sourceTree = "<group>"; };
|
||||
7BAF54CC27ACCEEC003D12F8 /* GlobalSearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalSearchViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -1211,8 +1213,8 @@
|
|||
7BAF54D227ACCF01003D12F8 /* SAEScreenLockViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SAEScreenLockViewController.swift; sourceTree = "<group>"; };
|
||||
7BAF54D527ACD0E2003D12F8 /* ReusableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReusableView.swift; sourceTree = "<group>"; };
|
||||
7BAF54DB27ACD12B003D12F8 /* UIColor+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Extensions.swift"; sourceTree = "<group>"; };
|
||||
7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentTitleViewController.swift; sourceTree = "<group>"; };
|
||||
7BBBDC43286EAD2D00747E59 /* TappableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TappableLabel.swift; sourceTree = "<group>"; };
|
||||
7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentTitleViewController.swift; sourceTree = "<group>"; };
|
||||
7BC01A3B241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SessionNotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7BC01A3D241F40AB00BC7C55 /* NotificationServiceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtension.swift; sourceTree = "<group>"; };
|
||||
7BC01A3F241F40AB00BC7C55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
|
@ -3555,6 +3557,7 @@
|
|||
FD37EA0E28AB3330003AE748 /* _006_FixHiddenModAdminSupport.swift */,
|
||||
7B81682728B310D50069F315 /* _007_HomeQueryOptimisationIndexes.swift */,
|
||||
FD09B7E4288670BB00ED0B66 /* _008_EmojiReacts.swift */,
|
||||
7BAA7B6528D2DE4700AE1489 /* _009_OpenGroupPermission.swift */,
|
||||
);
|
||||
path = Migrations;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5314,6 +5317,7 @@
|
|||
FD09799527FE7B8E00936362 /* Interaction.swift in Sources */,
|
||||
FD5C72FF284F0F120029977D /* MessageReceiver+ConfigurationMessages.swift in Sources */,
|
||||
FD37EA0D28AB2A45003AE748 /* _005_FixDeletedMessageReadState.swift in Sources */,
|
||||
7BAA7B6628D2DE4700AE1489 /* _009_OpenGroupPermission.swift in Sources */,
|
||||
FDC4380927B31D4E00C60D73 /* OpenGroupAPIError.swift in Sources */,
|
||||
FDC4382027B36ADC00C60D73 /* SOGSEndpoint.swift in Sources */,
|
||||
FDC438C927BB706500C60D73 /* SendDirectMessageRequest.swift in Sources */,
|
||||
|
|
|
@ -920,6 +920,7 @@ extension ConversationVC:
|
|||
}
|
||||
|
||||
func startThread(with sessionId: String, openGroupServer: String?, openGroupPublicKey: String?) {
|
||||
guard viewModel.threadData.canWrite else { return }
|
||||
guard SessionId.Prefix(from: sessionId) == .blinded else {
|
||||
Storage.shared.write { db in
|
||||
try SessionThread.fetchOrCreate(db, id: sessionId, variant: .contact)
|
||||
|
|
|
@ -69,10 +69,7 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers
|
|||
}
|
||||
|
||||
override var inputAccessoryView: UIView? {
|
||||
guard
|
||||
viewModel.threadData.threadVariant != .closedGroup ||
|
||||
viewModel.threadData.currentUserIsClosedGroupMember == true
|
||||
else { return nil }
|
||||
guard viewModel.threadData.canWrite else { return nil }
|
||||
|
||||
return (isShowingSearchUI ? searchController.resultsBar : snInputView)
|
||||
}
|
||||
|
@ -142,10 +139,11 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers
|
|||
result.showsVerticalScrollIndicator = false
|
||||
result.contentInsetAdjustmentBehavior = .never
|
||||
result.keyboardDismissMode = .interactive
|
||||
let bottomInset: CGFloat = viewModel.threadData.canWrite ? Values.mediumSpacing : Values.mediumSpacing + UIApplication.shared.keyWindow!.safeAreaInsets.bottom
|
||||
result.contentInset = UIEdgeInsets(
|
||||
top: 0,
|
||||
leading: 0,
|
||||
bottom: Values.mediumSpacing,
|
||||
bottom: bottomInset,
|
||||
trailing: 0
|
||||
)
|
||||
result.registerHeaderFooterView(view: UITableViewHeaderFooterView.self)
|
||||
|
|
|
@ -23,6 +23,9 @@ public enum SNMessagingKit { // Just to make the external API nice
|
|||
],
|
||||
[
|
||||
_008_EmojiReacts.self
|
||||
],
|
||||
[
|
||||
_009_OpenGroupPermission.self
|
||||
]
|
||||
]
|
||||
)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import SessionUtilitiesKit
|
||||
|
||||
enum _009_OpenGroupPermission: Migration {
|
||||
static let target: TargetMigrations.Identifier = .messagingKit
|
||||
static let identifier: String = "OpenGroupPermission"
|
||||
static let needsConfigSync: Bool = false
|
||||
static let minExpectedRunDuration: TimeInterval = 0.1
|
||||
|
||||
static func migrate(_ db: GRDB.Database) throws {
|
||||
try db.alter(table: OpenGroup.self) { t in
|
||||
t.add(.permissions, .text)
|
||||
.defaults(to: OpenGroup.Permission.all.rawValue)
|
||||
}
|
||||
|
||||
// When modifying OpenGroup behaviours we should always look to reset the `infoUpdates`
|
||||
// value for all OpenGroups to ensure they all have the correct state for newly
|
||||
// added/changed fields
|
||||
_ = try OpenGroup
|
||||
.updateAll(db, OpenGroup.Columns.infoUpdates.set(to: 0))
|
||||
|
||||
Storage.update(progress: 1, for: self, in: target) // In case this is the last migration
|
||||
}
|
||||
}
|
|
@ -27,6 +27,14 @@ public struct OpenGroup: Codable, Identifiable, FetchableRecord, PersistableReco
|
|||
case inboxLatestMessageId
|
||||
case outboxLatestMessageId
|
||||
case pollFailureCount
|
||||
case permissions
|
||||
}
|
||||
|
||||
public enum Permission: String {
|
||||
case read = "r"
|
||||
case write = "w"
|
||||
case upload = "u"
|
||||
case all = "rwu" // Convenience
|
||||
}
|
||||
|
||||
public var id: String { threadId } // Identifiable
|
||||
|
@ -90,6 +98,9 @@ public struct OpenGroup: Codable, Identifiable, FetchableRecord, PersistableReco
|
|||
/// The number of times this room has failed to poll since the last successful poll
|
||||
public let pollFailureCount: Int64
|
||||
|
||||
/// The permissions this room has for current user
|
||||
public let permissions: String?
|
||||
|
||||
// MARK: - Relationships
|
||||
|
||||
public var thread: QueryInterfaceRequest<SessionThread> {
|
||||
|
@ -122,7 +133,8 @@ public struct OpenGroup: Codable, Identifiable, FetchableRecord, PersistableReco
|
|||
sequenceNumber: Int64 = 0,
|
||||
inboxLatestMessageId: Int64 = 0,
|
||||
outboxLatestMessageId: Int64 = 0,
|
||||
pollFailureCount: Int64 = 0
|
||||
pollFailureCount: Int64 = 0,
|
||||
permissions: String? = nil
|
||||
) {
|
||||
self.threadId = OpenGroup.idFor(roomToken: roomToken, server: server)
|
||||
self.server = server.lowercased()
|
||||
|
@ -139,6 +151,7 @@ public struct OpenGroup: Codable, Identifiable, FetchableRecord, PersistableReco
|
|||
self.inboxLatestMessageId = inboxLatestMessageId
|
||||
self.outboxLatestMessageId = outboxLatestMessageId
|
||||
self.pollFailureCount = pollFailureCount
|
||||
self.permissions = permissions
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,7 +179,8 @@ public extension OpenGroup {
|
|||
sequenceNumber: 0,
|
||||
inboxLatestMessageId: 0,
|
||||
outboxLatestMessageId: 0,
|
||||
pollFailureCount: 0
|
||||
pollFailureCount: 0,
|
||||
permissions: nil
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -200,7 +214,8 @@ extension OpenGroup: CustomStringConvertible, CustomDebugStringConvertible {
|
|||
"sequenceNumber: \(sequenceNumber)",
|
||||
"inboxLatestMessageId: \(inboxLatestMessageId)",
|
||||
"outboxLatestMessageId: \(outboxLatestMessageId)",
|
||||
"pollFailureCount: \(pollFailureCount))"
|
||||
"pollFailureCount: \(pollFailureCount))",
|
||||
"permissions: \(permissions ?? "null")"
|
||||
].joined(separator: ", ")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -384,6 +384,11 @@ public final class OpenGroupManager: NSObject {
|
|||
|
||||
// Only update the database columns which have changed (this is to prevent the UI from triggering
|
||||
// updates due to changing database columns to the existing value)
|
||||
let permissions: String = ""
|
||||
.appending(pollInfo.read == true ? OpenGroup.Permission.read.rawValue : nil)
|
||||
.appending(pollInfo.write == true ? OpenGroup.Permission.write.rawValue : nil)
|
||||
.appending(pollInfo.upload == true ? OpenGroup.Permission.upload.rawValue : nil)
|
||||
|
||||
try OpenGroup
|
||||
.filter(id: openGroup.id)
|
||||
.updateAll(
|
||||
|
@ -412,6 +417,10 @@ public final class OpenGroupManager: NSObject {
|
|||
(openGroup.infoUpdates != pollInfo.details?.infoUpdates ?
|
||||
(pollInfo.details?.infoUpdates).map { OpenGroup.Columns.infoUpdates.set(to: $0) } :
|
||||
nil
|
||||
),
|
||||
(openGroup.permissions != permissions ?
|
||||
OpenGroup.Columns.permissions.set(to: permissions) :
|
||||
nil
|
||||
)
|
||||
].compactMap { $0 }
|
||||
)
|
||||
|
|
|
@ -45,6 +45,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
|
|||
public static let openGroupRoomTokenKey: SQL = SQL(stringLiteral: CodingKeys.openGroupRoomToken.stringValue)
|
||||
public static let openGroupProfilePictureDataKey: SQL = SQL(stringLiteral: CodingKeys.openGroupProfilePictureData.stringValue)
|
||||
public static let openGroupUserCountKey: SQL = SQL(stringLiteral: CodingKeys.openGroupUserCount.stringValue)
|
||||
public static let openGroupPermissionsKey: SQL = SQL(stringLiteral: CodingKeys.openGroupPermissions.stringValue)
|
||||
public static let interactionIdKey: SQL = SQL(stringLiteral: CodingKeys.interactionId.stringValue)
|
||||
public static let interactionVariantKey: SQL = SQL(stringLiteral: CodingKeys.interactionVariant.stringValue)
|
||||
public static let interactionTimestampMsKey: SQL = SQL(stringLiteral: CodingKeys.interactionTimestampMs.stringValue)
|
||||
|
@ -94,6 +95,14 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
|
|||
public let threadUnreadCount: UInt?
|
||||
public let threadUnreadMentionCount: UInt?
|
||||
|
||||
public var canWrite: Bool {
|
||||
switch threadVariant {
|
||||
case .contact: return true
|
||||
case .closedGroup: return currentUserIsClosedGroupMember == true
|
||||
case .openGroup: return openGroupPermissions?.range(of: OpenGroup.Permission.write.rawValue) != nil
|
||||
}
|
||||
}
|
||||
|
||||
// Thread display info
|
||||
|
||||
private let contactProfile: Profile?
|
||||
|
@ -109,6 +118,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
|
|||
public let openGroupRoomToken: String?
|
||||
public let openGroupProfilePictureData: Data?
|
||||
private let openGroupUserCount: Int?
|
||||
private let openGroupPermissions: String?
|
||||
|
||||
// Interaction display info
|
||||
|
||||
|
@ -262,6 +272,7 @@ public extension SessionThreadViewModel {
|
|||
self.openGroupRoomToken = nil
|
||||
self.openGroupProfilePictureData = nil
|
||||
self.openGroupUserCount = nil
|
||||
self.openGroupPermissions = nil
|
||||
|
||||
// Interaction display info
|
||||
|
||||
|
@ -320,6 +331,7 @@ public extension SessionThreadViewModel {
|
|||
openGroupRoomToken: self.openGroupRoomToken,
|
||||
openGroupProfilePictureData: self.openGroupProfilePictureData,
|
||||
openGroupUserCount: self.openGroupUserCount,
|
||||
openGroupPermissions: self.openGroupPermissions,
|
||||
interactionId: self.interactionId,
|
||||
interactionVariant: self.interactionVariant,
|
||||
interactionTimestampMs: self.interactionTimestampMs,
|
||||
|
@ -371,6 +383,7 @@ public extension SessionThreadViewModel {
|
|||
openGroupRoomToken: self.openGroupRoomToken,
|
||||
openGroupProfilePictureData: self.openGroupProfilePictureData,
|
||||
openGroupUserCount: self.openGroupUserCount,
|
||||
openGroupPermissions: self.openGroupPermissions,
|
||||
interactionId: self.interactionId,
|
||||
interactionVariant: self.interactionVariant,
|
||||
interactionTimestampMs: self.interactionTimestampMs,
|
||||
|
@ -726,6 +739,7 @@ public extension SessionThreadViewModel {
|
|||
\(openGroup[.server]) AS \(ViewModel.openGroupServerKey),
|
||||
\(openGroup[.roomToken]) AS \(ViewModel.openGroupRoomTokenKey),
|
||||
\(openGroup[.userCount]) AS \(ViewModel.openGroupUserCountKey),
|
||||
\(openGroup[.permissions]) AS \(ViewModel.openGroupPermissionsKey),
|
||||
|
||||
\(Interaction.self).\(ViewModel.interactionIdKey),
|
||||
|
||||
|
|
Loading…
Reference in New Issue