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

Scroll to bottom when scrolled to bottom #2231

Merged
merged 6 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions DcCore/DcCore/DC/events.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import UIKit
import UserNotifications

public let eventMsgsChangedReadDeliveredFailed = Notification.Name(rawValue: "eventMsgsChangedReadDeliveredFailed")
extension Notification.Name {
public static let messageChanged = Notification.Name(rawValue: "eventMsgsChanged")
public static let messageReadDeliveredFailedReaction = Notification.Name(rawValue: "messageReadDeliveredFailedReaction")
}

public let eventIncomingMsg = Notification.Name(rawValue: "eventIncomingMsg")
public let eventIncomingMsgAnyAccount = Notification.Name(rawValue: "eventIncomingMsgAnyAccount")
public let eventImexProgress = Notification.Name(rawValue: "eventImexProgress")
Expand Down Expand Up @@ -67,14 +71,23 @@ public class DcEventHandler {
"errorMessage": self.dcAccounts.get(id: accountId).lastErrorString,
])
}
case DC_EVENT_MSGS_CHANGED:
guard accountId == dcAccounts.getSelected().id else { return }

case DC_EVENT_MSGS_CHANGED, DC_EVENT_REACTIONS_CHANGED, DC_EVENT_MSG_READ, DC_EVENT_MSG_DELIVERED, DC_EVENT_MSG_FAILED:
if accountId != dcAccounts.getSelected().id {
return
}
logger.info("📡[\(accountId)] msgs changed: \(data1), \(data2)")
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventMsgsChangedReadDeliveredFailed, object: nil, userInfo: [
NotificationCenter.default.post(name: .messageChanged, object: nil, userInfo: [
"message_id": Int(data2),
"chat_id": Int(data1),
])
}

case DC_EVENT_REACTIONS_CHANGED, DC_EVENT_MSG_READ, DC_EVENT_MSG_DELIVERED, DC_EVENT_MSG_FAILED:
guard accountId == dcAccounts.getSelected().id else { return }

logger.info("📡[\(accountId)] msgs reaction/read/delivered/failed: \(data1), \(data2)")
DispatchQueue.main.async {
NotificationCenter.default.post(name: .messageReadDeliveredFailedReaction, object: nil, userInfo: [
"message_id": Int(data2),
"chat_id": Int(data1),
])
Expand Down
2 changes: 1 addition & 1 deletion deltachat-ios/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
if let userDefaults = UserDefaults.shared, userDefaults.bool(forKey: UserDefaults.hasExtensionAttemptedToSend) {
userDefaults.removeObject(forKey: UserDefaults.hasExtensionAttemptedToSend)
DispatchQueue.main.async {
NotificationCenter.default.post(name: eventMsgsChangedReadDeliveredFailed, object: nil, userInfo: [
NotificationCenter.default.post(name: .messageChanged, object: nil, userInfo: [
"message_id": Int(0),
"chat_id": Int(0),
])
Expand Down
86 changes: 65 additions & 21 deletions deltachat-ios/Chat/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {
private var dcContext: DcContext
private var messageIds: [Int] = []
private var msgChangedObserver: NSObjectProtocol?
private var msgReadDeliveredReactionFailedObserver: NSObjectProtocol?
private var incomingMsgObserver: NSObjectProtocol?
private var chatModifiedObserver: NSObjectProtocol?
private var ephemeralTimerModifiedObserver: NSObjectProtocol?
Expand Down Expand Up @@ -415,34 +416,74 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {
}
}

// MARK: - Notifications

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

let chatId = ui["chat_id"] as? Int ?? 0
if chatId == 0 || chatId == self.chatId {
let messageId = ui["message_id"] as? Int ?? 0
if messageId > 0 {
let msg = self.dcContext.getMessage(id: messageId)
if msg.state == DC_STATE_OUT_DRAFT && msg.type == DC_MSG_WEBXDC {
draft.draftMsg = msg
configureDraftArea(draft: draft, animated: false)
return
}
}

if isLastRowScrolledToBottom() {
scrollToBottom(animated: true)
}

refreshMessages()
updateTitle()
markSeenMessagesInVisibleArea()

}
}

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

let chatId = ui["chat_id"] as? Int ?? 0
if chatId == 0 || chatId == self.chatId {
let messageId = ui["message_id"] as? Int ?? 0
if messageId > 0 {
let msg = self.dcContext.getMessage(id: messageId)
if msg.state == DC_STATE_OUT_DRAFT && msg.type == DC_MSG_WEBXDC {
draft.draftMsg = msg
configureDraftArea(draft: draft, animated: false)
return
}
}

refreshMessages()
updateTitle()
markSeenMessagesInVisibleArea()
}
}

private func setupObservers() {
let nc = NotificationCenter.default
if msgChangedObserver == nil {
msgChangedObserver = nc.addObserver(
forName: eventMsgsChangedReadDeliveredFailed,
forName: .messageChanged,
object: nil,
queue: OperationQueue.main
) { [weak self] notification in
self?.handleMessageChanged(notification)
}
}

guard let self, let ui = notification.userInfo else { return }
let chatId = ui["chat_id"] as? Int ?? 0
if chatId == 0 || chatId == self.chatId {
let messageId = ui["message_id"] as? Int ?? 0
if messageId > 0 {
let msg = self.dcContext.getMessage(id: messageId)
if msg.state == DC_STATE_OUT_DRAFT && msg.type == DC_MSG_WEBXDC {
draft.draftMsg = msg
configureDraftArea(draft: draft, animated: false)
return
}
}
refreshMessages()
updateTitle()
DispatchQueue.main.async {
self.updateScrollDownButtonVisibility()
}
markSeenMessagesInVisibleArea()
}
if msgReadDeliveredReactionFailedObserver == nil {
msgReadDeliveredReactionFailedObserver = nc.addObserver(
forName: .messageReadDeliveredFailedReaction,
object: nil,
queue: OperationQueue.main
) { [weak self] notification in
self?.handleMsgReadDeliveredReactionFailed(notification)
}
}

Expand Down Expand Up @@ -521,6 +562,9 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {
if let msgChangedObserver {
nc.removeObserver(msgChangedObserver)
}
if let msgReadDeliveredReactionFailedObserver {
nc.removeObserver(msgReadDeliveredReactionFailedObserver)
}
if let incomingMsgObserver {
nc.removeObserver(incomingMsgObserver)
}
Expand Down Expand Up @@ -1664,7 +1708,7 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {
guard let self else { return }
let message = self.dcContext.newMessage(viewType: DC_MSG_TEXT)
message.text = text
if let quoteMessage = quoteMessage {
if let quoteMessage {
message.quoteMessage = quoteMessage
}
self.dcContext.sendMessage(chatId: self.chatId, message: message)
Expand Down
32 changes: 21 additions & 11 deletions deltachat-ios/Controller/ChatListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class ChatListViewController: UITableViewController {
private var accountSwitchTransitioningDelegate: PartialScreenModalTransitioningDelegate!

private var msgChangedObserver: NSObjectProtocol?
private var msgReadDeliveredReactionFailedObserver: NSObjectProtocol?
private var msgsNoticedObserver: NSObjectProtocol?
private var incomingMsgObserver: NSObjectProtocol?
private var incomingMsgAnyAccountObserver: NSObjectProtocol?
Expand Down Expand Up @@ -202,7 +203,7 @@ class ChatListViewController: UITableViewController {
}

msgChangedSearchResultObserver = nc.addObserver(
forName: eventMsgsChangedReadDeliveredFailed,
forName: .messageChanged,
object: nil,
queue: nil) { [weak self] _ in
guard let self else { return }
Expand All @@ -215,7 +216,13 @@ class ChatListViewController: UITableViewController {
}

msgChangedObserver = nc.addObserver(
forName: eventMsgsChangedReadDeliveredFailed,
forName: .messageChanged,
object: nil,
queue: nil) { [weak self] _ in
self?.refreshInBg()
}
msgReadDeliveredReactionFailedObserver = nc.addObserver(
forName: .messageReadDeliveredFailedReaction,
object: nil,
queue: nil) { [weak self] _ in
self?.refreshInBg()
Expand Down Expand Up @@ -266,30 +273,33 @@ class ChatListViewController: UITableViewController {
private func removeObservers() {
let nc = NotificationCenter.default
// remove observers with a block
if let msgChangedResultObserver = self.msgChangedSearchResultObserver {
nc.removeObserver(msgChangedResultObserver)
if let msgChangedSearchResultObserver {
nc.removeObserver(msgChangedSearchResultObserver)
}
if let msgChangedObserver = self.msgChangedObserver {
if let msgChangedObserver {
nc.removeObserver(msgChangedObserver)
}
if let incomingMsgObserver = self.incomingMsgObserver {
if let incomingMsgObserver {
nc.removeObserver(incomingMsgObserver)
}
if let incomingMsgAnyAccountObserver = self.incomingMsgAnyAccountObserver {
if let incomingMsgAnyAccountObserver {
nc.removeObserver(incomingMsgAnyAccountObserver)
}
if let msgsNoticedObserver = self.msgsNoticedObserver {
if let msgsNoticedObserver {
nc.removeObserver(msgsNoticedObserver)
}
if let chatModifiedObserver = self.chatModifiedObserver {
if let chatModifiedObserver {
nc.removeObserver(chatModifiedObserver)
}
if let contactsChangedObserver = self.contactsChangedObserver {
if let contactsChangedObserver {
nc.removeObserver(contactsChangedObserver)
}
if let connectivityChangedObserver = self.connectivityChangedObserver {
if let connectivityChangedObserver {
nc.removeObserver(connectivityChangedObserver)
}
if let msgReadDeliveredReactionFailedObserver {
nc.removeObserver(msgReadDeliveredReactionFailedObserver)
}
// remove non-block observers
NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
Expand Down
7 changes: 6 additions & 1 deletion deltachat-ios/Controller/FilesViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class FilesViewController: UIViewController {
private let chatId: Int

private var msgChangedObserver: NSObjectProtocol?
private var msgReadDelivedReactionFailedObserver: NSObjectProtocol?
private var incomingMsgObserver: NSObjectProtocol?

private lazy var tableView: UITableView = {
Expand Down Expand Up @@ -84,7 +85,11 @@ class FilesViewController: UIViewController {

private func addObservers() {
msgChangedObserver = NotificationCenter.default.addObserver(
forName: eventMsgsChangedReadDeliveredFailed, object: nil, queue: nil) { [weak self] _ in
forName: .messageChanged, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
msgReadDelivedReactionFailedObserver = NotificationCenter.default.addObserver(
forName: .messageReadDeliveredFailedReaction, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
incomingMsgObserver = NotificationCenter.default.addObserver(
Expand Down
14 changes: 11 additions & 3 deletions deltachat-ios/Controller/GalleryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class GalleryViewController: UIViewController {
private let gridDefaultSpacing: CGFloat = 5

private var msgChangedObserver: NSObjectProtocol?
private var msgReadDeliveredReactionFailedObserver: NSObjectProtocol?
private var incomingMsgObserver: NSObjectProtocol?

private lazy var gridLayout: GridCollectionViewFlowLayout = {
Expand Down Expand Up @@ -106,8 +107,12 @@ class GalleryViewController: UIViewController {
}

private func addObservers() {
msgReadDeliveredReactionFailedObserver = NotificationCenter.default.addObserver(
forName: .messageReadDeliveredFailedReaction, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
msgChangedObserver = NotificationCenter.default.addObserver(
forName: eventMsgsChangedReadDeliveredFailed, object: nil, queue: nil) { [weak self] _ in
forName: .messageChanged, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
incomingMsgObserver = NotificationCenter.default.addObserver(
Expand All @@ -117,10 +122,13 @@ class GalleryViewController: UIViewController {
}

private func removeObservers() {
if let msgChangedObserver = self.msgChangedObserver {
if let msgChangedObserver {
NotificationCenter.default.removeObserver(msgChangedObserver)
}
if let incomingMsgObserver = self.incomingMsgObserver {
if let msgReadDeliveredReactionFailedObserver {
NotificationCenter.default.removeObserver(msgReadDeliveredReactionFailedObserver)
}
if let incomingMsgObserver {
NotificationCenter.default.removeObserver(incomingMsgObserver)
}
}
Expand Down
20 changes: 18 additions & 2 deletions deltachat-ios/Controller/WebxdcViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class WebxdcViewController: WebViewViewController {

var messageId: Int
var msgChangedObserver: NSObjectProtocol?
var msgReadDeliveredReactionFailedObserver: NSObjectProtocol?
var webxdcUpdateObserver: NSObjectProtocol?
var webxdcRealtimeDataObserver: NSObjectProtocol?
var webxdcName: String = ""
Expand Down Expand Up @@ -349,7 +350,7 @@ class WebxdcViewController: WebViewViewController {
}

msgChangedObserver = nc.addObserver(
forName: eventMsgsChangedReadDeliveredFailed,
forName: .messageChanged,
object: nil,
queue: OperationQueue.main
) { [weak self] notification in
Expand All @@ -358,6 +359,18 @@ class WebxdcViewController: WebViewViewController {
self.refreshWebxdcInfo()
}
}

msgReadDeliveredReactionFailedObserver = nc.addObserver(
forName: .messageReadDeliveredFailedReaction,
object: nil,
queue: OperationQueue.main
) { [weak self] notification in
guard let self, let messageId = notification.userInfo?["message_id"] as? Int else { return }
if messageId == self.messageId {
self.refreshWebxdcInfo()
}
}

}

private func removeObservers() {
Expand All @@ -368,9 +381,12 @@ class WebxdcViewController: WebViewViewController {
if let webxdcRealtimeDataObserver {
nc.removeObserver(webxdcRealtimeDataObserver)
}
if let msgChangedObserver = msgChangedObserver {
if let msgChangedObserver {
nc.removeObserver(msgChangedObserver)
}
if let msgReadDeliveredReactionFailedObserver {
nc.removeObserver(msgReadDeliveredReactionFailedObserver)
}
shortcutManager = nil
}

Expand Down
Loading