- #57 Implemented XEP-0172 User Nickname
- Added New Column 'nickname' in roster_items Table - DB version changed from 13 to 14
This commit is contained in:
parent
d10c7842d3
commit
c26d44cd96
|
@ -24,7 +24,7 @@ import TigaseSwift
|
|||
|
||||
public class DBSchemaManager {
|
||||
|
||||
static let CURRENT_VERSION = 13;
|
||||
static let CURRENT_VERSION = 14;
|
||||
|
||||
fileprivate let dbConnection: DBConnection;
|
||||
|
||||
|
|
7
Shared/db-schema-14.sql
Normal file
7
Shared/db-schema-14.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
BEGIN;
|
||||
|
||||
ALTER TABLE roster_items ADD COLUMN nickname TEXT;
|
||||
|
||||
COMMIT;
|
||||
|
||||
PRAGMA user_version = 14;
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E928AD4326D6A08A00F29F93 /* db-schema-14.sql in Resources */ = {isa = PBXBuildFile; fileRef = E928AD4226D6A08A00F29F93 /* db-schema-14.sql */; };
|
||||
E95AA70226D38B6F00A38D44 /* DisplayNameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95AA70126D38B6E00A38D44 /* DisplayNameViewController.swift */; };
|
||||
E963721026D786D000332482 /* BlockingCommandModuleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E963720F26D786D000332482 /* BlockingCommandModuleExtension.swift */; };
|
||||
E963721226D79D3A00332482 /* PrivacyPolicyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E963721126D79D3A00332482 /* PrivacyPolicyTableViewCell.swift */; };
|
||||
|
@ -14,6 +15,7 @@
|
|||
E9D384B426CA95FF009BEAF3 /* UIDeviceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D384B326CA95FF009BEAF3 /* UIDeviceExtension.swift */; };
|
||||
E9D384B626CBB606009BEAF3 /* CustomUISlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D384B526CBB606009BEAF3 /* CustomUISlider.swift */; };
|
||||
E9D384B826CBBEB6009BEAF3 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D384B726CBBEB6009BEAF3 /* Extensions.swift */; };
|
||||
E9EC2B3326D554C000222BB9 /* PEPDisplayNameModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9EC2B3226D554C000222BB9 /* PEPDisplayNameModule.swift */; };
|
||||
FE00157D2017617B00490340 /* StreamFeaturesCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE00157C2017617B00490340 /* StreamFeaturesCache.swift */; };
|
||||
FE00157F2019090300490340 /* ExperimentalSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE00157E2019090300490340 /* ExperimentalSettingsViewController.swift */; };
|
||||
FE01ADA91E224CF400FA7E65 /* SiskinPushNotificationsModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE01ADA81E224CF400FA7E65 /* SiskinPushNotificationsModule.swift */; };
|
||||
|
@ -291,6 +293,7 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
E928AD4226D6A08A00F29F93 /* db-schema-14.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = "db-schema-14.sql"; sourceTree = "<group>"; };
|
||||
E95AA70126D38B6E00A38D44 /* DisplayNameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameViewController.swift; sourceTree = "<group>"; };
|
||||
E963720F26D786D000332482 /* BlockingCommandModuleExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockingCommandModuleExtension.swift; sourceTree = "<group>"; };
|
||||
E963721126D79D3A00332482 /* PrivacyPolicyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyTableViewCell.swift; sourceTree = "<group>"; };
|
||||
|
@ -298,6 +301,7 @@
|
|||
E9D384B326CA95FF009BEAF3 /* UIDeviceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDeviceExtension.swift; sourceTree = "<group>"; };
|
||||
E9D384B526CBB606009BEAF3 /* CustomUISlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomUISlider.swift; sourceTree = "<group>"; };
|
||||
E9D384B726CBBEB6009BEAF3 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
|
||||
E9EC2B3226D554C000222BB9 /* PEPDisplayNameModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PEPDisplayNameModule.swift; sourceTree = "<group>"; };
|
||||
FE00157C2017617B00490340 /* StreamFeaturesCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamFeaturesCache.swift; sourceTree = "<group>"; };
|
||||
FE00157E2019090300490340 /* ExperimentalSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExperimentalSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
FE01ADA81E224CF400FA7E65 /* SiskinPushNotificationsModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SiskinPushNotificationsModule.swift; sourceTree = "<group>"; };
|
||||
|
@ -794,6 +798,7 @@
|
|||
FEC79198241BE89E007BE572 /* db-schema-11.sql */,
|
||||
FE3BA0BF24B61583000C80D4 /* db-schema-12.sql */,
|
||||
FEBC12F124C70DE000689475 /* db-schema-13.sql */,
|
||||
E928AD4226D6A08A00F29F93 /* db-schema-14.sql */,
|
||||
);
|
||||
path = Shared;
|
||||
sourceTree = "<group>";
|
||||
|
@ -906,6 +911,7 @@
|
|||
FE75A00E2375F324001E78D9 /* PushEventHandler.swift */,
|
||||
FEDC6789238A9F16005C0FAB /* BlockedEventHandler.swift */,
|
||||
FE3E3879242765E700D3A8E8 /* MixEventHandler.swift */,
|
||||
E9EC2B3226D554C000222BB9 /* PEPDisplayNameModule.swift */,
|
||||
E963720F26D786D000332482 /* BlockingCommandModuleExtension.swift */,
|
||||
);
|
||||
path = service;
|
||||
|
@ -1179,6 +1185,7 @@
|
|||
FECEF29823B7B838007EC323 /* db-schema-9.sql in Resources */,
|
||||
FE3BA0C024B61583000C80D4 /* db-schema-12.sql in Resources */,
|
||||
FE759FF02371F21C001E78D9 /* db-schema-4.sql in Resources */,
|
||||
E928AD4326D6A08A00F29F93 /* db-schema-14.sql in Resources */,
|
||||
FE759FF32371F21C001E78D9 /* db-schema-7.sql in Resources */,
|
||||
FE759FF12371F21C001E78D9 /* db-schema-5.sql in Resources */,
|
||||
FE759FF523741527001E78D9 /* db-schema-8.sql in Resources */,
|
||||
|
@ -1302,6 +1309,7 @@
|
|||
FE3A45CF1CE49D3300C36264 /* RosterItemEditViewController.swift in Sources */,
|
||||
FEE49DD7242688E100900BBB /* ChannelViewController.swift in Sources */,
|
||||
FE507A211CDB7B3B001A015C /* SettingsViewController.swift in Sources */,
|
||||
E9EC2B3326D554C000222BB9 /* PEPDisplayNameModule.swift in Sources */,
|
||||
FE507A191CDB7B3B001A015C /* DBChatHistoryStore.swift in Sources */,
|
||||
FEA8D65D1F2F6AF60077C12F /* VCardEntryTypeAwareTableViewCell.swift in Sources */,
|
||||
FEBC12F524C70E7F00689475 /* DBChatHistorySyncStore.swift in Sources */,
|
||||
|
|
|
@ -509,11 +509,7 @@ class ChatTitleView: UIView {
|
|||
|
||||
|
||||
func reload(for account: BareJID, with jid: BareJID) {
|
||||
if let rosterModule: RosterModule = XmppService.instance.getClient(for: account)?.modulesManager.getModule(RosterModule.ID) {
|
||||
self.name = rosterModule.rosterStore.get(for: JID(jid))?.name ?? jid.stringValue;
|
||||
} else {
|
||||
self.name = jid.stringValue;
|
||||
}
|
||||
self.name = PEPDisplayNameModule.getDisplayName(account: account, for: jid)
|
||||
self.encryption = (DBChatStore.instance.getChat(for: account, with: jid) as? DBChat)?.options.encryption;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,10 +118,8 @@ class ChatsListViewController: UITableViewController {
|
|||
cell.nameLabel.text = channel.name ?? item.jid.localPart ?? item.jid.stringValue;
|
||||
cell.avatarStatusView.setStatus(channel.state == .joined ? Presence.Show.online : nil)
|
||||
default:
|
||||
let rosterModule: RosterModule? = xmppClient?.modulesManager.getModule(RosterModule.ID);
|
||||
let rosterItem = rosterModule?.rosterStore.get(for: item.jid);
|
||||
let name = rosterItem?.name ?? item.jid.bareJid.stringValue;
|
||||
cell.nameLabel.text = name;
|
||||
let name = PEPDisplayNameModule.getDisplayName(account: item.account, for: BareJID(item.jid))
|
||||
cell.nameLabel.text = name
|
||||
cell.avatarStatusView.set(name: name, avatar: AvatarManager.instance.avatar(for: item.jid.bareJid, on: item.account), orDefault: AvatarManager.instance.defaultAvatar);
|
||||
let presenceModule: PresenceModule? = xmppClient?.modulesManager.getModule(PresenceModule.ID);
|
||||
let presence = presenceModule?.presenceStore.getBestPresence(for: item.jid.bareJid);
|
||||
|
@ -471,6 +469,7 @@ class ChatsListViewController: UITableViewController {
|
|||
NotificationCenter.default.addObserver(self, selector: #selector(chatOpened), name: DBChatStore.CHAT_OPENED, object: nil);
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(chatClosed), name: DBChatStore.CHAT_CLOSED, object: nil);
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(chatUpdated), name: DBChatStore.CHAT_UPDATED, object: nil);
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(nickChanged(_:)), name: NickChangeEventHandler.NICK_CHANGED, object: nil)
|
||||
|
||||
applyActionsQueue.async {
|
||||
DispatchQueue.main.sync {
|
||||
|
@ -499,6 +498,11 @@ class ChatsListViewController: UITableViewController {
|
|||
self.refreshItem(for: account, with: jid);
|
||||
}
|
||||
|
||||
@objc func nickChanged(_ notification: Notification) {
|
||||
guard let account = notification.userInfo?["account"] as? BareJID, let jid = notification.userInfo?["jid"] as? BareJID else { return }
|
||||
self.refreshItem(for: account, with: jid)
|
||||
}
|
||||
|
||||
@objc func chatOpened(_ notification: Notification) {
|
||||
guard let opened = notification.object as? DBChatProtocol else {
|
||||
return;
|
||||
|
@ -563,26 +567,6 @@ class ChatsListViewController: UITableViewController {
|
|||
print("XX: executing for", actions.count, "actions");
|
||||
|
||||
var store = DispatchQueue.main.sync { return self.store };
|
||||
|
||||
// let removeIndexes = store.indexes(for: actions.filter { (item) -> Bool in
|
||||
// item.action == .remove;
|
||||
// });
|
||||
// let refreshActions = actions.filter { (item) -> Bool in
|
||||
// item.action == .refresh;
|
||||
// };
|
||||
// let refreshIndexes = store.indexes(for: refreshActions);
|
||||
//
|
||||
// store.remove(for: removeIndexes);
|
||||
//
|
||||
// let addActions = actions.filter { (item) -> Bool in
|
||||
// return item.action == .add;
|
||||
// }
|
||||
//
|
||||
// addActions.forEach { (item) in
|
||||
// _ = store.add(for: item)
|
||||
// }
|
||||
//
|
||||
// let addIndexes = store.indexes(for: addActions + refreshActions);
|
||||
|
||||
let removeIndexes = store.indexes(for: actions);
|
||||
|
||||
|
|
|
@ -120,6 +120,9 @@ open class DBRosterStore: RosterCacheProvider {
|
|||
fileprivate let insertItemGroupStmt: DBStatement;
|
||||
fileprivate let deleteItemGroupsStmt: DBStatement;
|
||||
|
||||
fileprivate let updateNicknameStmt: DBStatement
|
||||
fileprivate let getNicknameStmt: DBStatement
|
||||
|
||||
public init() {
|
||||
self.dispatcher = QueueDispatcher(label: "db_roster_store");
|
||||
|
||||
|
@ -135,9 +138,28 @@ open class DBRosterStore: RosterCacheProvider {
|
|||
insertItemGroupStmt = try! DBConnection.main.prepareStatement("INSERT INTO roster_items_groups (item_id, group_id) VALUES (:item_id, :group_id)");
|
||||
deleteItemGroupsStmt = try! DBConnection.main.prepareStatement("DELETE FROM roster_items_groups WHERE item_id = :item_id");
|
||||
|
||||
updateNicknameStmt = try! DBConnection.main.prepareStatement("UPDATE roster_items SET nickname = :nickname WHERE jid = :jid")
|
||||
getNicknameStmt = try! DBConnection.main.prepareStatement("SELECT nickname FROM roster_items WHERE jid = :jid")
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(DBRosterStore.accountRemoved), name: NSNotification.Name(rawValue: "accountRemoved"), object: nil);
|
||||
}
|
||||
|
||||
func updateNick(jid: String, nick: String) {
|
||||
dispatcher.sync {
|
||||
let params: [String: Any?] = ["jid": jid, "nickname": nick]
|
||||
_ = try! self.updateNicknameStmt.update(params)
|
||||
}
|
||||
}
|
||||
|
||||
func getNickname(jid: String) -> String? {
|
||||
dispatcher.sync {
|
||||
let params: [String: Any?] = ["jid":jid]
|
||||
return try! getNicknameStmt.queryFirstMatching(params) { cursor in
|
||||
return cursor["nickname"] as String?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getAll(for account: BareJID) -> [DBRosterItem] {
|
||||
return dispatcher.sync {
|
||||
let params: [String: Any?] = ["account": account];
|
||||
|
|
|
@ -39,26 +39,23 @@ class RosterItemEditViewController: UITableViewController, UIPickerViewDataSourc
|
|||
override func viewDidLoad() {
|
||||
xmppService = (UIApplication.shared.delegate as! AppDelegate).xmppService;
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view
|
||||
|
||||
let accountPicker = UIPickerView();
|
||||
accountPicker.dataSource = self;
|
||||
accountPicker.delegate = self;
|
||||
self.accountTextField.inputView = accountPicker;
|
||||
// self.accountTextField.addTarget(self, action: #selector(RosterItemEditViewController.textFieldDidChange), for: UIControlEvents.editingChanged);
|
||||
// self.jidTextField.addTarget(self, action: #selector(RosterItemEditViewController.textFieldDidChange), for: UIControlEvents.editingChanged);
|
||||
self.jidTextField.text = jid?.stringValue;
|
||||
self.accountTextField.text = account?.stringValue;
|
||||
self.sendPresenceUpdatesSwitch.isOn = true;
|
||||
self.receivePresenceUpdatesSwitch.isOn = true;//Settings.AutoSubscribeOnAcceptedSubscriptionRequest.getBool();
|
||||
if account != nil && jid != nil {
|
||||
self.receivePresenceUpdatesSwitch.isOn = true //Settings.AutoSubscribeOnAcceptedSubscriptionRequest.getBool();
|
||||
if let account = account, let jid = jid {
|
||||
self.jidTextField.isEnabled = false;
|
||||
self.accountTextField.isEnabled = false;
|
||||
|
||||
if let sessionObject = xmppService.getClient(forJid: account!)?.sessionObject {
|
||||
if let sessionObject = xmppService.getClient(forJid: account)?.sessionObject {
|
||||
let rosterStore: RosterStore = RosterModule.getRosterStore(sessionObject)
|
||||
if let rosterItem = rosterStore.get(for: jid!) {
|
||||
self.nameTextField.text = rosterItem.name;
|
||||
if let rosterItem = rosterStore.get(for: jid) {
|
||||
self.nameTextField.text = PEPDisplayNameModule.getDisplayName(account: account, for: BareJID(jid))
|
||||
self.sendPresenceUpdatesSwitch.isOn = rosterItem.subscription.isFrom;
|
||||
self.receivePresenceUpdatesSwitch.isOn = rosterItem.subscription.isTo;
|
||||
}
|
||||
|
@ -77,18 +74,6 @@ class RosterItemEditViewController: UITableViewController, UIPickerViewDataSourc
|
|||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
// func textFieldDidChange(_ textField: UITextField) {
|
||||
// if textField.text?.isEmpty != false {
|
||||
// textField.superview?.backgroundColor = UIColor.red;
|
||||
//// textField.layer.borderColor = UIColor.red.cgColor;
|
||||
//// textField.layer.borderWidth = 1;
|
||||
// } else {
|
||||
//// textField.layer.borderColor = UIColor(white: 1, alpha: 1).cgColor;
|
||||
//// textField.layer.borderWidth = 0;
|
||||
// textField.superview?.backgroundColor = UIColor.white;
|
||||
// }
|
||||
// }
|
||||
|
||||
@IBAction func saveBtnClicked(_ sender: UIBarButtonItem) {
|
||||
saveChanges()
|
||||
}
|
||||
|
@ -196,15 +181,6 @@ class RosterItemEditViewController: UITableViewController, UIPickerViewDataSourc
|
|||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||
// Get the new view controller using segue.destinationViewController.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
return 1;
|
||||
|
|
|
@ -46,6 +46,7 @@ class RosterViewController: AbstractRosterViewController, UIGestureRecognizerDel
|
|||
updateNavBarColors();
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(settingsChanged(_:)), name: Settings.SETTINGS_CHANGED, object: nil);
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.nickChanged(_:)), name: NickChangeEventHandler.NICK_CHANGED, object: nil)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
@ -111,6 +112,19 @@ class RosterViewController: AbstractRosterViewController, UIGestureRecognizerDel
|
|||
}
|
||||
}
|
||||
|
||||
@objc func nickChanged(_ notification: Notification) {
|
||||
guard let account = notification.userInfo?["account"] as? BareJID, let jid = notification.userInfo?["jid"] as? BareJID else { return }
|
||||
|
||||
if let sessionObject = XmppService.instance.getClient(forJid: account)?.sessionObject {
|
||||
let rosterStore: RosterStore = RosterModule.getRosterStore(sessionObject)
|
||||
if let rosterItem = rosterStore.get(for: JID(jid)), rosterItem.name == nil {
|
||||
DispatchQueue.main.async {
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func initializeRosterProvider(availableOnly: Bool, sortOrder: RosterSortingOrder) {
|
||||
let order = RosterSortingOrder(rawValue: Settings.RosterItemsOrder.getString() ?? "") ?? .alphabetical;
|
||||
super.initializeRosterProvider(availableOnly: false, sortOrder: order);
|
||||
|
@ -128,7 +142,7 @@ class RosterViewController: AbstractRosterViewController, UIGestureRecognizerDel
|
|||
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! RosterItemTableViewCell;
|
||||
|
||||
if let item = roster?.item(at: indexPath) {
|
||||
cell.nameLabel.text = item.displayName;
|
||||
cell.nameLabel.text = PEPDisplayNameModule.getDisplayName(account: item.account, for: BareJID(item.jid))
|
||||
cell.statusLabel.text = item.presence?.status ?? item.jid.stringValue;
|
||||
cell.avatarStatusView.setStatus(item.presence?.show);
|
||||
cell.avatarStatusView.set(name: item.displayName, avatar: AvatarManager.instance.avatar(for: item.jid.bareJid, on: item.account), orDefault: AvatarManager.instance.defaultAvatar);
|
||||
|
|
152
Snikket/service/PEPDisplayNameModule.swift
Normal file
152
Snikket/service/PEPDisplayNameModule.swift
Normal file
|
@ -0,0 +1,152 @@
|
|||
//
|
||||
// PEPDisplayNameModule.swift
|
||||
// Snikket
|
||||
//
|
||||
// Created by Khalid Khan on 8/24/21.
|
||||
// Copyright © 2021 Snikket. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import TigaseSwift
|
||||
|
||||
class PEPDisplayNameModule: AbstractPEPModule {
|
||||
|
||||
public static let ID = "NICKNAME"
|
||||
|
||||
public static let XMLNS = "http://jabber.org/protocol/nick"
|
||||
|
||||
public static let PUBSUB_XMLNS = "http://jabber.org/protocol/pubsub";
|
||||
public static let PUBSUB_EVENT_XMLNS = PUBSUB_XMLNS + "#event";
|
||||
|
||||
public static let FEATURES: [String] = [XMLNS + "+notify"]
|
||||
|
||||
var id = ID
|
||||
|
||||
var criteria = Criteria.name("message").add(Criteria.name("event", xmlns: PUBSUB_EVENT_XMLNS));
|
||||
|
||||
var features: [String] = FEATURES
|
||||
|
||||
func process(stanza: Stanza) throws {
|
||||
throw ErrorCondition.bad_request
|
||||
}
|
||||
|
||||
var context: Context!{
|
||||
didSet {
|
||||
if oldValue != nil {
|
||||
oldValue.eventBus.unregister(handler: self, for: PubSubModule.NotificationReceivedEvent.TYPE);
|
||||
}
|
||||
if context != nil {
|
||||
context.eventBus.register(handler: self, for: PubSubModule.NotificationReceivedEvent.TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func publishNick(nick: String, userJID: JID, completion: @escaping (Bool)->Void) {
|
||||
guard let pubsubModule: PubSubModule = context.modulesManager.getModule(PubSubModule.ID) else {
|
||||
print("Required PubSubModule is not registered!")
|
||||
return
|
||||
}
|
||||
|
||||
let payload = Element(name: "nick", cdata: nick, xmlns: PEPDisplayNameModule.XMLNS)
|
||||
|
||||
pubsubModule.publishItem(at: nil, to: PEPDisplayNameModule.XMLNS, payload: payload) { responseStanza in
|
||||
switch responseStanza {
|
||||
case .success(response: _, node: _, itemId: _):
|
||||
completion(true)
|
||||
case .failure(errorCondition: _, pubSubErrorCondition: _, response: _):
|
||||
completion(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveNick(from jid: BareJID, itemId: String? = nil, completion: @escaping (String?)->Void) {
|
||||
guard let pubsubModule: PubSubModule = context.modulesManager.getModule(PubSubModule.ID) else {
|
||||
print("Required PubSubModule is not registered!")
|
||||
return
|
||||
}
|
||||
|
||||
pubsubModule.retrieveItems(from: jid, for: PEPDisplayNameModule.XMLNS) { responseStanza in
|
||||
switch responseStanza {
|
||||
case .success(_, _, let items,_):
|
||||
if let nick = items.first?.payload?.value {
|
||||
completion(nick)
|
||||
} else { completion(nil) }
|
||||
|
||||
case .failure(errorCondition: _, pubsubErrorCondition: _, response: _):
|
||||
completion(nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func handle(event: Event) {
|
||||
switch event {
|
||||
case let nre as PubSubModule.NotificationReceivedEvent:
|
||||
guard nre.nodeName == PEPDisplayNameModule.XMLNS, let from = nre.message.from else { return }
|
||||
|
||||
let nick = nre.payload?.value
|
||||
context.eventBus.fire(NickChangedEvent(sessionObject: nre.sessionObject, jid: from, itemId: nre.itemId, nick: nick))
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static func getDisplayName(account: BareJID, for jid: BareJID) -> String {
|
||||
guard let client = XmppService.instance.getClient(forJid: account) else { return "" }
|
||||
|
||||
let rosterModule: RosterModule? = client.modulesManager.getModule(RosterModule.ID);
|
||||
let rosterItem = rosterModule?.rosterStore.get(for: JID(jid))
|
||||
var name = rosterItem?.name ?? DBRosterStore.instance.getNickname(jid: jid.stringValue)
|
||||
name = name == nil ? jid.localPart : name
|
||||
return name ?? ""
|
||||
}
|
||||
|
||||
public init() { }
|
||||
|
||||
class NickChangedEvent: Event {
|
||||
public static let TYPE = NickChangedEvent()
|
||||
|
||||
public let type = "PEPNickChanged"
|
||||
|
||||
public let sessionObject: SessionObject!
|
||||
public let jid: JID!
|
||||
public let itemId: String?
|
||||
public let nick: String?
|
||||
|
||||
init() {
|
||||
self.sessionObject = nil
|
||||
self.jid = nil
|
||||
self.itemId = nil
|
||||
self.nick = nil
|
||||
}
|
||||
|
||||
init(sessionObject: SessionObject, jid: JID, itemId: String?, nick: String?) {
|
||||
self.sessionObject = sessionObject
|
||||
self.jid = jid
|
||||
self.itemId = itemId
|
||||
self.nick = nick ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
class NickChangeEventHandler: XmppServiceEventHandler {
|
||||
public static let NICK_CHANGED = Notification.Name("NICK_CHANGED")
|
||||
|
||||
var events: [Event] = [PEPDisplayNameModule.NickChangedEvent.TYPE]
|
||||
|
||||
func handle(event: Event) {
|
||||
guard let event = event as? PEPDisplayNameModule.NickChangedEvent, let account = event.sessionObject.userBareJid, let jid = event.jid, let nick = event.nick else { return }
|
||||
|
||||
DBRosterStore.instance.updateNick(jid: jid.stringValue, nick: nick)
|
||||
|
||||
NotificationCenter.default.post(name: NickChangeEventHandler.NICK_CHANGED, object: self, userInfo: ["account":account, "jid": BareJID(jid)])
|
||||
|
||||
// if let nickname = DBRosterStore.instance.getNickname(jid: jid.stringValue), nickname != nick, let account = event.sessionObject.userBareJid {
|
||||
// NotificationCenter.default.post(name: NickChangeEventHandler.NICK_CHANGED, object: self, userInfo: ["account":account,"jid": BareJID(jid)])
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -49,9 +49,9 @@ open class XmppService: Logger, EventHandler {
|
|||
fileprivate var fetchStart = NSDate();
|
||||
|
||||
#if targetEnvironment(simulator)
|
||||
fileprivate let eventHandlers: [XmppServiceEventHandler] = [NewFeaturesDetector(), MessageEventHandler(), MucEventHandler.instance, PresenceRosterEventHandler(), AvatarEventHandler(), DiscoEventHandler(), PushEventHandler.instance, BlockedEventHandler.instance, MixEventHandler.instance];
|
||||
fileprivate let eventHandlers: [XmppServiceEventHandler] = [NewFeaturesDetector(), MessageEventHandler(), MucEventHandler.instance, PresenceRosterEventHandler(), AvatarEventHandler(), NickChangeEventHandler(), DiscoEventHandler(), PushEventHandler.instance, BlockedEventHandler.instance, MixEventHandler.instance];
|
||||
#else
|
||||
fileprivate let eventHandlers: [XmppServiceEventHandler] = [NewFeaturesDetector(), MessageEventHandler(), MucEventHandler.instance, PresenceRosterEventHandler(), AvatarEventHandler(), DiscoEventHandler(), PushEventHandler.instance, JingleManager.instance, BlockedEventHandler.instance, MixEventHandler.instance];
|
||||
fileprivate let eventHandlers: [XmppServiceEventHandler] = [NewFeaturesDetector(), MessageEventHandler(), MucEventHandler.instance, PresenceRosterEventHandler(), AvatarEventHandler(), NickChangeEventHandler(), DiscoEventHandler(), PushEventHandler.instance, JingleManager.instance, BlockedEventHandler.instance, MixEventHandler.instance];
|
||||
#endif
|
||||
|
||||
public let dbCapsCache: DBCapabilitiesCache;
|
||||
|
@ -666,6 +666,7 @@ open class XmppService: Logger, EventHandler {
|
|||
_ = client.modulesManager.register(PubSubModule());
|
||||
_ = client.modulesManager.register(PEPUserAvatarModule());
|
||||
_ = client.modulesManager.register(PEPBookmarksModule());
|
||||
_ = client.modulesManager.register(PEPDisplayNameModule())
|
||||
let rosterModule = client.modulesManager.register(RosterModule());
|
||||
let rosterStore = DBRosterStoreWrapper(sessionObject: client.sessionObject);
|
||||
rosterStore.initialize();
|
||||
|
|
|
@ -47,9 +47,20 @@ class DisplayNameViewController: UIViewController {
|
|||
|
||||
@objc func done() {
|
||||
if !textView.text.isEmpty, let account = account {
|
||||
AccountSettings.displayName(account).set(string: textView.text)
|
||||
let nick = textView.text ?? ""
|
||||
|
||||
if let pepModule: PEPDisplayNameModule = XmppService.instance.getClient(for: account)?.modulesManager.getModule(PEPDisplayNameModule.ID) {
|
||||
|
||||
pepModule.publishNick(nick: nick, userJID: JID(account), completion: { success in
|
||||
AccountSettings.displayName(account).set(string: nick)
|
||||
DispatchQueue.main.async {
|
||||
self.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
self.navigationController?.popViewController(animated: true)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,8 +80,17 @@ extension DisplayNameViewController: UITextViewDelegate {
|
|||
}
|
||||
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
if text == "\n", !textView.text.isEmpty, let account = account {
|
||||
AccountSettings.displayName(account).set(string: textView.text)
|
||||
self.navigationController?.popViewController(animated: true)
|
||||
|
||||
if let pepModule: PEPDisplayNameModule = XmppService.instance.getClient(for: account)?.modulesManager.getModule(PEPDisplayNameModule.ID) {
|
||||
|
||||
pepModule.publishNick(nick: textView.text ?? "", userJID: JID(account), completion: { success in
|
||||
AccountSettings.displayName(account).set(string: textView.text)
|
||||
DispatchQueue.main.async {
|
||||
self.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
textView.resignFirstResponder()
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue