Skip to content

Commit

Permalink
Mark messages which were delivered to your another client as read #be…
Browse files Browse the repository at this point in the history
…agleim-73
  • Loading branch information
hantu85 committed May 30, 2019
1 parent 64c96e6 commit c1b580f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 17 deletions.
30 changes: 23 additions & 7 deletions BeagleIM/database/DBChatHistoryStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ import TigaseSwift
class DBChatHistoryStore {

static let MESSAGE_NEW = Notification.Name("messageAdded");
// TODO: it looks like it is not working as expected. We should remove this notification in the future
static let MESSAGES_MARKED_AS_READ = Notification.Name("messagesMarkedAsRead");
static let MESSAGE_UPDATED = Notification.Name("messageUpdated");
static var instance: DBChatHistoryStore = DBChatHistoryStore.init();

fileprivate let appendMessageStmt: DBStatement = try! DBConnection.main.prepareStatement("INSERT INTO chat_history (account, jid, timestamp, item_type, data, stanza_id, state, author_nickname, author_jid, encryption, fingerprint) VALUES (:account, :jid, :timestamp, :item_type, :data, :stanza_id, :state, :author_nickname, :author_jid, :encryption, :fingerprint)");
fileprivate let checkItemAlreadyAddedStmt: DBStatement = try! DBConnection.main.prepareStatement("SELECT count(id) FROM chat_history WHERE account = :account AND jid = :jid AND timestamp BETWEEN :ts_from AND :ts_to AND item_type = :item_type AND (:data IS NULL OR data = :data) AND (:stanza_id IS NULL OR (stanza_id IS NOT NULL AND stanza_id = :stanza_id)) AND (state % 2 == :direction) AND (:author_nickname is null OR author_nickname = :author_nickname)");
fileprivate let markAsReadStmt: DBStatement = try! DBConnection.main.prepareStatement("UPDATE chat_history SET state = case state when \(MessageState.incoming_error_unread.rawValue) then \(MessageState.incoming_error.rawValue) when \(MessageState.outgoing_error_unread.rawValue) then \(MessageState.outgoing_error.rawValue) else \(MessageState.incoming.rawValue) end WHERE account = :account AND jid = :jid AND state in (\(MessageState.incoming_unread.rawValue), \(MessageState.incoming_error_unread.rawValue), \(MessageState.outgoing_error_unread.rawValue))");
fileprivate let markMessageAsReadStmt: DBStatement = try! DBConnection.main.prepareStatement("UPDATE chat_history SET state = case state when \(MessageState.incoming_error_unread.rawValue) then \(MessageState.incoming_error.rawValue) when \(MessageState.outgoing_error_unread.rawValue) then \(MessageState.outgoing_error.rawValue) else \(MessageState.incoming.rawValue) end WHERE id = :id AND account = :account AND jid = :jid AND state in (\(MessageState.incoming_unread.rawValue), \(MessageState.incoming_error_unread.rawValue), \(MessageState.outgoing_error_unread.rawValue))");
fileprivate let updateItemStateStmt: DBStatement = try! DBConnection.main.prepareStatement("UPDATE chat_history SET state = :newState WHERE id = :id AND (:oldState IS NULL OR state = :oldState)");
fileprivate let updateItemStmt: DBStatement = try! DBConnection.main.prepareStatement("UPDATE chat_history SET preview = coalesce(:preview, preview) WHERE id = :id");
fileprivate let markAsErrorStmt: DBStatement = try! DBConnection.main.prepareStatement("UPDATE chat_history SET state = :state, error = :error WHERE id = :id");
Expand Down Expand Up @@ -101,14 +103,28 @@ class DBChatHistoryStore {
return true;
}

open func markAsRead(for account: BareJID, with jid: BareJID) {
open func markAsRead(for account: BareJID, with jid: BareJID, messageId: String? = nil) {
dispatcher.async {
let params: [String: Any?] = ["account": account, "jid": jid];
let updateRecords = try! self.markAsReadStmt.update(params);
if updateRecords > 0 {
DBChatStore.instance.markAsRead(for: account, with: jid);
DispatchQueue.main.async {
NotificationCenter.default.post(name: DBChatHistoryStore.MESSAGES_MARKED_AS_READ, object: self, userInfo: ["account": account, "jid": jid]);
if let id = messageId {
var params: [String: Any?] = ["account": account, "jid": jid, "stanza_id": id];
if let msgId = try! self.getItemIdByStanzaId.scalar(params) {
params = ["account": account, "jid": jid, "id": msgId];
let updateRecords = try! self.markMessageAsReadStmt.update(params);
if updateRecords > 0 {
DBChatStore.instance.markAsRead(for: account, with: jid, count: 1);
DispatchQueue.main.async {
NotificationCenter.default.post(name: DBChatHistoryStore.MESSAGES_MARKED_AS_READ, object: self, userInfo: ["account": account, "jid": jid]);
}
}
}
} else {
let params: [String: Any?] = ["account": account, "jid": jid];
let updateRecords = try! self.markAsReadStmt.update(params);
if updateRecords > 0 {
DBChatStore.instance.markAsRead(for: account, with: jid);
DispatchQueue.main.async {
NotificationCenter.default.post(name: DBChatHistoryStore.MESSAGES_MARKED_AS_READ, object: self, userInfo: ["account": account, "jid": jid]);
}
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions BeagleIM/database/DBChatStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,12 @@ open class DBChatStore {
}
}

func markAsRead(for account: BareJID, with jid: BareJID) {
func markAsRead(for account: BareJID, with jid: BareJID, count: Int? = nil) {
dispatcher.async {
if let chat = self.getChat(for: account, with: jid) {
let unread = chat.unread;
if chat.markAsRead() {
self.unreadMessagesCount = self.unreadMessagesCount - unread;
if chat.markAsRead(count: count ?? unread) {
self.unreadMessagesCount = self.unreadMessagesCount - (count ?? unread);
NotificationCenter.default.post(name: DBChatStore.CHAT_UPDATED, object: chat);
}
}
Expand Down Expand Up @@ -489,11 +489,11 @@ open class DBChatStore {
return true;
}

func markAsRead() -> Bool {
func markAsRead(count: Int) -> Bool {
guard unread > 0 else {
return false;
}
unread = 0;
unread = max(unread - count, 0);
return true
}

Expand Down Expand Up @@ -565,11 +565,11 @@ open class DBChatStore {
return true;
}

func markAsRead() -> Bool {
func markAsRead(count: Int) -> Bool {
guard unread > 0 else {
return false;
}
unread = 0;
unread = max(unread - count, 0);
return true
}

Expand All @@ -585,7 +585,7 @@ protocol DBChatProtocol: ChatProtocol {
var unread: Int { get }
var encryption: ChatEncryption? { get }

func markAsRead() -> Bool;
func markAsRead(count: Int) -> Bool;
func updateLastMessage(_ message: String?, timestamp: Date, isUnread: Bool) -> Bool;

}
Expand Down
9 changes: 9 additions & 0 deletions BeagleIM/service/MessageEventHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ class MessageEventHandler: XmppServiceEventHandler {
}
let (body, encryption,fingerprint) = MessageEventHandler.prepareBody(message: e.message, forAccount: account);
guard body != nil else {
if Settings.markMessageDeliveredToOtherResourceAsRead.bool(), let delivery = e.message.messageDelivery, e.action == .sent {
switch delivery {
case .received(let msgId):
DBChatHistoryStore.instance.markAsRead(for: from.bareJid, with: to.bareJid, messageId: msgId);
break;
default:
break;
}
}
return;
}
let jid = account == from.bareJid ? to.bareJid : from.bareJid;
Expand Down
11 changes: 9 additions & 2 deletions BeagleIM/settings/GeneralSettingsController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class GeneralSettingsController: NSViewController {

fileprivate var enableMessageCarbonsButton: NSButton!;
fileprivate var messageCarbonsMarkAsReadButton: NSButton!;

fileprivate var messageCarbonsMarkDeliveredToOtherResourceAsRead: NSButton!;

fileprivate var notificationsFromUnknownSenders: NSButton!;
fileprivate var systemMenuIcon: NSButton!;

Expand Down Expand Up @@ -68,7 +69,8 @@ class GeneralSettingsController: NSViewController {

enableMessageCarbonsButton = formView.addRow(label: "Message carbons:", field: NSButton(checkboxWithTitle: "Enable", target: self, action: #selector(checkboxChanged(_:))));
messageCarbonsMarkAsReadButton = formView.addRow(label: "", field: NSButton(checkboxWithTitle: "Mark carbon messages as read", target: self, action: #selector(checkboxChanged(_:))));
formView.groupItems(from: enableMessageCarbonsButton, to: messageCarbonsMarkAsReadButton);
messageCarbonsMarkDeliveredToOtherResourceAsRead = formView.addRow(label: "", field: NSButton(checkboxWithTitle: "Mark messages confirmed as delivered to another client as read", target: self, action: #selector(checkboxChanged(_:))));
formView.groupItems(from: enableMessageCarbonsButton, to: messageCarbonsMarkDeliveredToOtherResourceAsRead);

encryptionButton = formView.addRow(label: "Default encryption:", field: NSPopUpButton(frame: .zero, pullsDown: false));
encryptionButton?.target = self;
Expand Down Expand Up @@ -121,6 +123,8 @@ class GeneralSettingsController: NSViewController {
enableMessageCarbonsButton.state = Settings.enableMessageCarbons.bool() ? .on : .off;
messageCarbonsMarkAsReadButton.state = Settings.markMessageCarbonsAsRead.bool() ? .on : .off;
messageCarbonsMarkAsReadButton.isEnabled = Settings.enableMessageCarbons.bool();
messageCarbonsMarkDeliveredToOtherResourceAsRead.state = Settings.markMessageDeliveredToOtherResourceAsRead.bool() ? .on : .off;
messageCarbonsMarkDeliveredToOtherResourceAsRead.isEnabled = Settings.enableMessageCarbons.bool();
notificationsFromUnknownSenders.state = Settings.notificationsFromUnknownSenders.bool() ? .on : .off;
markdownFormatting.state = Settings.enableMarkdownFormatting.bool() ? .on : .off;
showEmoticons.state = Settings.showEmoticons.bool() ? .on : .off;
Expand Down Expand Up @@ -155,8 +159,11 @@ class GeneralSettingsController: NSViewController {
case enableMessageCarbonsButton:
Settings.enableMessageCarbons.set(value: sender.state == .on);
messageCarbonsMarkAsReadButton.isEnabled = sender.state == .on;
messageCarbonsMarkDeliveredToOtherResourceAsRead.isEnabled = sender.state == .on;
case messageCarbonsMarkAsReadButton:
Settings.markMessageCarbonsAsRead.set(value: sender.state == .on);
case messageCarbonsMarkDeliveredToOtherResourceAsRead:
Settings.markMessageDeliveredToOtherResourceAsRead.set(value: sender.state == .on);
case notificationsFromUnknownSenders:
Settings.notificationsFromUnknownSenders.set(value: sender.state == .on);
case systemMenuIcon:
Expand Down
1 change: 1 addition & 0 deletions BeagleIM/utils/Settings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum Settings: String {

case enableMessageCarbons
case markMessageCarbonsAsRead
case markMessageDeliveredToOtherResourceAsRead
case enableBookmarksSync
case imageDownloadSizeLimit

Expand Down

0 comments on commit c1b580f

Please sign in to comment.