Debug & make UI clearer
This commit is contained in:
parent
ce86d9a196
commit
ee1d4b1bd5
|
@ -7,6 +7,7 @@ final class UserCell : UITableViewCell {
|
||||||
// MARK: Accessory
|
// MARK: Accessory
|
||||||
enum Accessory {
|
enum Accessory {
|
||||||
case none
|
case none
|
||||||
|
case lock
|
||||||
case tick(isSelected: Bool)
|
case tick(isSelected: Bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ final class UserCell : UITableViewCell {
|
||||||
return result
|
return result
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var tickImageView: UIImageView = {
|
private lazy var accessoryImageView: UIImageView = {
|
||||||
let result = UIImageView()
|
let result = UIImageView()
|
||||||
result.contentMode = .scaleAspectFit
|
result.contentMode = .scaleAspectFit
|
||||||
let size: CGFloat = 24
|
let size: CGFloat = 24
|
||||||
|
@ -61,7 +62,7 @@ final class UserCell : UITableViewCell {
|
||||||
profilePictureView.set(.height, to: profilePictureViewSize)
|
profilePictureView.set(.height, to: profilePictureViewSize)
|
||||||
profilePictureView.size = profilePictureViewSize
|
profilePictureView.size = profilePictureViewSize
|
||||||
// Set up the main stack view
|
// Set up the main stack view
|
||||||
let stackView = UIStackView(arrangedSubviews: [ profilePictureView, displayNameLabel, tickImageView ])
|
let stackView = UIStackView(arrangedSubviews: [ profilePictureView, displayNameLabel, accessoryImageView ])
|
||||||
stackView.axis = .horizontal
|
stackView.axis = .horizontal
|
||||||
stackView.alignment = .center
|
stackView.alignment = .center
|
||||||
stackView.spacing = Values.mediumSpacing
|
stackView.spacing = Values.mediumSpacing
|
||||||
|
@ -85,11 +86,14 @@ final class UserCell : UITableViewCell {
|
||||||
profilePictureView.update()
|
profilePictureView.update()
|
||||||
displayNameLabel.text = UserDisplayNameUtilities.getPrivateChatDisplayName(for: publicKey) ?? publicKey
|
displayNameLabel.text = UserDisplayNameUtilities.getPrivateChatDisplayName(for: publicKey) ?? publicKey
|
||||||
switch accessory {
|
switch accessory {
|
||||||
case .none: tickImageView.isHidden = true
|
case .none: accessoryImageView.isHidden = true
|
||||||
|
case .lock:
|
||||||
|
accessoryImageView.isHidden = false
|
||||||
|
accessoryImageView.image = #imageLiteral(resourceName: "ic_lock_outline").asTintedImage(color: Colors.text.withAlphaComponent(Values.unimportantElementOpacity))!
|
||||||
case .tick(let isSelected):
|
case .tick(let isSelected):
|
||||||
tickImageView.isHidden = false
|
accessoryImageView.isHidden = false
|
||||||
let icon = isSelected ? #imageLiteral(resourceName: "CircleCheck") : #imageLiteral(resourceName: "Circle")
|
let icon = isSelected ? #imageLiteral(resourceName: "CircleCheck") : #imageLiteral(resourceName: "Circle")
|
||||||
tickImageView.image = isDarkMode ? icon : icon.asTintedImage(color: Colors.text)!
|
accessoryImageView.image = isDarkMode ? icon : icon.asTintedImage(color: Colors.text)!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,12 @@ final class EditClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelega
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var addMembersButton: Button = {
|
private lazy var addMembersButton: Button = {
|
||||||
let result = Button(style: .prominentOutline, size: .large)
|
let result = Button(style: .prominentOutline, size: .large)
|
||||||
result.setTitle("Add Members", for: UIControl.State.normal)
|
result.setTitle("Add Members", for: UIControl.State.normal)
|
||||||
result.addTarget(self, action: #selector(addMembers), for: UIControl.Event.touchUpInside)
|
result.addTarget(self, action: #selector(addMembers), for: UIControl.Event.touchUpInside)
|
||||||
result.contentEdgeInsets = UIEdgeInsets(top: 0, leading: Values.mediumSpacing, bottom: 0, trailing: Values.mediumSpacing)
|
result.contentEdgeInsets = UIEdgeInsets(top: 0, leading: Values.mediumSpacing, bottom: 0, trailing: Values.mediumSpacing)
|
||||||
return result
|
return result
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@objc private lazy var tableView: UITableView = {
|
@objc private lazy var tableView: UITableView = {
|
||||||
let result = UITableView()
|
let result = UITableView()
|
||||||
|
@ -141,13 +141,14 @@ final class EditClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelega
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "UserCell") as! UserCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: "UserCell") as! UserCell
|
||||||
let publicKey = members[indexPath.row]
|
let publicKey = members[indexPath.row]
|
||||||
cell.publicKey = publicKey
|
cell.publicKey = publicKey
|
||||||
|
cell.accessory = !canBeRemoved(publicKey) ? .lock : .none
|
||||||
cell.update()
|
cell.update()
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
||||||
let publicKey = members[indexPath.row]
|
let publicKey = members[indexPath.row]
|
||||||
return publicKey != getUserHexEncodedPublicKey()
|
return canBeRemoved(publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
|
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
|
||||||
|
@ -286,4 +287,16 @@ final class EditClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelega
|
||||||
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default, handler: nil))
|
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default, handler: nil))
|
||||||
presentAlert(alert)
|
presentAlert(alert)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func canBeRemoved(_ publicKey: String) -> Bool {
|
||||||
|
return !isAdmin(publicKey) && !isCurrentUser(publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func isAdmin(_ publicKey: String) -> Bool {
|
||||||
|
return thread.groupModel.groupAdminIds.contains(publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func isCurrentUser(_ publicKey: String) -> Bool {
|
||||||
|
return publicKey == getUserHexEncodedPublicKey()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,13 @@ import SessionUtilitiesKit
|
||||||
public final class ClosedGroupUpdateV2 : ControlMessage {
|
public final class ClosedGroupUpdateV2 : ControlMessage {
|
||||||
public var kind: Kind?
|
public var kind: Kind?
|
||||||
|
|
||||||
|
public override var ttl: UInt64 {
|
||||||
|
switch kind {
|
||||||
|
case .encryptionKeyPair: return 4 * 24 * 60 * 60 * 1000
|
||||||
|
default: return 2 * 24 * 60 * 60 * 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Kind
|
// MARK: Kind
|
||||||
public enum Kind : CustomStringConvertible {
|
public enum Kind : CustomStringConvertible {
|
||||||
case new(publicKey: Data, name: String, encryptionKeyPair: ECKeyPair, members: [Data], admins: [Data])
|
case new(publicKey: Data, name: String, encryptionKeyPair: ECKeyPair, members: [Data], admins: [Data])
|
||||||
|
|
|
@ -4,7 +4,7 @@ import SessionUtilitiesKit
|
||||||
public final class TypingIndicator : ControlMessage {
|
public final class TypingIndicator : ControlMessage {
|
||||||
public var kind: Kind?
|
public var kind: Kind?
|
||||||
|
|
||||||
public override class var ttl: UInt64 { 30 * 1000 }
|
public override var ttl: UInt64 { 20 * 1000 }
|
||||||
|
|
||||||
// MARK: Kind
|
// MARK: Kind
|
||||||
public enum Kind : Int, CustomStringConvertible {
|
public enum Kind : Int, CustomStringConvertible {
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class Message : NSObject, NSCoding { // NSObject/NSCoding conformance is
|
||||||
public var groupPublicKey: String?
|
public var groupPublicKey: String?
|
||||||
public var openGroupServerMessageID: UInt64?
|
public var openGroupServerMessageID: UInt64?
|
||||||
|
|
||||||
public class var ttl: UInt64 { 2 * 24 * 60 * 60 * 1000 }
|
public var ttl: UInt64 { 2 * 24 * 60 * 60 * 1000 }
|
||||||
|
|
||||||
public override init() { }
|
public override init() { }
|
||||||
|
|
||||||
|
|
|
@ -144,8 +144,6 @@ extension MessageSender : SharedSenderKeysDelegate {
|
||||||
}
|
}
|
||||||
// Generate the new encryption key pair
|
// Generate the new encryption key pair
|
||||||
let newKeyPair = Curve25519.generateKeyPair()
|
let newKeyPair = Curve25519.generateKeyPair()
|
||||||
// Store it
|
|
||||||
Storage.shared.addClosedGroupEncryptionKeyPair(newKeyPair, for: groupPublicKey, using: transaction)
|
|
||||||
// Distribute it
|
// Distribute it
|
||||||
let proto = try SNProtoDataMessageClosedGroupUpdateV2KeyPair.builder(publicKey: newKeyPair.publicKey,
|
let proto = try SNProtoDataMessageClosedGroupUpdateV2KeyPair.builder(publicKey: newKeyPair.publicKey,
|
||||||
privateKey: newKeyPair.privateKey).build()
|
privateKey: newKeyPair.privateKey).build()
|
||||||
|
@ -155,7 +153,12 @@ extension MessageSender : SharedSenderKeysDelegate {
|
||||||
return ClosedGroupUpdateV2.KeyPairWrapper(publicKey: publicKey, encryptedKeyPair: ciphertext)
|
return ClosedGroupUpdateV2.KeyPairWrapper(publicKey: publicKey, encryptedKeyPair: ciphertext)
|
||||||
}
|
}
|
||||||
let closedGroupUpdate = ClosedGroupUpdateV2(kind: .encryptionKeyPair(wrappers))
|
let closedGroupUpdate = ClosedGroupUpdateV2(kind: .encryptionKeyPair(wrappers))
|
||||||
MessageSender.send(closedGroupUpdate, in: thread, using: transaction)
|
let _ = MessageSender.sendNonDurably(closedGroupUpdate, in: thread, using: transaction).done { // FIXME: It'd be great if we could make this a durable operation
|
||||||
|
// Store it * after * having sent out the message to the group
|
||||||
|
SNMessagingKitConfiguration.shared.storage.write { transaction in
|
||||||
|
Storage.shared.addClosedGroupEncryptionKeyPair(newKeyPair, for: groupPublicKey, using: transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -219,11 +219,7 @@ public final class MessageSender : NSObject {
|
||||||
}
|
}
|
||||||
let recipient = message.recipient!
|
let recipient = message.recipient!
|
||||||
let base64EncodedData = wrappedMessage.base64EncodedString()
|
let base64EncodedData = wrappedMessage.base64EncodedString()
|
||||||
var ttl = type(of: message).ttl
|
guard let (timestamp, nonce) = ProofOfWork.calculate(ttl: message.ttl, publicKey: recipient, data: base64EncodedData) else {
|
||||||
if let closedGroupUpdate = message as? ClosedGroupUpdateV2, case .encryptionKeyPair = closedGroupUpdate.kind! {
|
|
||||||
ttl = 30 * 24 * 60 * 60 * 1000
|
|
||||||
}
|
|
||||||
guard let (timestamp, nonce) = ProofOfWork.calculate(ttl: ttl, publicKey: recipient, data: base64EncodedData) else {
|
|
||||||
SNLog("Proof of work calculation failed.")
|
SNLog("Proof of work calculation failed.")
|
||||||
handleFailure(with: Error.proofOfWorkCalculationFailed, using: transaction)
|
handleFailure(with: Error.proofOfWorkCalculationFailed, using: transaction)
|
||||||
return promise
|
return promise
|
||||||
|
@ -234,7 +230,7 @@ public final class MessageSender : NSObject {
|
||||||
NotificationCenter.default.post(name: .messageSending, object: NSNumber(value: message.sentTimestamp!))
|
NotificationCenter.default.post(name: .messageSending, object: NSNumber(value: message.sentTimestamp!))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let snodeMessage = SnodeMessage(recipient: recipient, data: base64EncodedData, ttl: type(of: message).ttl, timestamp: timestamp, nonce: nonce)
|
let snodeMessage = SnodeMessage(recipient: recipient, data: base64EncodedData, ttl: message.ttl, timestamp: timestamp, nonce: nonce)
|
||||||
SnodeAPI.sendMessage(snodeMessage).done(on: DispatchQueue.global(qos: .userInitiated)) { promises in
|
SnodeAPI.sendMessage(snodeMessage).done(on: DispatchQueue.global(qos: .userInitiated)) { promises in
|
||||||
var isSuccess = false
|
var isSuccess = false
|
||||||
let promiseCount = promises.count
|
let promiseCount = promises.count
|
||||||
|
|
|
@ -75,7 +75,9 @@ public final class SnodeAPI : NSObject {
|
||||||
|
|
||||||
@objc public static func clearSnodePool() {
|
@objc public static func clearSnodePool() {
|
||||||
snodePool.removeAll()
|
snodePool.removeAll()
|
||||||
setSnodePool(to: [])
|
Threading.workQueue.async {
|
||||||
|
setSnodePool(to: [])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Swarm Interaction
|
// MARK: Swarm Interaction
|
||||||
|
|
Loading…
Reference in New Issue