- #157 Remember that a contact supports audio/video

This commit is contained in:
Muhammad Khalid 2021-11-20 16:06:25 +05:00 committed by Matthew Wild
parent e6f7b72ed2
commit 8662c82a96
6 changed files with 88 additions and 23 deletions

View file

@ -24,7 +24,7 @@ import TigaseSwift
public class DBSchemaManager {
static let CURRENT_VERSION = 15;
static let CURRENT_VERSION = 16;
fileprivate let dbConnection: DBConnection;

8
Shared/db-schema-16.sql Normal file
View file

@ -0,0 +1,8 @@
BEGIN;
ALTER TABLE roster_items ADD COLUMN audio_call INTEGER;
ALTER TABLE roster_items ADD COLUMN video_call INTEGER;
COMMIT;
PRAGMA user_version = 16;

View file

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
370B6FD12748F31C00D14123 /* db-schema-16.sql in Resources */ = {isa = PBXBuildFile; fileRef = 370B6FD02748F31C00D14123 /* db-schema-16.sql */; };
37359BDF2731427500066DC1 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37359BDE2731427500066DC1 /* Intents.framework */; };
373A8020271063E1000E50FE /* TelephonyProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A801F271063E1000E50FE /* TelephonyProviderViewController.swift */; };
374AB4C3273153E700E16682 /* CallsAccountSelectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374AB4C2273153E700E16682 /* CallsAccountSelectionController.swift */; };
@ -307,6 +308,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
370B6FD02748F31C00D14123 /* db-schema-16.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = "db-schema-16.sql"; sourceTree = "<group>"; };
37359BDE2731427500066DC1 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
373A801F271063E1000E50FE /* TelephonyProviderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelephonyProviderViewController.swift; sourceTree = "<group>"; };
374AB4C2273153E700E16682 /* CallsAccountSelectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallsAccountSelectionController.swift; sourceTree = "<group>"; };
@ -918,6 +920,7 @@
FEBC12F124C70DE000689475 /* db-schema-13.sql */,
E928AD4226D6A08A00F29F93 /* db-schema-14.sql */,
379D914926E8A0E300B877CA /* db-schema-15.sql */,
370B6FD02748F31C00D14123 /* db-schema-16.sql */,
);
path = Shared;
sourceTree = "<group>";
@ -1314,6 +1317,7 @@
FE759FEF2371F21C001E78D9 /* db-schema-3.sql in Resources */,
FEC79199241BE89E007BE572 /* db-schema-11.sql in Resources */,
FE759FED2371F213001E78D9 /* db-schema-2.sql in Resources */,
370B6FD12748F31C00D14123 /* db-schema-16.sql in Resources */,
FECEF29823B7B838007EC323 /* db-schema-9.sql in Resources */,
FE3BA0C024B61583000C80D4 /* db-schema-12.sql in Resources */,
FE759FF02371F21C001E78D9 /* db-schema-4.sql in Resources */,

View file

@ -376,29 +376,38 @@ class ChatViewController : BaseChatViewControllerWithDataSourceAndContextMenuAnd
}
#if targetEnvironment(simulator)
#else
let jingleSupported = CallManager.isAvailable ? JingleManager.instance.support(for: JID(self.jid), on: self.account) : [];
var count = jingleSupported.contains(.audio) ? 1 : 0;
if jingleSupported.contains(.video) {
count = count + 1;
}
DispatchQueue.main.async {
guard (self.navigationItem.rightBarButtonItems?.count ?? 0 != count) else {
return;
}
var buttons: [UIBarButtonItem] = [];
if jingleSupported.contains(.video) {
//buttons.append(UIBarButtonItem(image: UIImage(named: "videoCall"), style: .plain, target: self, action: #selector(self.videoCall)));
buttons.append(self.smallBarButtonItem(image: UIImage(named: "videoCall")!, action: #selector(self.videoCall)));
}
if jingleSupported.contains(.audio) {
//buttons.append(UIBarButtonItem(image: UIImage(named: "audioCall"), style: .plain, target: self, action: #selector(self.audioCall)));
buttons.append(self.smallBarButtonItem(image: UIImage(named: "audioCall")!, action: #selector(self.audioCall)));
}
self.navigationItem.rightBarButtonItems = buttons;
let (oldAudio,oldVideo) = DBRosterStore.instance.getAudioVideoCallStatus(account: account, jid: jid)
// if both true no need to update it again
if oldAudio ?? false, oldVideo ?? false {
enableCallingBtns(supportsAudio: oldAudio ?? false, supportsVideo: oldVideo ?? false)
} else {
let jingleSupported = CallManager.isAvailable ? JingleManager.instance.support(for: JID(self.jid), on: self.account) : [];
let supportsAudio = jingleSupported.contains(.audio) ? 1 : (oldAudio == true ? 1 : 0) // do not set false if previous value was true
let supportsVideo = jingleSupported.contains(.video) ? 1 : (oldVideo == true ? 1 : 0)
DBRosterStore.instance.updateAudioVideoCallStatus(account: account, jid: jid, audioCall: supportsAudio, videoCall: supportsVideo)
let (audio,video) = DBRosterStore.instance.getAudioVideoCallStatus(account: account, jid: jid)
enableCallingBtns(supportsAudio: audio ?? false, supportsVideo: video ?? false)
}
#endif
}
func enableCallingBtns(supportsAudio: Bool, supportsVideo: Bool) {
DispatchQueue.main.async {
var buttons: [UIBarButtonItem] = []
if supportsVideo {
buttons.append(self.smallBarButtonItem(image: UIImage(named: "videoCall")!, action: #selector(self.videoCall)))
}
if supportsAudio {
buttons.append(self.smallBarButtonItem(image: UIImage(named: "audioCall")!, action: #selector(self.audioCall)))
}
self.navigationItem.rightBarButtonItems = buttons
}
}
fileprivate func smallBarButtonItem(image: UIImage, action: Selector) -> UIBarButtonItem {
let btn = UIButton(type: .custom);
btn.setImage(image, for: .normal);

View file

@ -123,6 +123,9 @@ open class DBRosterStore: RosterCacheProvider {
fileprivate let updateNicknameStmt: DBStatement
fileprivate let getNicknameStmt: DBStatement
fileprivate let updateAudioVideoCallStmt: DBStatement
fileprivate let getAudioVideoCallStmt: DBStatement
public init() {
self.dispatcher = QueueDispatcher(label: "db_roster_store");
@ -141,6 +144,9 @@ open class DBRosterStore: RosterCacheProvider {
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")
updateAudioVideoCallStmt = try! DBConnection.main.prepareStatement("UPDATE roster_items SET audio_call = :audioCall, video_call = :videoCall WHERE account = :account AND jid = :jid")
getAudioVideoCallStmt = try! DBConnection.main.prepareStatement("SELECT audio_call, video_call FROM roster_items WHERE account = :account AND jid = :jid")
NotificationCenter.default.addObserver(self, selector: #selector(DBRosterStore.accountRemoved), name: NSNotification.Name(rawValue: "accountRemoved"), object: nil);
}
@ -160,6 +166,34 @@ open class DBRosterStore: RosterCacheProvider {
}
}
func updateAudioVideoCallStatus(account: BareJID, jid: BareJID, audioCall: Int?, videoCall: Int?) {
return dispatcher.sync {
let params: [String: Any?] = ["account":account,
"jid":jid,
"audioCall":audioCall,
"videoCall":videoCall]
_ = try! self.updateAudioVideoCallStmt.update(params)
}
}
func getAudioVideoCallStatus(account: BareJID, jid: BareJID) -> (audio:Bool?, video:Bool?) {
dispatcher.sync {
let params: [String: Any?] = ["account":account,
"jid":jid]
var audioCall: Bool? = nil
var videoCall: Bool? = nil
try! getAudioVideoCallStmt.queryFirstMatching(params) { cursor in
let audio: Int? = cursor["audio_call"]
let video: Int? = cursor["video_call"]
audioCall = audio == 1 ? true : (audio == 0 ? false : nil)
videoCall = video == 1 ? true : (video == 0 ? false : nil)
}
return (audioCall,videoCall)
}
}
func getAll(for account: BareJID) -> [DBRosterItem] {
return dispatcher.sync {
let params: [String: Any?] = ["account": account];

View file

@ -315,13 +315,23 @@ class RosterViewController: AbstractRosterViewController, UIGestureRecognizerDel
];
#if targetEnvironment(simulator)
#else
let jingleSupport = JingleManager.instance.support(for: item.jid, on: item.account);
if jingleSupport.contains(.audio) && jingleSupport.contains(.video) {
let (oldAudio,oldVideo) = DBRosterStore.instance.getAudioVideoCallStatus(account: item.account, jid: item.jid.bareJid)
if let oldAudio = oldAudio, let oldVideo = oldVideo, !oldVideo, !oldAudio {
let jingleSupport = JingleManager.instance.support(for: item.jid, on: item.account);
let supportsAudio = jingleSupport.contains(.audio) ? 1 : (oldAudio == true ? 1 : 0) // do not set false if previous value was true
let supportsVideo = jingleSupport.contains(.video) ? 1 : (oldVideo == true ? 1 : 0)
DBRosterStore.instance.updateAudioVideoCallStatus(account: item.account, jid: item.jid.bareJid, audioCall: supportsAudio, videoCall: supportsVideo)
}
let (audio,video) = DBRosterStore.instance.getAudioVideoCallStatus(account: item.account, jid: item.jid.bareJid)
if (audio ?? false) && (video ?? false) {
items.append(UIAction(title: NSLocalizedString("Video call", comment: ""), image: UIImage(systemName: "video"), handler: { (action) in
VideoCallController.call(jid: item.jid.bareJid, from: item.account, media: [.audio, .video], sender: self);
}));
}
if jingleSupport.contains(.audio) {
if audio ?? false {
items.append(UIAction(title: NSLocalizedString("Audio call", comment: ""), image: UIImage(systemName: "phone"), handler: { (action) in
VideoCallController.call(jid: item.jid.bareJid, from: item.account, media: [.audio], sender: self);
}));