Include profile in configuration sync message
This commit is contained in:
parent
d532badd09
commit
e945a6779f
|
@ -126,7 +126,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
view.addSubview(messagesTableView)
|
||||
messagesTableView.pin(to: view)
|
||||
view.addSubview(scrollButton)
|
||||
scrollButton.pin(.right, to: .right, of: view, withInset: -22)
|
||||
scrollButton.pin(.right, to: .right, of: view, withInset: -16)
|
||||
// Blocked banner
|
||||
addOrRemoveBlockedBanner()
|
||||
// Notifications
|
||||
|
@ -207,7 +207,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
guard let newHeight = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size.height else { return }
|
||||
if !didConstrainScrollButton {
|
||||
// Bit of a hack to do this here, but it works out.
|
||||
scrollButton.pin(.bottom, to: .bottom, of: view, withInset: -(newHeight + 22))
|
||||
scrollButton.pin(.bottom, to: .bottom, of: view, withInset: -(newHeight + 16))
|
||||
didConstrainScrollButton = true
|
||||
}
|
||||
UIView.animate(withDuration: 0.25) {
|
||||
|
|
|
@ -104,7 +104,7 @@ final class InputView : UIView, InputViewButtonDelegate, InputTextViewDelegate,
|
|||
mainStackView.axis = .vertical
|
||||
mainStackView.isLayoutMarginsRelativeArrangement = true
|
||||
let adjustment = (InputViewButton.expandedSize - InputViewButton.size) / 2
|
||||
mainStackView.layoutMargins = UIEdgeInsets(top: Values.smallSpacing, leading: Values.largeSpacing, bottom: Values.smallSpacing, trailing: Values.largeSpacing - adjustment)
|
||||
mainStackView.layoutMargins = UIEdgeInsets(top: 2, leading: Values.mediumSpacing, bottom: 2, trailing: Values.mediumSpacing - adjustment)
|
||||
addSubview(mainStackView)
|
||||
mainStackView.pin(.top, to: .bottom, of: separator)
|
||||
mainStackView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing ], to: self)
|
||||
|
|
|
@ -46,6 +46,9 @@ final class InputViewButton : UIView {
|
|||
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
|
||||
addSubview(blurView)
|
||||
blurView.pin(to: self)
|
||||
layer.borderWidth = Values.separatorThickness
|
||||
let borderColor = (isLightMode ? UIColor.black : UIColor.white).withAlphaComponent(Values.veryLowOpacity)
|
||||
layer.borderColor = borderColor.cgColor
|
||||
}
|
||||
backgroundView.backgroundColor = isSendButton ? Colors.accent : Colors.text.withAlphaComponent(0.05)
|
||||
addSubview(backgroundView)
|
||||
|
|
|
@ -38,7 +38,7 @@ final class ScrollToBottomButton : UIView {
|
|||
layer.cornerRadius = size / 2
|
||||
layer.masksToBounds = true
|
||||
// Border
|
||||
layer.borderWidth = 1
|
||||
layer.borderWidth = Values.separatorThickness
|
||||
let borderColor = (isLightMode ? UIColor.black : UIColor.white).withAlphaComponent(Values.veryLowOpacity)
|
||||
layer.borderColor = borderColor.cgColor
|
||||
// Icon
|
||||
|
|
|
@ -35,7 +35,7 @@ final class LinkDeviceVC : BaseVC, UIPageViewControllerDataSource, UIPageViewCon
|
|||
}()
|
||||
|
||||
private lazy var scanQRCodeWrapperVC: ScanQRCodeWrapperVC = {
|
||||
let message = "Bla bla foo bar"
|
||||
let message = "Navigate to Settings → Recovery Phrase on your other device to show your QR code."
|
||||
let result = ScanQRCodeWrapperVC(message: message)
|
||||
result.delegate = self
|
||||
return result
|
||||
|
@ -117,7 +117,8 @@ final class LinkDeviceVC : BaseVC, UIPageViewControllerDataSource, UIPageViewCon
|
|||
}
|
||||
|
||||
func controller(_ controller: OWSQRCodeScanningViewController, didDetectQRCodeWith string: String) {
|
||||
print(string)
|
||||
guard let seed = string.data(using: .utf8) else { return }
|
||||
continueWithSeed(seed)
|
||||
}
|
||||
|
||||
func continueWithSeed(_ seed: Data) {
|
||||
|
@ -126,11 +127,7 @@ final class LinkDeviceVC : BaseVC, UIPageViewControllerDataSource, UIPageViewCon
|
|||
TSAccountManager.sharedInstance().phoneNumberAwaitingVerification = x25519KeyPair.hexEncodedPublicKey
|
||||
OWSPrimaryStorage.shared().setRestorationTime(Date().timeIntervalSince1970)
|
||||
UserDefaults.standard[.hasViewedSeed] = true
|
||||
UserDefaults.standard[.isUsingFullAPNs] = true // TODO: Get this from the sync message or show the PN mode screen
|
||||
TSAccountManager.sharedInstance().didRegister()
|
||||
let syncTokensJob = SyncPushTokensJob(accountManager: AppEnvironment.shared.accountManager, preferences: Environment.shared.preferences)
|
||||
syncTokensJob.uploadOnlyIfStale = false
|
||||
let _: Promise<Void> = syncTokensJob.run()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleConfigurationMessageReceived), name: .configurationMessageReceived, object: nil)
|
||||
ModalActivityIndicatorViewController.present(fromViewController: navigationController!) { [weak self] modal in
|
||||
self?.activityIndicatorModal = modal
|
||||
|
@ -138,7 +135,12 @@ final class LinkDeviceVC : BaseVC, UIPageViewControllerDataSource, UIPageViewCon
|
|||
}
|
||||
|
||||
@objc private func handleConfigurationMessageReceived() {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.navigationController!.dismiss(animated: true) {
|
||||
let pnModeVC = PNModeVC()
|
||||
self.navigationController!.setViewControllers([ pnModeVC ], animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ extension AppDelegate {
|
|||
|
||||
@objc(syncConfigurationIfNeeded)
|
||||
func syncConfigurationIfNeeded() {
|
||||
guard Storage.shared.getUserDisplayName() != nil else { return }
|
||||
let userDefaults = UserDefaults.standard
|
||||
let lastSync = userDefaults[.lastConfigurationSync] ?? .distantPast
|
||||
guard Date().timeIntervalSince(lastSync) > 2 * 24 * 60 * 60 else { return } // Sync every 2 days
|
||||
|
@ -17,6 +18,7 @@ extension AppDelegate {
|
|||
}
|
||||
|
||||
func forceSyncConfigurationNowIfNeeded() -> Promise<Void> {
|
||||
guard Storage.shared.getUserDisplayName() != nil else { return Promise.value(()) }
|
||||
let configurationMessage = ConfigurationMessage.getCurrent()
|
||||
let destination = Message.Destination.contact(publicKey: getUserHexEncodedPublicKey())
|
||||
let (promise, seal) = Promise<Void>.pending()
|
||||
|
|
|
@ -4,16 +4,28 @@ import SessionUtilitiesKit
|
|||
public final class ConfigurationMessage : ControlMessage {
|
||||
public var closedGroups: Set<ClosedGroup> = []
|
||||
public var openGroups: Set<String> = []
|
||||
public var displayName: String?
|
||||
public var profilePictureURL: String?
|
||||
public var profileKey: Data?
|
||||
|
||||
public override var ttl: UInt64 { 4 * 24 * 60 * 60 * 1000 }
|
||||
|
||||
public override var isSelfSendValid: Bool { true }
|
||||
|
||||
// MARK: Validation
|
||||
public override var isValid: Bool {
|
||||
guard displayName != nil else { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: Initialization
|
||||
public override init() { super.init() }
|
||||
|
||||
public init(closedGroups: Set<ClosedGroup>, openGroups: Set<String>) {
|
||||
public init(displayName: String, profilePictureURL: String?, profileKey: Data?, closedGroups: Set<ClosedGroup>, openGroups: Set<String>) {
|
||||
super.init()
|
||||
self.displayName = displayName
|
||||
self.profilePictureURL = profilePictureURL
|
||||
self.profileKey = profileKey
|
||||
self.closedGroups = closedGroups
|
||||
self.openGroups = openGroups
|
||||
}
|
||||
|
@ -23,24 +35,36 @@ public final class ConfigurationMessage : ControlMessage {
|
|||
super.init(coder: coder)
|
||||
if let closedGroups = coder.decodeObject(forKey: "closedGroups") as! Set<ClosedGroup>? { self.closedGroups = closedGroups }
|
||||
if let openGroups = coder.decodeObject(forKey: "openGroups") as! Set<String>? { self.openGroups = openGroups }
|
||||
if let displayName = coder.decodeObject(forKey: "displayName") as! String? { self.displayName = displayName }
|
||||
if let profilePictureURL = coder.decodeObject(forKey: "profilePictureURL") as! String? { self.profilePictureURL = profilePictureURL }
|
||||
if let profileKey = coder.decodeObject(forKey: "profileKey") as! Data? { self.profileKey = profileKey }
|
||||
}
|
||||
|
||||
public override func encode(with coder: NSCoder) {
|
||||
super.encode(with: coder)
|
||||
coder.encode(closedGroups, forKey: "closedGroups")
|
||||
coder.encode(openGroups, forKey: "openGroups")
|
||||
coder.encode(displayName, forKey: "displayName")
|
||||
coder.encode(profilePictureURL, forKey: "profilePictureURL")
|
||||
coder.encode(profileKey, forKey: "profileKey")
|
||||
}
|
||||
|
||||
// MARK: Proto Conversion
|
||||
public override class func fromProto(_ proto: SNProtoContent) -> ConfigurationMessage? {
|
||||
guard let configurationProto = proto.configurationMessage else { return nil }
|
||||
let displayName = configurationProto.displayName
|
||||
let profilePictureURL = configurationProto.profilePicture
|
||||
let profileKey = configurationProto.profileKey
|
||||
let closedGroups = Set(configurationProto.closedGroups.compactMap { ClosedGroup.fromProto($0) })
|
||||
let openGroups = Set(configurationProto.openGroups)
|
||||
return ConfigurationMessage(closedGroups: closedGroups, openGroups: openGroups)
|
||||
return ConfigurationMessage(displayName: displayName, profilePictureURL: profilePictureURL, profileKey: profileKey, closedGroups: closedGroups, openGroups: openGroups)
|
||||
}
|
||||
|
||||
public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
|
||||
let configurationProto = SNProtoConfigurationMessage.builder()
|
||||
guard let displayName = displayName else { return nil }
|
||||
let configurationProto = SNProtoConfigurationMessage.builder(displayName: displayName)
|
||||
if let profilePictureURL = profilePictureURL { configurationProto.setProfilePicture(profilePictureURL) }
|
||||
if let profileKey = profileKey { configurationProto.setProfileKey(profileKey) }
|
||||
configurationProto.setClosedGroups(closedGroups.compactMap { $0.toProto() })
|
||||
configurationProto.setOpenGroups([String](openGroups))
|
||||
let contentProto = SNProtoContent.builder()
|
||||
|
|
|
@ -3126,15 +3126,21 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
|
|||
|
||||
// MARK: - SNProtoConfigurationMessageBuilder
|
||||
|
||||
@objc public class func builder() -> SNProtoConfigurationMessageBuilder {
|
||||
return SNProtoConfigurationMessageBuilder()
|
||||
@objc public class func builder(displayName: String) -> SNProtoConfigurationMessageBuilder {
|
||||
return SNProtoConfigurationMessageBuilder(displayName: displayName)
|
||||
}
|
||||
|
||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
||||
@objc public func asBuilder() -> SNProtoConfigurationMessageBuilder {
|
||||
let builder = SNProtoConfigurationMessageBuilder()
|
||||
let builder = SNProtoConfigurationMessageBuilder(displayName: displayName)
|
||||
builder.setClosedGroups(closedGroups)
|
||||
builder.setOpenGroups(openGroups)
|
||||
if let _value = profilePicture {
|
||||
builder.setProfilePicture(_value)
|
||||
}
|
||||
if let _value = profileKey {
|
||||
builder.setProfileKey(_value)
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
|
@ -3144,6 +3150,12 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
|
|||
|
||||
@objc fileprivate override init() {}
|
||||
|
||||
@objc fileprivate init(displayName: String) {
|
||||
super.init()
|
||||
|
||||
setDisplayName(displayName)
|
||||
}
|
||||
|
||||
@objc public func addClosedGroups(_ valueParam: SNProtoConfigurationMessageClosedGroup) {
|
||||
var items = proto.closedGroups
|
||||
items.append(valueParam.proto)
|
||||
|
@ -3164,6 +3176,18 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
|
|||
proto.openGroups = wrappedItems
|
||||
}
|
||||
|
||||
@objc public func setDisplayName(_ valueParam: String) {
|
||||
proto.displayName = valueParam
|
||||
}
|
||||
|
||||
@objc public func setProfilePicture(_ valueParam: String) {
|
||||
proto.profilePicture = valueParam
|
||||
}
|
||||
|
||||
@objc public func setProfileKey(_ valueParam: Data) {
|
||||
proto.profileKey = valueParam
|
||||
}
|
||||
|
||||
@objc public func build() throws -> SNProtoConfigurationMessage {
|
||||
return try SNProtoConfigurationMessage.parseProto(proto)
|
||||
}
|
||||
|
@ -3177,14 +3201,38 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
|
|||
|
||||
@objc public let closedGroups: [SNProtoConfigurationMessageClosedGroup]
|
||||
|
||||
@objc public let displayName: String
|
||||
|
||||
@objc public var openGroups: [String] {
|
||||
return proto.openGroups
|
||||
}
|
||||
|
||||
@objc public var profilePicture: String? {
|
||||
guard proto.hasProfilePicture else {
|
||||
return nil
|
||||
}
|
||||
return proto.profilePicture
|
||||
}
|
||||
@objc public var hasProfilePicture: Bool {
|
||||
return proto.hasProfilePicture
|
||||
}
|
||||
|
||||
@objc public var profileKey: Data? {
|
||||
guard proto.hasProfileKey else {
|
||||
return nil
|
||||
}
|
||||
return proto.profileKey
|
||||
}
|
||||
@objc public var hasProfileKey: Bool {
|
||||
return proto.hasProfileKey
|
||||
}
|
||||
|
||||
private init(proto: SessionProtos_ConfigurationMessage,
|
||||
closedGroups: [SNProtoConfigurationMessageClosedGroup]) {
|
||||
closedGroups: [SNProtoConfigurationMessageClosedGroup],
|
||||
displayName: String) {
|
||||
self.proto = proto
|
||||
self.closedGroups = closedGroups
|
||||
self.displayName = displayName
|
||||
}
|
||||
|
||||
@objc
|
||||
|
@ -3201,12 +3249,18 @@ extension SNProtoConfigurationMessageClosedGroup.SNProtoConfigurationMessageClos
|
|||
var closedGroups: [SNProtoConfigurationMessageClosedGroup] = []
|
||||
closedGroups = try proto.closedGroups.map { try SNProtoConfigurationMessageClosedGroup.parseProto($0) }
|
||||
|
||||
guard proto.hasDisplayName else {
|
||||
throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: displayName")
|
||||
}
|
||||
let displayName = proto.displayName
|
||||
|
||||
// MARK: - Begin Validation Logic for SNProtoConfigurationMessage -
|
||||
|
||||
// MARK: - End Validation Logic for SNProtoConfigurationMessage -
|
||||
|
||||
let result = SNProtoConfigurationMessage(proto: proto,
|
||||
closedGroups: closedGroups)
|
||||
closedGroups: closedGroups,
|
||||
displayName: displayName)
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
@ -1139,7 +1139,7 @@ struct SessionProtos_DataMessage {
|
|||
/// name, members
|
||||
case update // = 2
|
||||
|
||||
/// wrappers
|
||||
/// publicKey, wrappers
|
||||
case encryptionKeyPair // = 3
|
||||
|
||||
/// name
|
||||
|
@ -1151,8 +1151,6 @@ struct SessionProtos_DataMessage {
|
|||
/// members
|
||||
case membersRemoved // = 6
|
||||
case memberLeft // = 7
|
||||
|
||||
/// wrappers
|
||||
case encryptionKeyPairRequest // = 8
|
||||
|
||||
init() {
|
||||
|
@ -1248,6 +1246,34 @@ struct SessionProtos_ConfigurationMessage {
|
|||
|
||||
var openGroups: [String] = []
|
||||
|
||||
/// @required
|
||||
var displayName: String {
|
||||
get {return _displayName ?? String()}
|
||||
set {_displayName = newValue}
|
||||
}
|
||||
/// Returns true if `displayName` has been explicitly set.
|
||||
var hasDisplayName: Bool {return self._displayName != nil}
|
||||
/// Clears the value of `displayName`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDisplayName() {self._displayName = nil}
|
||||
|
||||
var profilePicture: String {
|
||||
get {return _profilePicture ?? String()}
|
||||
set {_profilePicture = newValue}
|
||||
}
|
||||
/// Returns true if `profilePicture` has been explicitly set.
|
||||
var hasProfilePicture: Bool {return self._profilePicture != nil}
|
||||
/// Clears the value of `profilePicture`. Subsequent reads from it will return its default value.
|
||||
mutating func clearProfilePicture() {self._profilePicture = nil}
|
||||
|
||||
var profileKey: Data {
|
||||
get {return _profileKey ?? SwiftProtobuf.Internal.emptyData}
|
||||
set {_profileKey = newValue}
|
||||
}
|
||||
/// Returns true if `profileKey` has been explicitly set.
|
||||
var hasProfileKey: Bool {return self._profileKey != nil}
|
||||
/// Clears the value of `profileKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearProfileKey() {self._profileKey = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
struct ClosedGroup {
|
||||
|
@ -1300,6 +1326,10 @@ struct SessionProtos_ConfigurationMessage {
|
|||
}
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _displayName: String? = nil
|
||||
fileprivate var _profilePicture: String? = nil
|
||||
fileprivate var _profileKey: Data? = nil
|
||||
}
|
||||
|
||||
struct SessionProtos_ReceiptMessage {
|
||||
|
@ -3186,9 +3216,13 @@ extension SessionProtos_ConfigurationMessage: SwiftProtobuf.Message, SwiftProtob
|
|||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "closedGroups"),
|
||||
2: .same(proto: "openGroups"),
|
||||
3: .same(proto: "displayName"),
|
||||
4: .same(proto: "profilePicture"),
|
||||
5: .same(proto: "profileKey"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._displayName == nil {return false}
|
||||
if !SwiftProtobuf.Internal.areAllInitialized(self.closedGroups) {return false}
|
||||
return true
|
||||
}
|
||||
|
@ -3198,6 +3232,9 @@ extension SessionProtos_ConfigurationMessage: SwiftProtobuf.Message, SwiftProtob
|
|||
switch fieldNumber {
|
||||
case 1: try decoder.decodeRepeatedMessageField(value: &self.closedGroups)
|
||||
case 2: try decoder.decodeRepeatedStringField(value: &self.openGroups)
|
||||
case 3: try decoder.decodeSingularStringField(value: &self._displayName)
|
||||
case 4: try decoder.decodeSingularStringField(value: &self._profilePicture)
|
||||
case 5: try decoder.decodeSingularBytesField(value: &self._profileKey)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -3210,12 +3247,24 @@ extension SessionProtos_ConfigurationMessage: SwiftProtobuf.Message, SwiftProtob
|
|||
if !self.openGroups.isEmpty {
|
||||
try visitor.visitRepeatedStringField(value: self.openGroups, fieldNumber: 2)
|
||||
}
|
||||
if let v = self._displayName {
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 3)
|
||||
}
|
||||
if let v = self._profilePicture {
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 4)
|
||||
}
|
||||
if let v = self._profileKey {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 5)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SessionProtos_ConfigurationMessage, rhs: SessionProtos_ConfigurationMessage) -> Bool {
|
||||
if lhs.closedGroups != rhs.closedGroups {return false}
|
||||
if lhs.openGroups != rhs.openGroups {return false}
|
||||
if lhs._displayName != rhs._displayName {return false}
|
||||
if lhs._profilePicture != rhs._profilePicture {return false}
|
||||
if lhs._profileKey != rhs._profileKey {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -222,8 +222,12 @@ message ConfigurationMessage {
|
|||
repeated bytes admins = 5;
|
||||
}
|
||||
|
||||
repeated ClosedGroup closedGroups = 1;
|
||||
repeated string openGroups = 2;
|
||||
repeated ClosedGroup closedGroups = 1;
|
||||
repeated string openGroups = 2;
|
||||
// @required
|
||||
required string displayName = 3;
|
||||
optional string profilePicture = 4;
|
||||
optional bytes profileKey = 5;
|
||||
}
|
||||
|
||||
message ReceiptMessage {
|
||||
|
|
|
@ -145,6 +145,22 @@ extension MessageReceiver {
|
|||
private static func handleConfigurationMessage(_ message: ConfigurationMessage, using transaction: Any) {
|
||||
guard message.sender == getUserHexEncodedPublicKey(), !UserDefaults.standard[.hasSyncedConfiguration] else { return }
|
||||
let storage = SNMessagingKitConfiguration.shared.storage
|
||||
let profileManager = SSKEnvironment.shared.profileManager
|
||||
// Profile
|
||||
let sessionID = getUserHexEncodedPublicKey()
|
||||
let contact = Storage.shared.getContact(with: sessionID) ?? Contact(sessionID: sessionID)
|
||||
if let displayName = message.displayName {
|
||||
profileManager.updateProfileForContact(withID: sessionID, displayName: displayName, with: transaction as! YapDatabaseReadWriteTransaction)
|
||||
contact.displayName = displayName
|
||||
}
|
||||
if let profileKey = message.profileKey, let profilePictureURL = message.profilePictureURL, profileKey.count == kAES256_KeyByteLength {
|
||||
profileManager.setProfileKeyData(profileKey, forRecipientId: sessionID, avatarURL: profilePictureURL)
|
||||
contact.profilePictureURL = profilePictureURL
|
||||
contact.profilePictureEncryptionKey = OWSAES256Key(data: profileKey)
|
||||
}
|
||||
// Notification
|
||||
UserDefaults.standard[.hasSyncedConfiguration] = true
|
||||
// Closed groups
|
||||
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
|
||||
NotificationCenter.default.post(name: .configurationMessageReceived, object: nil)
|
||||
for closedGroup in message.closedGroups {
|
||||
|
@ -152,12 +168,12 @@ extension MessageReceiver {
|
|||
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair,
|
||||
members: [String](closedGroup.members), admins: [String](closedGroup.admins), messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
||||
}
|
||||
// Open groups
|
||||
let allOpenGroups = Set(storage.getAllUserOpenGroups().keys)
|
||||
for openGroupURL in message.openGroups {
|
||||
guard !allOpenGroups.contains(openGroupURL) else { continue }
|
||||
OpenGroupManager.shared.add(with: openGroupURL, using: transaction).retainUntilComplete()
|
||||
}
|
||||
UserDefaults.standard[.hasSyncedConfiguration] = true
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
|
|
@ -152,7 +152,9 @@ public enum MessageReceiver {
|
|||
if message is VisibleMessage && !isValid && proto.dataMessage?.attachments.isEmpty == false {
|
||||
isValid = true
|
||||
}
|
||||
guard isValid else { throw Error.invalidMessage }
|
||||
guard isValid else {
|
||||
throw Error.invalidMessage
|
||||
}
|
||||
// Return
|
||||
return (message, proto)
|
||||
} else {
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
extension ConfigurationMessage {
|
||||
|
||||
public static func getCurrent() -> ConfigurationMessage {
|
||||
let storage = Storage.shared
|
||||
let displayName = storage.getUserDisplayName()!
|
||||
let profilePictureURL = storage.getUserProfilePictureURL()
|
||||
let profileKey = storage.getUserProfileKey()
|
||||
var closedGroups: Set<ClosedGroup> = []
|
||||
var openGroups: Set<String> = []
|
||||
Storage.read { transaction in
|
||||
|
@ -12,18 +16,18 @@ extension ConfigurationMessage {
|
|||
guard thread.isCurrentUserMemberInGroup() else { return }
|
||||
let groupID = thread.groupModel.groupId
|
||||
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
|
||||
guard Storage.shared.isClosedGroup(groupPublicKey),
|
||||
let encryptionKeyPair = Storage.shared.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { return }
|
||||
guard storage.isClosedGroup(groupPublicKey),
|
||||
let encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { return }
|
||||
let closedGroup = ClosedGroup(publicKey: groupPublicKey, name: thread.groupModel.groupName!, encryptionKeyPair: encryptionKeyPair,
|
||||
members: Set(thread.groupModel.groupMemberIds), admins: Set(thread.groupModel.groupAdminIds))
|
||||
closedGroups.insert(closedGroup)
|
||||
case .openGroup:
|
||||
guard let openGroup = Storage.shared.getOpenGroup(for: thread.uniqueId!) else { return }
|
||||
guard let openGroup = storage.getOpenGroup(for: thread.uniqueId!) else { return }
|
||||
openGroups.insert(openGroup.server)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
return ConfigurationMessage(closedGroups: closedGroups, openGroups: openGroups)
|
||||
return ConfigurationMessage(displayName: displayName, profilePictureURL: profilePictureURL, profileKey: profileKey, closedGroups: closedGroups, openGroups: openGroups)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue