Replace PublicChatManager

This commit is contained in:
nielsandriesse 2021-01-13 16:10:06 +11:00 committed by Niels Andriesse
parent b8d9334d19
commit e38dae5a05
13 changed files with 159 additions and 246 deletions

View File

@ -295,6 +295,7 @@
B8CA011525A293800091AF73 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CA011425A293800091AF73 /* Configuration.swift */; };
B8CA011F25A2939F0091AF73 /* SharedSenderKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CA011E25A2939F0091AF73 /* SharedSenderKeys.swift */; };
B8CA014125A293EE0091AF73 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CA014025A293EE0091AF73 /* Storage.swift */; };
B8CADAE925AFADF400AAFA15 /* OpenGroupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3AAFFCB25AE92150089E6DD /* OpenGroupManager.swift */; };
B8CCF6352396005F0091D419 /* SpaceMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B8CCF6342396005F0091D419 /* SpaceMono-Regular.ttf */; };
B8CCF63723961D6D0091D419 /* NewPrivateChatVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CCF63623961D6D0091D419 /* NewPrivateChatVC.swift */; };
B8CCF63F23975CFB0091D419 /* JoinPublicChatVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CCF63E23975CFB0091D419 /* JoinPublicChatVC.swift */; };
@ -475,7 +476,6 @@
C33FDC95255A582000E217F9 /* OWSFailedMessagesJob.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDADB255A580400E217F9 /* OWSFailedMessagesJob.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC96255A582000E217F9 /* NSObject+Casting.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDADC255A580400E217F9 /* NSObject+Casting.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDC98255A582000E217F9 /* SwiftSingletons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDADE255A580400E217F9 /* SwiftSingletons.swift */; };
C33FDC99255A582000E217F9 /* PublicChatManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDADF255A580400E217F9 /* PublicChatManager.swift */; };
C33FDC9A255A582000E217F9 /* ByteParser.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAE0255A580400E217F9 /* ByteParser.m */; };
C33FDCA2255A582000E217F9 /* OWSMessageUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAE8255A580500E217F9 /* OWSMessageUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33FDCC7255A582000E217F9 /* NSArray+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB0D255A580800E217F9 /* NSArray+OWS.m */; };
@ -718,7 +718,6 @@
C3A7229C2558E4310043A11F /* OpenGroupMessage+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A7229B2558E4310043A11F /* OpenGroupMessage+Conversion.swift */; };
C3AABDDF2553ECF00042FF4C /* Array+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D12553860800C340D1 /* Array+Description.swift */; };
C3AAFFC225AE916D0089E6DD /* OpenGroupManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3AAFFC125AE916D0089E6DD /* OpenGroupManagerProtocol.swift */; };
C3AAFFD525AE92860089E6DD /* OpenGroupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3AAFFCB25AE92150089E6DD /* OpenGroupManager.swift */; };
C3AAFFE825AE975D0089E6DD /* ConfigurationMessage+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3AAFFDE25AE96FF0089E6DD /* ConfigurationMessage+Convenience.swift */; };
C3AAFFF225AE99710089E6DD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3AAFFF125AE99710089E6DD /* AppDelegate.swift */; };
C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BBE0752554CDA60050F1E3 /* Configuration.swift */; };
@ -1391,7 +1390,6 @@
C33FDADC255A580400E217F9 /* NSObject+Casting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Casting.h"; sourceTree = "<group>"; };
C33FDADD255A580400E217F9 /* TSInfoMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInfoMessage.h; sourceTree = "<group>"; };
C33FDADE255A580400E217F9 /* SwiftSingletons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSingletons.swift; sourceTree = "<group>"; };
C33FDADF255A580400E217F9 /* PublicChatManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublicChatManager.swift; sourceTree = "<group>"; };
C33FDAE0255A580400E217F9 /* ByteParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ByteParser.m; sourceTree = "<group>"; };
C33FDAE1255A580400E217F9 /* OWSReadTracking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSReadTracking.h; sourceTree = "<group>"; };
C33FDAE4255A580400E217F9 /* TSAttachmentStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAttachmentStream.h; sourceTree = "<group>"; };
@ -3118,8 +3116,6 @@
isa = PBXGroup;
children = (
C33FDB19255A580900E217F9 /* GroupUtilities.swift */,
C33FDADF255A580400E217F9 /* PublicChatManager.swift */,
C3AAFFCB25AE92150089E6DD /* OpenGroupManager.swift */,
C38EF3E5255B6DF4007E1867 /* ContactCellView.h */,
C38EF3D6255B6DEF007E1867 /* ContactCellView.m */,
C38EF3E6255B6DF4007E1867 /* ContactTableViewCell.h */,
@ -3197,6 +3193,7 @@
C3A721362558BDFA0043A11F /* OpenGroupInfo.swift */,
C3A721342558BDF90043A11F /* OpenGroupMessage.swift */,
C3A7229B2558E4310043A11F /* OpenGroupMessage+Conversion.swift */,
C3AAFFCB25AE92150089E6DD /* OpenGroupManager.swift */,
);
path = "Open Groups";
sourceTree = "<group>";
@ -4640,7 +4637,6 @@
C38EF3C3255B6DE7007E1867 /* ImageEditorTextItem.swift in Sources */,
C33FDC7D255A582000E217F9 /* OWSDispatch.m in Sources */,
C38EF247255B6D67007E1867 /* NSAttributedString+OWS.m in Sources */,
C33FDC99255A582000E217F9 /* PublicChatManager.swift in Sources */,
C33FDD49255A582000E217F9 /* ParamParser.swift in Sources */,
C38EF35F255B6DCC007E1867 /* SelectRecipientViewController.m in Sources */,
C38EF3C5255B6DE7007E1867 /* OWSViewController+ImageEditor.swift in Sources */,
@ -4709,7 +4705,6 @@
C33FDCFA255A582000E217F9 /* SignalIOSProto.swift in Sources */,
C33FDD13255A582000E217F9 /* OWSFailedAttachmentDownloadsJob.m in Sources */,
C38EF24D255B6D67007E1867 /* UIView+OWS.swift in Sources */,
C3AAFFD525AE92860089E6DD /* OpenGroupManager.swift in Sources */,
C38EF408255B6DF7007E1867 /* OWSSearchBar.m in Sources */,
C38EF327255B6DBF007E1867 /* BlockListUIUtils.m in Sources */,
C38EF310255B6DBF007E1867 /* DebugLogger.m in Sources */,
@ -4927,6 +4922,7 @@
C32C5EDC256DF501003C73A2 /* YapDatabaseConnection+OWS.m in Sources */,
C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */,
B8B32033258B235D0020074B /* Storage+Contacts.swift in Sources */,
B8CADAE925AFADF400AAFA15 /* OpenGroupManager.swift in Sources */,
B8856D69256F141F001CE70E /* OWSWindowManager.m in Sources */,
C3D9E3BE25676AD70040E4F3 /* TSAttachmentPointer.m in Sources */,
C3ECBF7B257056B700EA7FCE /* Threading.swift in Sources */,

View File

@ -395,45 +395,14 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
guard let thread = self.thread(at: indexPath.row) else { return [] }
let openGroup = Storage.shared.getOpenGroup(for: thread.uniqueId!)
let delete = UITableViewRowAction(style: .destructive, title: NSLocalizedString("TXT_DELETE_TITLE", comment: "")) { [weak self] _, _ in
var message = NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_MESSAGE", comment: "")
if let thread = thread as? TSGroupThread, thread.isClosedGroup, thread.groupModel.groupAdminIds.contains(getUserHexEncodedPublicKey()) {
message = "Because you are the creator of this group it will be deleted for everyone. This cannot be undone."
}
let alert = UIAlertController(title: NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE", comment: ""), message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("TXT_DELETE_TITLE", comment: ""), style: .destructive) { _ in
Storage.write { transaction in
Storage.shared.cancelPendingMessageSendJobs(for: thread.uniqueId!, using: transaction)
if let openGroup = openGroup {
var messageIDs: Set<String> = []
thread.enumerateInteractions(with: transaction) { interaction, _ in
messageIDs.insert(interaction.uniqueId!)
}
OWSPrimaryStorage.shared().updateMessageIDCollectionByPruningMessagesWithIDs(messageIDs, in: transaction)
transaction.removeObject(forKey: "\(openGroup.server).\(openGroup.channel)", inCollection: Storage.lastMessageServerIDCollection)
transaction.removeObject(forKey: "\(openGroup.server).\(openGroup.channel)", inCollection: Storage.lastDeletionServerIDCollection)
let _ = OpenGroupAPI.leave(openGroup.channel, on: openGroup.server)
thread.removeAllThreadInteractions(with: transaction)
thread.remove(with: transaction)
} else if let thread = thread as? TSGroupThread, thread.isClosedGroup == true {
let groupID = thread.groupModel.groupId
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
do {
try MessageSender.leave(groupPublicKey, using: transaction)
} catch {
// TODO: Handle
}
Storage.write { transaction in
thread.removeAllThreadInteractions(with: transaction)
thread.remove(with: transaction)
}
} else {
thread.removeAllThreadInteractions(with: transaction)
thread.remove(with: transaction)
}
}
NotificationCenter.default.post(name: .threadDeleted, object: nil, userInfo: [ "threadId" : thread.uniqueId! ])
alert.addAction(UIAlertAction(title: NSLocalizedString("TXT_DELETE_TITLE", comment: ""), style: .destructive) { [weak self] _ in
self?.delete(thread)
})
alert.addAction(UIAlertAction(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .default) { _ in })
guard let self = self else { return }
@ -460,6 +429,29 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
}
}
private func delete(_ thread: TSThread) {
let openGroup = Storage.shared.getOpenGroup(for: thread.uniqueId!)
Storage.write { transaction in
Storage.shared.cancelPendingMessageSendJobs(for: thread.uniqueId!, using: transaction)
if let openGroup = openGroup {
OpenGroupManager.shared.delete(openGroup, associatedWith: thread, using: transaction)
} else if let thread = thread as? TSGroupThread, thread.isClosedGroup == true {
let groupID = thread.groupModel.groupId
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
do {
try MessageSender.leave(groupPublicKey, using: transaction)
} catch {
// TODO: Handle
}
thread.removeAllThreadInteractions(with: transaction)
thread.remove(with: transaction)
} else {
thread.removeAllThreadInteractions(with: transaction)
thread.remove(with: transaction)
}
}
}
@objc private func openSettings() {
let settingsVC = SettingsVC()
let navigationController = OWSNavigationController(rootViewController: settingsVC)

View File

@ -756,10 +756,10 @@ static NSTimeInterval launchStartedAt;
- (void)startOpenGroupPollersIfNeeded
{
[LKPublicChatManager.shared startPollersIfNeeded];
[SNOpenGroupManager.shared startPolling];
}
- (void)stopOpenGroupPollers { [LKPublicChatManager.shared stopPollers]; }
- (void)stopOpenGroupPollers { [SNOpenGroupManager.shared stopPolling]; }
# pragma mark - App Mode
@ -813,7 +813,7 @@ static NSTimeInterval launchStartedAt;
[self stopPoller];
[self stopClosedGroupPoller];
[self stopOpenGroupPollers];
[LKPublicChatManager.shared stopPollers];
[SNOpenGroupManager.shared stopPolling];
BOOL wasUnlinked = [NSUserDefaults.standardUserDefaults boolForKey:@"wasUnlinked"];
[SignalApp resetAppData:^{
// Resetting the data clears the old user defaults. We need to restore the unlink default.

View File

@ -13,6 +13,7 @@ extension AppDelegate {
let job = MessageSendJob(message: configurationMessage, destination: destination)
JobQueue.shared.add(job, using: transaction)
}
userDefaults[.lastConfigurationSync] = Date()
}
func forceSyncConfigurationNowIfNeeded() -> Promise<Void> {

View File

@ -132,11 +132,9 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie
}
isJoining = true
ModalActivityIndicatorViewController.present(fromViewController: navigationController!, canCancel: false) { [weak self] _ in
Storage.shared.write { transaction in
OpenGroupManager.shared.addOpenGroup(with: urlAsString, using: transaction)
Storage.shared.write(with: { transaction in
OpenGroupManager.shared.add(with: urlAsString, using: transaction)
.done(on: DispatchQueue.main) { [weak self] _ in
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
self?.presentingViewController!.dismiss(animated: true, completion: nil)
}
.catch(on: DispatchQueue.main) { [weak self] error in
@ -150,7 +148,10 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie
self?.isJoining = false
self?.showError(title: title, message: message)
}
}
}, completion: {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
})
}
}

View File

@ -116,16 +116,6 @@ extension Storage {
(transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: server, inCollection: Storage.openGroupPublicKeyCollection)
}
// MARK: - Deletion
public func clearAllData(for group: UInt64, on server: String, using transaction: Any) {
removeLastMessageServerID(for: group, on: server, using: transaction)
removeLastDeletionServerID(for: group, on: server, using: transaction)
removeOpenGroupPublicKey(for: server, using: transaction)
}
// MARK: - Last Message Server ID

View File

@ -0,0 +1,96 @@
import PromiseKit
@objc(SNOpenGroupManager)
public final class OpenGroupManager : NSObject, OpenGroupManagerProtocol {
private var pollers: [String:OpenGroupPoller] = [:]
private var isPolling = false
// MARK: Error
public enum Error : LocalizedError {
case invalidURL
public var errorDescription: String? {
switch self {
case .invalidURL: return "Invalid URL."
}
}
}
// MARK: Initialization
@objc public static let shared = OpenGroupManager()
private override init() { }
// MARK: Polling
@objc public func startPolling() {
guard !isPolling else { return }
isPolling = true
let openGroups = Storage.shared.getAllUserOpenGroups()
for (_, openGroup) in openGroups {
if let poller = pollers[openGroup.id] { poller.stop() } // Should never occur
let poller = OpenGroupPoller(for: openGroup)
poller.startIfNeeded()
pollers[openGroup.id] = poller
}
}
@objc public func stopPolling() {
pollers.forEach { (_, openGroupPoller) in openGroupPoller.stop() }
pollers.removeAll()
}
// MARK: Adding & Removing
public func add(with url: String, using transaction: Any) -> Promise<Void> {
guard let url = URL(string: url), let scheme = url.scheme, scheme == "https", url.host != nil else {
return Promise(error: Error.invalidURL)
}
let channel: UInt64 = 1
let server = url.absoluteString
let userPublicKey = getUserHexEncodedPublicKey()
let profileManager = SSKEnvironment.shared.profileManager
let displayName = profileManager.profileNameForRecipient(withID: userPublicKey)
let profilePictureURL = profileManager.profilePictureURL()
let profileKey = profileManager.localProfileKey().keyData
Storage.shared.removeLastMessageServerID(for: channel, on: server, using: transaction)
Storage.shared.removeLastDeletionServerID(for: channel, on: server, using: transaction)
return OpenGroupAPI.getInfo(for: channel, on: server).done { info in
let openGroup = OpenGroup(channel: channel, server: server, displayName: info.displayName, isDeletable: true)!
let groupID = LKGroupUtilities.getEncodedOpenGroupIDAsData(openGroup.id)
let model = TSGroupModel(title: openGroup.displayName, memberIds: [ userPublicKey ], image: nil, groupId: groupID, groupType: .openGroup, adminIds: [])
Storage.shared.write(with: { transaction in
let thread = TSGroupThread.getOrCreateThread(with: model, transaction: transaction as! YapDatabaseReadWriteTransaction)
Storage.shared.setOpenGroup(openGroup, for: thread.uniqueId!, using: transaction)
}, completion: {
let _ = OpenGroupAPI.setDisplayName(to: displayName, on: server)
let _ = OpenGroupAPI.setProfilePictureURL(to: profilePictureURL, using: profileKey, on: server)
let _ = OpenGroupAPI.join(channel, on: server)
if let poller = OpenGroupManager.shared.pollers[openGroup.id] {
poller.stop()
OpenGroupManager.shared.pollers[openGroup.id] = nil
}
let poller = OpenGroupPoller(for: openGroup)
poller.startIfNeeded()
OpenGroupManager.shared.pollers[openGroup.id] = poller
})
}
}
public func delete(_ openGroup: OpenGroup, associatedWith thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) {
if let poller = pollers[openGroup.id] {
poller.stop()
pollers[openGroup.id] = nil
}
var messageIDs: Set<String> = []
thread.enumerateInteractions(with: transaction) { interaction, _ in
messageIDs.insert(interaction.uniqueId!)
}
SNMessagingKitConfiguration.shared.storage.updateMessageIDCollectionByPruningMessagesWithIDs(messageIDs, using: transaction)
Storage.shared.removeLastMessageServerID(for: openGroup.channel, on: openGroup.server, using: transaction)
Storage.shared.removeLastDeletionServerID(for: openGroup.channel, on: openGroup.server, using: transaction)
let _ = OpenGroupAPI.leave(openGroup.channel, on: openGroup.server)
Storage.shared.removeOpenGroupPublicKey(for: openGroup.server, using: transaction)
thread.removeAllThreadInteractions(with: transaction)
thread.remove(with: transaction)
Storage.shared.removeOpenGroup(for: thread.uniqueId!, using: transaction)
}
}

View File

@ -2,5 +2,5 @@ import PromiseKit
public protocol OpenGroupManagerProtocol {
func addOpenGroup(with url: String, using transaction: Any) -> Promise<Void>
func add(with url: String, using transaction: Any) -> Promise<Void>
}

View File

@ -92,22 +92,6 @@ extension MessageReceiver {
}
}
private static func handleConfigurationMessage(_ message: ConfigurationMessage, using transaction: Any) {
guard message.sender == getUserHexEncodedPublicKey() else { return }
let storage = SNMessagingKitConfiguration.shared.storage
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
for closedGroup in message.closedGroups {
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair,
members: [String](closedGroup.members), admins: [String](closedGroup.admins), using: transaction)
}
let allOpenGroups = Set(storage.getAllUserOpenGroups().keys)
for openGroupURL in message.openGroups {
guard !allOpenGroups.contains(openGroupURL) else { continue }
SNMessagingKitConfiguration.shared.openGroupManager.addOpenGroup(with: openGroupURL, using: transaction).retainUntilComplete()
}
}
public static func setExpirationTimer(to duration: UInt32, for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
let transaction = transaction as! YapDatabaseReadWriteTransaction
var isGroup = false
@ -151,6 +135,22 @@ extension MessageReceiver {
message.save(with: transaction)
SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary()
}
private static func handleConfigurationMessage(_ message: ConfigurationMessage, using transaction: Any) {
guard message.sender == getUserHexEncodedPublicKey() else { return }
let storage = SNMessagingKitConfiguration.shared.storage
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
for closedGroup in message.closedGroups {
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair,
members: [String](closedGroup.members), admins: [String](closedGroup.admins), using: transaction)
}
let allOpenGroups = Set(storage.getAllUserOpenGroups().keys)
for openGroupURL in message.openGroups {
guard !allOpenGroups.contains(openGroupURL) else { continue }
SNMessagingKitConfiguration.shared.openGroupManager.add(with: openGroupURL, using: transaction).retainUntilComplete()
}
}
@discardableResult
public static func handleVisibleMessage(_ message: VisibleMessage, associatedWithProto proto: SNProtoContent, openGroupID: String?, isBackgroundPoll: Bool, using transaction: Any) throws -> String {

View File

@ -53,6 +53,7 @@ public protocol SessionMessagingKitStorageProtocol {
func getAllUserOpenGroups() -> [String:OpenGroup]
func getOpenGroup(for threadID: String) -> OpenGroup?
func getThreadID(for openGroupID: String) -> String?
func updateMessageIDCollectionByPruningMessagesWithIDs(_ messageIDs: Set<String>, using transaction: Any)
// MARK: - Open Group Public Keys

View File

@ -1,2 +1,8 @@
extension Storage : SessionMessagingKitStorageProtocol, SessionProtocolKitStorageProtocol, SessionSnodeKitStorageProtocol { }
extension Storage : SessionMessagingKitStorageProtocol, SessionProtocolKitStorageProtocol, SessionSnodeKitStorageProtocol {
public func updateMessageIDCollectionByPruningMessagesWithIDs(_ messageIDs: Set<String>, using transaction: Any) {
let transaction = transaction as! YapDatabaseReadWriteTransaction
OWSPrimaryStorage.shared().updateMessageIDCollectionByPruningMessagesWithIDs(messageIDs, in: transaction)
}
}

View File

@ -1,39 +0,0 @@
import PromiseKit
public final class OpenGroupManager : OpenGroupManagerProtocol {
public enum Error : LocalizedError {
case invalidURL
public var errorDescription: String? {
switch self {
case .invalidURL: return "Invalid URL."
}
}
}
public static let shared = OpenGroupManager()
private init() { }
public func addOpenGroup(with url: String, using transaction: Any) -> Promise<Void> {
guard let url = URL(string: url), let scheme = url.scheme, scheme == "https", url.host != nil else {
return Promise(error: Error.invalidURL)
}
let channelID: UInt64 = 1
let urlAsString = url.absoluteString
let userPublicKey = getUserHexEncodedPublicKey()
let profileManager = OWSProfileManager.shared()
let displayName = profileManager.profileNameForRecipient(withID: userPublicKey)
let profilePictureURL = profileManager.profilePictureURL()
let profileKey = profileManager.localProfileKey().keyData
let transaction = transaction as! YapDatabaseReadWriteTransaction
transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: Storage.lastMessageServerIDCollection)
transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: Storage.lastDeletionServerIDCollection)
return PublicChatManager.shared.addChat(server: urlAsString, channel: channelID).done(on: DispatchQueue.main) { _ in
let _ = OpenGroupAPI.setDisplayName(to: displayName, on: urlAsString)
let _ = OpenGroupAPI.setProfilePictureURL(to: profilePictureURL, using: profileKey, on: urlAsString)
let _ = OpenGroupAPI.join(channelID, on: urlAsString)
}
}
}

View File

@ -1,131 +0,0 @@
import PromiseKit
// TODO: Clean
@objc(LKPublicChatManager)
public final class PublicChatManager : NSObject {
private let storage = OWSPrimaryStorage.shared()
@objc public var chats: [String:OpenGroup] = [:]
private var pollers: [String:OpenGroupPoller] = [:]
private var isPolling = false
private var userHexEncodedPublicKey: String? {
return OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey
}
public enum Error : Swift.Error {
case chatCreationFailed
case userPublicKeyNotFound
}
@objc public static let shared = PublicChatManager()
private override init() {
super.init()
NotificationCenter.default.addObserver(self, selector: #selector(onThreadDeleted(_:)), name: .threadDeleted, object: nil)
refreshChatsAndPollers()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc public func startPollersIfNeeded() {
for (threadID, publicChat) in chats {
if let poller = pollers[threadID] {
poller.startIfNeeded()
} else {
let poller = OpenGroupPoller(for: publicChat)
poller.startIfNeeded()
pollers[threadID] = poller
}
}
isPolling = true
}
@objc public func stopPollers() {
for poller in pollers.values { poller.stop() }
isPolling = false
}
public func addChat(server: String, channel: UInt64) -> Promise<OpenGroup> {
if let existingChat = getChat(server: server, channel: channel) {
if let newChat = self.addChat(server: server, channel: channel, name: existingChat.displayName) {
return Promise.value(newChat)
} else {
return Promise(error: Error.chatCreationFailed)
}
}
return OpenGroupAPI.getInfo(for: channel, on: server).map2 { channelInfo -> OpenGroup in
guard let chat = self.addChat(server: server, channel: channel, name: channelInfo.displayName) else { throw Error.chatCreationFailed }
return chat
}
}
@discardableResult
@objc(addChatWithServer:channel:name:)
public func addChat(server: String, channel: UInt64, name: String) -> OpenGroup? {
guard let chat = OpenGroup(channel: channel, server: server, displayName: name, isDeletable: true) else { return nil }
let model = TSGroupModel(title: chat.displayName, memberIds: [userHexEncodedPublicKey!, chat.server], image: nil, groupId: LKGroupUtilities.getEncodedOpenGroupIDAsData(chat.id), groupType: .openGroup, adminIds: [])
// Store the group chat mapping
Storage.writeSync { transaction in
let thread = TSGroupThread.getOrCreateThread(with: model, transaction: transaction)
// Save the group chat
Storage.shared.setOpenGroup(chat, for: thread.uniqueId!, using: transaction)
}
// Update chats and pollers
self.refreshChatsAndPollers()
return chat
}
@objc(addChatWithServer:channel:)
public func objc_addChat(server: String, channel: UInt64) -> AnyPromise {
return AnyPromise.from(addChat(server: server, channel: channel))
}
@objc func refreshChatsAndPollers() {
let newChats = Storage.shared.getAllUserOpenGroups()
// Remove any chats that don't exist in the database
let removedChatThreadIds = self.chats.keys.filter { !newChats.keys.contains($0) }
removedChatThreadIds.forEach { threadID in
let poller = self.pollers.removeValue(forKey: threadID)
poller?.stop()
}
// Only append to chats if we have a thread for the chat
self.chats = newChats.filter { (threadID, group) in
return TSGroupThread.fetch(uniqueId: threadID) != nil
}
if (isPolling) { startPollersIfNeeded() }
}
@objc private func onThreadDeleted(_ notification: Notification) {
guard let threadId = notification.userInfo?["threadId"] as? String else { return }
// Reset the last message cache
if let chat = self.chats[threadId] {
Storage.write { transaction in
Storage.shared.clearAllData(for: chat.channel, on: chat.server, using: transaction)
}
}
// Remove the chat from the db
Storage.write { transaction in
Storage.shared.removeOpenGroup(for: threadId, using: transaction)
}
refreshChatsAndPollers()
}
public func getChat(server: String, channel: UInt64) -> OpenGroup? {
return chats.values.first { chat in
return chat.server == server && chat.channel == channel
}
}
}