Skip to content

Commit

Permalink
refresh file/gallery-view when messages change
Browse files Browse the repository at this point in the history
  • Loading branch information
r10s committed May 4, 2023
1 parent 7c3cdb9 commit b326193
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 29 deletions.
2 changes: 0 additions & 2 deletions deltachat-ios/Controller/ChatListController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,8 @@ class ChatListController: UITableViewController {
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil {
// logger.debug("chat observer: remove")
removeObservers()
} else {
// logger.debug("chat observer: setup")
addObservers()
}
}
Expand Down
76 changes: 64 additions & 12 deletions deltachat-ios/Controller/FilesViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class FilesViewController: UIViewController {
private let dcContext: DcContext
private let chatId: Int

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

private lazy var tableView: UITableView = {
let table = UITableView(frame: .zero, style: .plain)
table.register(DocumentGalleryFileCell.self, forCellReuseIdentifier: DocumentGalleryFileCell.reuseIdentifier)
Expand Down Expand Up @@ -83,14 +86,25 @@ class FilesViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupSubviews()
loadMediaAsync()
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
self?.refreshDataFromBgThread()
}
}

override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil {
removeObservers()
} else {
addObservers()
}
}

override func viewWillAppear(_ animated: Bool) {
setupContextMenuIfNeeded()
}

// MARK: - layout
// MARK: - setup
private func setupSubviews() {
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
Expand All @@ -107,20 +121,58 @@ class FilesViewController: UIViewController {
UIMenuController.shared.update()
}

private func loadMediaAsync() {
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
guard let self = self else { return }
let ids: [Int]
ids = self.dcContext.getChatMedia(chatId: self.chatId, messageType: self.type1, messageType2: self.type2, messageType3: self.type3).reversed()
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.fileMessageIds = ids
self.emptyStateView.isHidden = !ids.isEmpty
self.tableView.reloadData()
private func addObservers() {
msgChangedObserver = NotificationCenter.default.addObserver(
forName: dcNotificationChanged, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
incomingMsgObserver = NotificationCenter.default.addObserver(
forName: dcNotificationIncoming, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
}

private func removeObservers() {
if let msgChangedObserver = self.msgChangedObserver {
NotificationCenter.default.removeObserver(msgChangedObserver)
}
if let incomingMsgObserver = self.incomingMsgObserver {
NotificationCenter.default.removeObserver(incomingMsgObserver)
}
}

private var inBgRefresh = false
private var needsAnotherBgRefresh = false
private func refreshInBg() {
if inBgRefresh {
needsAnotherBgRefresh = true
} else {
inBgRefresh = true
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
self?.needsAnotherBgRefresh = false
self?.refreshDataFromBgThread()
while self?.needsAnotherBgRefresh != false {
usleep(500000)
self?.needsAnotherBgRefresh = false
self?.refreshDataFromBgThread()
}
self?.inBgRefresh = false
}
}
}

private func refreshDataFromBgThread() {
// may take a moment, should not be called from main thread
let ids: [Int]
ids = self.dcContext.getChatMedia(chatId: self.chatId, messageType: self.type1, messageType2: self.type2, messageType3: self.type3).reversed()
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.fileMessageIds = ids
self.emptyStateView.isHidden = !ids.isEmpty
self.tableView.reloadData()
}
}

// MARK: - actions
private func askToDeleteItem(at indexPath: IndexPath) {
let chat = dcContext.getChat(chatId: chatId)
Expand Down
79 changes: 64 additions & 15 deletions deltachat-ios/Controller/GalleryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import QuickLook
class GalleryViewController: UIViewController {

private let dcContext: DcContext
// MARK: - data
private let chatId: Int
private var mediaMessageIds: [Int] = []
private var galleryItemCache: [Int: GalleryItem] = [:]

// MARK: - subview specs
private let gridDefaultSpacing: CGFloat = 5

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

private lazy var gridLayout: GridCollectionViewFlowLayout = {
let layout = GridCollectionViewFlowLayout()
layout.minimumLineSpacing = gridDefaultSpacing
Expand Down Expand Up @@ -87,7 +87,18 @@ class GalleryViewController: UIViewController {
super.viewDidLoad()
setupSubviews()
title = String.localized("images_and_videos")
loadMediaAsync()
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
self?.refreshDataFromBgThread()
}
}

override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil {
removeObservers()
} else {
addObservers()
}
}

override func viewWillAppear(_ animated: Bool) {
Expand Down Expand Up @@ -129,18 +140,56 @@ class GalleryViewController: UIViewController {
UIMenuController.shared.update()
}

private func loadMediaAsync() {
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
guard let self = self else { return }
let ids: [Int]
ids = self.dcContext.getChatMedia(chatId: self.chatId, messageType: DC_MSG_IMAGE, messageType2: DC_MSG_GIF, messageType3: DC_MSG_VIDEO).reversed()
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.galleryItemCache = [:]
self.mediaMessageIds = ids
self.emptyStateView.isHidden = !ids.isEmpty
self.grid.reloadData()
private func addObservers() {
msgChangedObserver = NotificationCenter.default.addObserver(
forName: dcNotificationChanged, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
incomingMsgObserver = NotificationCenter.default.addObserver(
forName: dcNotificationIncoming, object: nil, queue: nil) { [weak self] _ in
self?.refreshInBg()
}
}

private func removeObservers() {
if let msgChangedObserver = self.msgChangedObserver {
NotificationCenter.default.removeObserver(msgChangedObserver)
}
if let incomingMsgObserver = self.incomingMsgObserver {
NotificationCenter.default.removeObserver(incomingMsgObserver)
}
}

private var inBgRefresh = false
private var needsAnotherBgRefresh = false
private func refreshInBg() {
if inBgRefresh {
needsAnotherBgRefresh = true
} else {
inBgRefresh = true
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
self?.needsAnotherBgRefresh = false
self?.refreshDataFromBgThread()
while self?.needsAnotherBgRefresh != false {
usleep(500000)
self?.needsAnotherBgRefresh = false
self?.refreshDataFromBgThread()
}
self?.inBgRefresh = false
}
}
}

private func refreshDataFromBgThread() {
// may take a moment, should not be called from main thread
let ids: [Int]
ids = self.dcContext.getChatMedia(chatId: self.chatId, messageType: DC_MSG_IMAGE, messageType2: DC_MSG_GIF, messageType3: DC_MSG_VIDEO).reversed()
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.galleryItemCache = [:]
self.mediaMessageIds = ids
self.emptyStateView.isHidden = !ids.isEmpty
self.grid.reloadData()
}
}

Expand Down

0 comments on commit b326193

Please sign in to comment.