221 lines
9.7 KiB
Swift
221 lines
9.7 KiB
Swift
//
|
|
// ChatListViewController.swift
|
|
//
|
|
// Tigase iOS Messenger
|
|
// Copyright (C) 2016 "Tigase, Inc." <office@tigase.com>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. Look for COPYING file in the top folder.
|
|
// If not, see http://www.gnu.org/licenses/.
|
|
//
|
|
|
|
|
|
import UIKit
|
|
import TigaseSwift
|
|
|
|
class ChatsListViewController: UITableViewController, EventHandler {
|
|
var dbConnection:DBConnection {
|
|
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate;
|
|
return appDelegate.dbConnection;
|
|
}
|
|
var xmppService:XmppService {
|
|
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate;
|
|
return appDelegate.xmppService;
|
|
}
|
|
|
|
lazy var countChats:DBStatement! = try? self.dbConnection.prepareStatement("SELECT count(id) AS count FROM chats");
|
|
lazy var getChat:DBStatement! = try? self.dbConnection.prepareStatement("SELECT jid, account, timestamp, thread_id, (SELECT data FROM chat_history ch WHERE ch.account = c.account AND ch.jid = c.jid AND item_type = 0 ORDER BY timestamp DESC LIMIT 1) AS last_message, (SELECT count(ch.id) FROM chat_history ch WHERE ch.account = c.account AND ch.jid = c.jid AND state = 2) as unread, (SELECT name FROM roster_items ri WHERE ri.account = c.account AND ri.jid = c.jid) as name FROM chats as c ORDER BY timestamp DESC LIMIT 1 OFFSET :offset");
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
tableView.rowHeight = 66.0;//UITableViewAutomaticDimension;
|
|
//tableView.estimatedRowHeight = 66.0;
|
|
tableView.dataSource = self;
|
|
// tableView.separatorStyle = .;
|
|
}
|
|
|
|
override func viewWillAppear(animated: Bool) {
|
|
xmppService.registerEventHandler(self, events: MessageModule.ChatCreatedEvent.TYPE, MessageModule.ChatClosedEvent.TYPE, PresenceModule.ContactPresenceChanged.TYPE);
|
|
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ChatsListViewController.newMessage), name: "newMessage", object: nil);
|
|
tableView.reloadData();
|
|
//(self.tabBarController as? CustomTabBarController)?.showTabBar();
|
|
super.viewWillAppear(animated);
|
|
}
|
|
|
|
override func viewDidDisappear(animated: Bool) {
|
|
NSNotificationCenter.defaultCenter().removeObserver(self);
|
|
super.viewDidDisappear(animated);
|
|
xmppService.unregisterEventHandler(self, events: MessageModule.ChatCreatedEvent.TYPE, MessageModule.ChatClosedEvent.TYPE, PresenceModule.ContactPresenceChanged.TYPE);
|
|
}
|
|
|
|
override func didReceiveMemoryWarning() {
|
|
super.didReceiveMemoryWarning()
|
|
// Dispose of any resources that can be recreated.
|
|
}
|
|
|
|
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
|
|
return 1;
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
return try! countChats.scalar() ?? 0;
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
|
let cellIdentifier = "ChatsListTableViewCell";
|
|
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! ChatsListTableViewCell;
|
|
|
|
let params:[String:Any?] = ["offset": indexPath.row];
|
|
do {
|
|
try getChat.query(params) { (cursor)->Void in
|
|
let account:String = (cursor["account"] ?? "");
|
|
let jidStr:String = cursor["jid"]!;
|
|
let jid = BareJID(jidStr);
|
|
cell.nameLabel.text = cursor["name"] ?? jidStr;
|
|
cell.avatarStatusView.setAvatar(self.xmppService.avatarManager.getAvatar(jid));
|
|
cell.lastMessageLabel.text = cursor["last_message"];
|
|
let formattedTS = self.formatTimestamp(cursor["timestamp"]!);
|
|
cell.timestampLabel.text = formattedTS;
|
|
let xmppClient = self.xmppService.getClient(BareJID(account));
|
|
let presenceModule:PresenceModule = xmppClient.modulesManager.getModule(PresenceModule.ID)!;
|
|
let presence = presenceModule.presenceStore.getBestPresence(jid);
|
|
cell.avatarStatusView.setStatus(presence?.show);
|
|
}
|
|
} catch _ {
|
|
cell.nameLabel.text = "DBError";
|
|
}
|
|
|
|
return cell;
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
|
|
if (indexPath.section == 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
|
|
if editingStyle == UITableViewCellEditingStyle.Delete {
|
|
if indexPath.section == 0 {
|
|
do {
|
|
let params:[String:Any?] = ["offset": indexPath.row];
|
|
try getChat.query(params) { (cursor)->Void in
|
|
let accountStr:String = cursor["account"]!;
|
|
let jidStr:String = cursor["jid"]!;
|
|
let account = BareJID(accountStr);
|
|
let jid = JID(jidStr);
|
|
let thread:String? = cursor["thread_id"];
|
|
|
|
let xmppClient = self.xmppService.getClient(account);
|
|
let messageModule:MessageModule = xmppClient.modulesManager.getModule(MessageModule.ID)!;
|
|
if let chat = messageModule.chatManager.getChat(jid, thread: thread) {
|
|
messageModule.chatManager.close(chat);
|
|
}
|
|
}
|
|
} catch _ {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
|
if segue.identifier == "showChatTableInDetailSegue" {
|
|
let cell = sender as! ChatsListTableViewCell;
|
|
if let indexPath = tableView.indexPathForCell(cell) {
|
|
let navigation = segue.destinationViewController as! UINavigationController;
|
|
let destination = navigation.visibleViewController as! ChatViewController;
|
|
destination.hidesBottomBarWhenPushed = true;
|
|
do {
|
|
let params:[String:Any?] = ["offset": indexPath.row];
|
|
try getChat.query(params) { (cursor)->Void in
|
|
let accountStr:String = cursor["account"]!;
|
|
let jidStr:String = cursor["jid"]!;
|
|
let account = BareJID(accountStr);
|
|
let jid = JID(jidStr);
|
|
|
|
destination.account = account;
|
|
destination.jid = jid;
|
|
|
|
self.tableView.deselectRowAtIndexPath(indexPath, animated: true);
|
|
}
|
|
} catch _ {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleEvent(event: Event) {
|
|
switch event {
|
|
case is MessageModule.ChatCreatedEvent:
|
|
tableView.beginUpdates();
|
|
// we are adding rows always on top
|
|
let index = NSIndexPath(forRow: 0, inSection: 0);
|
|
tableView.insertRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Automatic);
|
|
tableView.endUpdates();
|
|
|
|
// if above is not working we can reload
|
|
//tableView.reloadData();
|
|
case is MessageModule.ChatClosedEvent:
|
|
// we do not know position of chat which was closed
|
|
tableView.reloadData();
|
|
case is PresenceModule.ContactPresenceChanged:
|
|
tableView.reloadData();
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
func newMessage(notification:NSNotification) {
|
|
tableView.reloadData();
|
|
}
|
|
|
|
private static let todaysFormatter = ({()-> NSDateFormatter in
|
|
var f = NSDateFormatter();
|
|
f.dateStyle = .NoStyle;
|
|
f.timeStyle = .ShortStyle;
|
|
return f;
|
|
})();
|
|
private static let defaultFormatter = ({()-> NSDateFormatter in
|
|
var f = NSDateFormatter();
|
|
f.dateFormat = NSDateFormatter.dateFormatFromTemplate("dd.MM", options: 0, locale: NSLocale.currentLocale());
|
|
// f.timeStyle = .NoStyle;
|
|
return f;
|
|
})();
|
|
private static let fullFormatter = ({()-> NSDateFormatter in
|
|
var f = NSDateFormatter();
|
|
f.dateFormat = NSDateFormatter.dateFormatFromTemplate("dd.MM.yyyy", options: 0, locale: NSLocale.currentLocale());
|
|
// f.timeStyle = .NoStyle;
|
|
return f;
|
|
})();
|
|
|
|
private func formatTimestamp(ts:NSDate) -> String {
|
|
let flags:NSCalendarUnit = [.Day, .Year];
|
|
let components = NSCalendar.currentCalendar().components(flags, fromDate: ts, toDate: NSDate(), options: []);
|
|
if (components.day == 1) {
|
|
return "Yesterday";
|
|
} else if (components.day < 1) {
|
|
return ChatsListViewController.todaysFormatter.stringFromDate(ts);
|
|
}
|
|
if (components.year != 0) {
|
|
return ChatsListViewController.fullFormatter.stringFromDate(ts);
|
|
} else {
|
|
return ChatsListViewController.defaultFormatter.stringFromDate(ts);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|