Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor events #2234

Merged
merged 13 commits into from
Jul 16, 2024
69 changes: 33 additions & 36 deletions DcCore/DcCore/DC/events.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,32 @@ import UIKit
import UserNotifications

extension Notification.Name {
// Messages
public static let messagesChanged = Notification.Name(rawValue: "eventMsgsChanged")
public static let messageReadDeliveredFailedReaction = Notification.Name(rawValue: "messageReadDeliveredFailedReaction")
public static let incomingMessage = Notification.Name(rawValue: "eventIncomingMsg")
public static let incomingMessageOnAnyAccount = Notification.Name(rawValue: "eventIncomingMsgAnyAccount")
public static let messagesNoticed = Notification.Name(rawValue: "eventMsgsNoticed")

// Chats
public static let chatModified = Notification.Name(rawValue: "eventChatModified")

// Contacts
public static let contactsChanged = Notification.Name(rawValue: "eventContactsChanged")

// Progress
public static let importExportProgress = Notification.Name(rawValue: "eventImexProgress")
public static let configurationProgress = Notification.Name(rawValue: "eventConfigureProgress")

public static let connectivityChanged = Notification.Name(rawValue: "eventConnectivityChanged")

// Webxdc
public static let webxdcStatusUpdate = Notification.Name(rawValue: "eventWebxdcStatusUpdate")
public static let webxdcRealtimeDataReceived = Notification.Name(rawValue: "eventWebxdcRealtimeData")

public static let ephemeralTimerModified = Notification.Name(rawValue: "eventEphemeralTimerModified")
}

public let eventIncomingMsg = Notification.Name(rawValue: "eventIncomingMsg")
public let eventIncomingMsgAnyAccount = Notification.Name(rawValue: "eventIncomingMsgAnyAccount")
public let eventImexProgress = Notification.Name(rawValue: "eventImexProgress")
public let eventConfigureProgress = Notification.Name(rawValue: "eventConfigureProgress")
public let eventSecureInviterProgress = Notification.Name(rawValue: "eventSecureInviterProgress")
public let eventContactsChanged = Notification.Name(rawValue: "eventContactsChanged")
public let eventChatModified = Notification.Name(rawValue: "eventChatModified")
public let eventEphemeralTimerModified = Notification.Name(rawValue: "eventEphemeralTimerModified")
public let eventMsgsNoticed = Notification.Name(rawValue: "eventMsgsNoticed")
public let eventConnectivityChanged = Notification.Name(rawValue: "eventConnectivityChanged")
public let eventWebxdcStatusUpdate = Notification.Name(rawValue: "eventWebxdcStatusUpdate")
public let eventWebxdcRealtimeData = Notification.Name(rawValue: "eventWebxdcRealtimeData")

public class DcEventHandler {
let dcAccounts: DcAccounts
Expand Down Expand Up @@ -49,7 +59,7 @@ public class DcEventHandler {
DispatchQueue.main.async {
let done = Int(data1) == 1000

NotificationCenter.default.post(name: eventConfigureProgress, object: nil, userInfo: [
NotificationCenter.default.post(name: .configurationProgress, object: nil, userInfo: [
"progress": Int(data1),
"error": Int(data1) == 0,
"done": done,
Expand All @@ -64,7 +74,7 @@ public class DcEventHandler {

case DC_EVENT_IMEX_PROGRESS:
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventImexProgress, object: nil, userInfo: [
NotificationCenter.default.post(name: .importExportProgress, object: nil, userInfo: [
"progress": Int(data1),
"error": Int(data1) == 0,
"done": Int(data1) == 1000,
Expand Down Expand Up @@ -98,7 +108,7 @@ public class DcEventHandler {
return
}
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventMsgsNoticed, object: nil, userInfo: [
NotificationCenter.default.post(name: .messagesNoticed, object: nil, userInfo: [
"chat_id": Int(data1),
])
}
Expand All @@ -109,7 +119,7 @@ public class DcEventHandler {
}
logger.info("📡[\(accountId)] chat modified: \(data1)")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventChatModified, object: nil, userInfo: [
NotificationCenter.default.post(name: .chatModified, object: nil, userInfo: [
"chat_id": Int(data1),
])
}
Expand All @@ -119,46 +129,33 @@ public class DcEventHandler {
}
logger.info("📡[\(accountId)] ephemeral timer modified: \(data1)")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventEphemeralTimerModified, object: nil, userInfo: [
NotificationCenter.default.post(name: .ephemeralTimerModified, object: nil, userInfo: [
"chat_id": Int(data1),
])
}

case DC_EVENT_INCOMING_MSG:
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventIncomingMsgAnyAccount, object: nil)
NotificationCenter.default.post(name: .incomingMessageOnAnyAccount, object: nil)
}
if accountId != dcAccounts.getSelected().id {
return
}
logger.info("📡[\(accountId)] incoming message \(data2)")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventIncomingMsg, object: nil, userInfo: [
NotificationCenter.default.post(name: .incomingMessage, object: nil, userInfo: [
"message_id": Int(data2),
"chat_id": Int(data1),
])
}

case DC_EVENT_SECUREJOIN_INVITER_PROGRESS:
if accountId != dcAccounts.getSelected().id {
return
}
logger.info("📡[\(accountId)] securejoin inviter: \(data1)")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventSecureInviterProgress, object: nil, userInfo: [
"progress": Int(data2),
"error": Int(data2) == 0,
"done": Int(data2) == 1000,
])
}

case DC_EVENT_CONTACTS_CHANGED:
if accountId != dcAccounts.getSelected().id {
return
}
logger.info("📡[\(accountId)] contact changed: \(data1)")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventContactsChanged, object: nil, userInfo: [
NotificationCenter.default.post(name: .contactsChanged, object: nil, userInfo: [
"contact_id": Int(data1)
])
}
Expand All @@ -169,7 +166,7 @@ public class DcEventHandler {
}
logger.info("📡[\(accountId)] connectivity changed")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventConnectivityChanged, object: nil)
NotificationCenter.default.post(name: .connectivityChanged, object: nil)
}

case DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE:
Expand All @@ -183,7 +180,7 @@ public class DcEventHandler {
}
logger.info("📡[\(accountId)] webxdc update")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventWebxdcStatusUpdate, object: nil, userInfo: [
NotificationCenter.default.post(name: .webxdcStatusUpdate, object: nil, userInfo: [
"message_id": Int(data1),
])
}
Expand All @@ -193,7 +190,7 @@ public class DcEventHandler {
return
}
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventWebxdcRealtimeData, object: nil, userInfo: [
NotificationCenter.default.post(name: .webxdcRealtimeDataReceived, object: nil, userInfo: [
"message_id": Int(data1),
"data": event.data2Data,
])
Expand Down
88 changes: 49 additions & 39 deletions deltachat-ios/Chat/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,32 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {

// MARK: - Notifications

@objc private func handleEphemeralTimerModified(_ notification: Notification) {
updateTitle()
}

@objc private func handleChatModified(_ notification: Notification) {
guard let ui = notification.userInfo, chatId == ui["chat_id"] as? Int else { return }

dcChat = dcContext.getChat(chatId: chatId)
if dcChat.canSend {
if messageInputBar.isHidden {
configureUIForWriting()
messageInputBar.isHidden = false
becomeFirstResponder()
}
} else if dcChat.isProtectionBroken {
configureContactRequestBar()
messageInputBar.isHidden = false
becomeFirstResponder()
} else if !dcChat.isContactRequest {
if !messageInputBar.isHidden {
messageInputBar.isHidden = true
}
}
updateTitle()
}

@objc private func handleMessagesChanged(_ notification: Notification) {
guard let ui = notification.userInfo else { return }

Expand All @@ -440,7 +466,6 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {
refreshMessages()
updateTitle()
markSeenMessagesInVisibleArea()

}
}

Expand All @@ -465,6 +490,22 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {
}
}

@objc private func handleIncomingMessage(_ notification: Notification) {
guard let ui = notification.userInfo else { return }

let chatId = ui["chat_id"] as? Int ?? 0
if chatId == 0 || chatId == self.chatId {
let wasLastSectionScrolledToBottom = isLastRowScrolledToBottom()
refreshMessages()
updateTitle()
if wasLastSectionScrolledToBottom {
scrollToBottom(animated: true)
}
updateScrollDownButtonVisibility()
markSeenMessagesInVisibleArea()
}
}

private func setupObservers() {
let nc = NotificationCenter.default
if msgChangedObserver == nil {
Expand All @@ -489,60 +530,29 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {

if incomingMsgObserver == nil {
incomingMsgObserver = nc.addObserver(
forName: eventIncomingMsg,
forName: .incomingMessage,
object: nil, queue: OperationQueue.main
) { [weak self] notification in
guard let self, let ui = notification.userInfo else { return }
let chatId = ui["chat_id"] as? Int ?? 0
if chatId == 0 || chatId == self.chatId {
let wasLastSectionScrolledToBottom = isLastRowScrolledToBottom()
refreshMessages()
updateTitle()
if wasLastSectionScrolledToBottom {
scrollToBottom(animated: true)
}
updateScrollDownButtonVisibility()
markSeenMessagesInVisibleArea()
}
self?.handleIncomingMessage(notification)
}
}

if chatModifiedObserver == nil {
chatModifiedObserver = nc.addObserver(
forName: eventChatModified,
forName: .chatModified,
object: nil,
queue: OperationQueue.main
) { [weak self] notification in
guard let self, let ui = notification.userInfo else { return }
if self.chatId == ui["chat_id"] as? Int {
self.dcChat = self.dcContext.getChat(chatId: self.chatId)
if self.dcChat.canSend {
if self.messageInputBar.isHidden {
self.configureUIForWriting()
self.messageInputBar.isHidden = false
self.becomeFirstResponder()
}
} else if self.dcChat.isProtectionBroken {
self.configureContactRequestBar()
self.messageInputBar.isHidden = false
self.becomeFirstResponder()
} else if !self.dcChat.isContactRequest {
if !self.messageInputBar.isHidden {
self.messageInputBar.isHidden = true
}
}
self.updateTitle()
}
self?.handleChatModified(notification)
}
}

if ephemeralTimerModifiedObserver == nil {
ephemeralTimerModifiedObserver = nc.addObserver(
forName: eventEphemeralTimerModified,
forName: .ephemeralTimerModified,
object: nil, queue: OperationQueue.main
) { [weak self] _ in
guard let self else { return }
self.updateTitle()
) { [weak self] notification in
self?.handleEphemeralTimerModified(notification)
}
}

Expand Down
57 changes: 30 additions & 27 deletions deltachat-ios/Controller/AccountSetup/AccountSetupController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,14 @@ class AccountSetupController: UITableViewController, ProgressAlertHandler {
}

private func login(emailAddress: String, password: String, skipAdvanceSetup: Bool = false) {
addProgressHudLoginListener()
progressObserver = NotificationCenter.default.addObserver(
forName: .configurationProgress,
object: nil,
queue: nil
) { [weak self] notification in
self?.handleConfigurationProgress(notification)
}

resignFirstResponderOnAllCells() // this will resign focus from all textFieldCells so the keyboard wont pop up anymore
dcContext.addr = emailAddress
dcContext.mailPw = password
Expand Down Expand Up @@ -557,32 +564,6 @@ class AccountSetupController: UITableViewController, ProgressAlertHandler {
UIApplication.shared.open(url) // this opens safari as seperate app
}

private func addProgressHudLoginListener() {
progressObserver = NotificationCenter.default.addObserver(
forName: eventConfigureProgress,
object: nil,
queue: nil
) { notification in
if let ui = notification.userInfo {
if let error = ui["error"] as? Bool, error {
self.dcAccounts.startIo()
var errorMessage = ui["errorMessage"] as? String
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
if let reachability = appDelegate.reachability, reachability.connection == .unavailable {
errorMessage = String.localized("login_error_no_internet_connection")
}
}
self.updateProgressAlert(error: errorMessage)
} else if let done = ui["done"] as? Bool, done {
self.dcAccounts.startIo()
self.updateProgressAlertSuccess(completion: self.handleLoginSuccess)
} else {
self.updateProgressAlertValue(value: ui["progress"] as? Int)
}
}
}
}

private func evaluateAdvancedSetup() {
for cell in advancedSectionCells {
if let textFieldCell = cell as? TextFieldCell {
Expand Down Expand Up @@ -667,6 +648,28 @@ class AccountSetupController: UITableViewController, ProgressAlertHandler {
}
}

// MARK: - Notifications

@objc private func handleConfigurationProgress(_ notification: Notification) {
guard let ui = notification.userInfo else { return }

if let error = ui["error"] as? Bool, error {
self.dcAccounts.startIo()
var errorMessage = ui["errorMessage"] as? String
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
if let reachability = appDelegate.reachability, reachability.connection == .unavailable {
errorMessage = String.localized("login_error_no_internet_connection")
}
}
self.updateProgressAlert(error: errorMessage)
} else if let done = ui["done"] as? Bool, done {
self.dcAccounts.startIo()
self.updateProgressAlertSuccess(completion: self.handleLoginSuccess)
} else {
self.updateProgressAlertValue(value: ui["progress"] as? Int)
}
}

// MARK: - coordinator

private func showLogViewController() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class InstantOnboardingViewController: UIViewController, ProgressAlertHandler {

// MARK: - action: configuration
@objc private func acceptAndCreateButtonPressed() {
addProgressAlertListener(dcAccounts: self.dcAccounts, progressName: eventConfigureProgress, onSuccess: self.handleCreateSuccess)
addProgressAlertListener(dcAccounts: self.dcAccounts, progressName: .configurationProgress, onSuccess: self.handleCreateSuccess)
showProgressAlert(title: String.localized("add_account"), dcContext: self.dcContext)

DispatchQueue.global().async { [weak self] in
Expand Down
Loading
Loading