diff --git a/Shared/database/DBSchemaManager.swift b/Shared/database/DBSchemaManager.swift index 78bb6954..add29144 100644 --- a/Shared/database/DBSchemaManager.swift +++ b/Shared/database/DBSchemaManager.swift @@ -24,7 +24,7 @@ import TigaseSwift public class DBSchemaManager { - static let CURRENT_VERSION = 15; + static let CURRENT_VERSION = 16; fileprivate let dbConnection: DBConnection; diff --git a/Shared/db-schema-16.sql b/Shared/db-schema-16.sql new file mode 100644 index 00000000..5152d792 --- /dev/null +++ b/Shared/db-schema-16.sql @@ -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; diff --git a/Snikket - Share/Base.lproj/MainInterface.storyboard b/Snikket - Share/Base.lproj/MainInterface.storyboard index 747c2d83..156e0376 100644 --- a/Snikket - Share/Base.lproj/MainInterface.storyboard +++ b/Snikket - Share/Base.lproj/MainInterface.storyboard @@ -1,19 +1,16 @@ - - - - + + - - + - + @@ -32,21 +29,21 @@ - + - - + + - + - + @@ -1397,9 +1424,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/Snikket/Base.lproj/VoIP.storyboard b/Snikket/Base.lproj/VoIP.storyboard index 2474651d..3b8a2255 100644 --- a/Snikket/Base.lproj/VoIP.storyboard +++ b/Snikket/Base.lproj/VoIP.storyboard @@ -1,17 +1,18 @@ - + - + + - + @@ -825,6 +826,24 @@ + + + + + + + + + + + + + + + + + + @@ -837,5 +856,8 @@ + + + diff --git a/Snikket/Info.plist b/Snikket/Info.plist index cc6440a7..bf3ae761 100644 --- a/Snikket/Info.plist +++ b/Snikket/Info.plist @@ -58,6 +58,8 @@ Used to save attachements from conversations NSPhotoLibraryUsageDescription Used to select avatar + NSUserActivityTypes + INStartCallIntent UIBackgroundModes fetch diff --git a/Snikket/chat/ChatViewController.swift b/Snikket/chat/ChatViewController.swift index 558e5093..47dc0598 100644 --- a/Snikket/chat/ChatViewController.swift +++ b/Snikket/chat/ChatViewController.swift @@ -376,27 +376,36 @@ 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; + 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 { - guard (self.navigationItem.rightBarButtonItems?.count ?? 0 != count) else { - return; + var buttons: [UIBarButtonItem] = [] + if supportsVideo { + buttons.append(self.smallBarButtonItem(image: UIImage(named: "videoCall")!, action: #selector(self.videoCall))) } - 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 supportsAudio { + buttons.append(self.smallBarButtonItem(image: UIImage(named: "audioCall")!, action: #selector(self.audioCall))) } - 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; + self.navigationItem.rightBarButtonItems = buttons } - #endif } fileprivate func smallBarButtonItem(image: UIImage, action: Selector) -> UIBarButtonItem { diff --git a/Snikket/da.lproj/Localizable.strings b/Snikket/da.lproj/Localizable.strings index e7f41e5b..d024f426 100644 --- a/Snikket/da.lproj/Localizable.strings +++ b/Snikket/da.lproj/Localizable.strings @@ -417,6 +417,9 @@ /* No comment provided by engineer. */ "No messages yet. Say hi!" = "No messages yet. Say hi!"; +/* No comment provided by engineer. */ +"No Telephony Provider!" = "No Telephony Provider!"; + /* No comment provided by engineer. */ "None" = "None"; @@ -480,6 +483,9 @@ /* Menu item: select media to share from photo/video library */ "Photo & Video Library" = "Photo & Video Library"; +/* No comment provided by engineer. */ +"Please Select a Telephony Provider from Settings" = "Please Select a Telephony Provider from Settings"; + /* No comment provided by engineer. */ "Please try again!" = "Please try again!"; @@ -564,6 +570,9 @@ /* Shown above a choice list of the user's accounts */ "Select account to open chat from:" = "Select account to open chat from:"; +/* No comment provided by engineer. */ +"Select Account for Call" = "Select Account for Call"; + /* No comment provided by engineer. */ "Select photo" = "Select photo"; @@ -639,6 +648,12 @@ /* Error text - while uploading file */ "There was a server error processing the file upload. Please try again later." = "There was a server error processing the file upload. Please try again later."; +/* No comment provided by engineer. */ +"This is an audio call, and no video is available" = "This is an audio call, and no video is available"; + +/* No comment provided by engineer. */ +"This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages" = "This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages"; + /* No comment provided by engineer. */ "This will delete all the message history for this chat. Continue?" = "This will delete all the message history for this chat. Continue?"; @@ -672,6 +687,9 @@ /* No comment provided by engineer. */ "Video call" = "Video call"; +/* No comment provided by engineer. */ +"Video not available" = "Video not available"; + /* No comment provided by engineer. */ "Warning" = "Warning"; diff --git a/Snikket/da.lproj/Main.strings b/Snikket/da.lproj/Main.strings index 71078ef7..58aeeda3 100644 --- a/Snikket/da.lproj/Main.strings +++ b/Snikket/da.lproj/Main.strings @@ -22,6 +22,9 @@ /* Class = "UILabel"; text = "Message Archiving"; ObjectID = "Ckp-Mb-v0c"; */ "Ckp-Mb-v0c.text" = "Message Archiving"; +/* Class = "UITableViewSection"; headerTitle = "Invite"; ObjectID = "dib-YA-Eiz"; */ +"dib-YA-Eiz.headerTitle" = "Invite"; + /* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "Dx3-QU-3cN"; */ "Dx3-QU-3cN.title" = "Back"; @@ -79,6 +82,12 @@ /* Class = "UILabel"; text = "Chat with"; ObjectID = "Qr0-8H-IJq"; */ "Qr0-8H-IJq.text" = "Chat with"; +/* Class = "UITextField"; placeholder = "Enter contact name"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.placeholder" = "Enter contact name"; + +/* Class = "UITextField"; text = "Send Invitation Link"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.text" = "Send Invitation Link"; + /* Class = "UINavigationItem"; title = "Contacts"; ObjectID = "SEz-IM-IWL"; */ "SEz-IM-IWL.title" = "Contacts"; diff --git a/Snikket/da.lproj/Settings.strings b/Snikket/da.lproj/Settings.strings index af302709..56c46710 100644 --- a/Snikket/da.lproj/Settings.strings +++ b/Snikket/da.lproj/Settings.strings @@ -10,6 +10,9 @@ /* Class = "UILabel"; text = "About"; ObjectID = "3vM-ad-4ap"; Note = "Action button: show app about screen"; */ "3vM-ad-4ap.text" = "About"; +/* Class = "UITableViewController"; title = "Notification settings"; ObjectID = "4VG-XN-BdZ"; */ +"4VG-XN-BdZ.title" = "Notification settings"; + /* Class = "UILabel"; text = "Account name"; ObjectID = "7ho-Mu-thd"; */ "7ho-Mu-thd.text" = "Account name"; @@ -82,6 +85,9 @@ /* Class = "UILabel"; text = "Blocked contacts"; ObjectID = "MJ0-kw-1Kl"; */ "MJ0-kw-1Kl.text" = "Blocked contacts"; +/* Class = "UILabel"; text = "Add to system call history"; ObjectID = "Ngk-vc-zET"; */ +"Ngk-vc-zET.text" = "Add to system call history"; + /* Class = "UILabel"; text = "\"Hidden\" group"; ObjectID = "P82-B8-768"; */ "P82-B8-768.text" = "\"Hidden\" group"; @@ -97,6 +103,12 @@ /* Class = "UILabel"; text = "Medium"; ObjectID = "u45-W8-GP0"; */ "u45-W8-GP0.text" = "Medium"; +/* Class = "UITableViewSection"; headerTitle = "TELEPHONY"; ObjectID = "v8T-iN-1IT"; */ +"v8T-iN-1IT.headerTitle" = "TELEPHONY"; + +/* Class = "UILabel"; text = "Calls"; ObjectID = "wfP-Tn-CDA"; */ +"wfP-Tn-CDA.text" = "Calls"; + /* Class = "UITableViewController"; title = "Contacts settings"; ObjectID = "xRS-v5-T5C"; */ "xRS-v5-T5C.title" = "Contacts settings"; diff --git a/Snikket/database/DBRosterStore.swift b/Snikket/database/DBRosterStore.swift index 4b031655..339af903 100644 --- a/Snikket/database/DBRosterStore.swift +++ b/Snikket/database/DBRosterStore.swift @@ -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]; diff --git a/Snikket/de.lproj/Localizable.strings b/Snikket/de.lproj/Localizable.strings index 20765f37..f5b11e84 100644 --- a/Snikket/de.lproj/Localizable.strings +++ b/Snikket/de.lproj/Localizable.strings @@ -263,6 +263,9 @@ "No attachments" = "Keine Anhänge"; "No messages yet. Say hi!" = "Noch keine Nachrichten. Sag Hallo!"; +/* No comment provided by engineer. */ +"No Telephony Provider!" = "No Telephony Provider!"; + /* Encryption mode */ "None" = "Keine"; @@ -293,6 +296,12 @@ "Operation timed out" = "Aktion wegen Zeitüberschreitung abgebrochen"; "operation timed out" = "Aktion aufgrund einer Zeitüberschreitung abgebrochen"; +/* No comment provided by engineer. */ +"Please Select a Telephony Provider from Settings" = "Please Select a Telephony Provider from Settings"; + +/* No comment provided by engineer. */ +"Please try again!" = "Please try again!"; + /* Image or Video Quality */ "Original" = "Original"; "Original quality will share image in the format in which it is stored on your phone and it may not be supported by every device." = "Bei Originalqualität wird das Bild in dem ursprünglichen Format in dem es auf dem Telefon gespeichert ist gesendet. Das wird ggfs. nicht von jedem Empfangsgerät unterstützt."; @@ -371,7 +380,6 @@ "Send Pin Location" = "Gewählte Position senden"; "Server did not respond to registration request" = "Der Server hat auf die Registrierungsanfrage nicht geantwortet"; -/* Preceded by user's server domain */ "server returned an error on the request to enable archiving. You can try to enable this feature later on from the account settings." = "server returned an error on the request to enable archiving. You can try to enable this feature later on from the account settings."; "Server returned error:" = "Der Server hat folgenden Fehler zurückgegeben:"; "Set" = "Setzen"; @@ -393,7 +401,48 @@ /* followed by a space and error condition */ "The server returned an error:" = "Der Server hat folgenden Fehler zurückgegeben:"; -"The server returned an error: " = "Der Server hat folgenden Fehler zurückgegeben: "; + +/* No comment provided by engineer. */ +"The server returned an error: " = "The server returned an error: "; + +/* No comment provided by engineer. */ +"The user will be reported and any calls, messages and status updates from them will be blocked." = "The user will be reported and any calls, messages and status updates from them will be blocked."; + +/* No comment provided by engineer. */ +"This is an audio call, and no video is available" = "This is an audio call, and no video is available"; + +/* No comment provided by engineer. */ +"This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages" = "This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages"; + +/* No comment provided by engineer. */ +"This will delete all the message history for this chat. Continue?" = "This will delete all the message history for this chat. Continue?"; + +/* No comment provided by engineer. */ +"Unblock" = "Unblock"; + +/* No comment provided by engineer. */ +"Unkown error occured" = "Unkown error occured"; + +/* No comment provided by engineer. */ +"Unlimited" = "Unlimited"; + +/* No comment provided by engineer. */ +"Used image and video quality may impact storage and network usage" = "Used image and video quality may impact storage and network usage"; + +/* No comment provided by engineer. */ +"User with provided username already exists" = "User with provided username already exists"; + +/* No comment provided by engineer. */ +"using" = "using"; + +/* No comment provided by engineer. */ +"Video call" = "Video call"; + +/* No comment provided by engineer. */ +"Video not available" = "Video not available"; + +/* No comment provided by engineer. */ +"Warning" = "Warning"; /* Error text - while uploading a file. Placeholder is a HTTP status code. */ "The upload was rejected by the server (error %d)." = "Der Upload wurde vom Server abgelehnt (Fehler %d)."; diff --git a/Snikket/de.lproj/Main.strings b/Snikket/de.lproj/Main.strings index fb289e91..f18b2eac 100644 --- a/Snikket/de.lproj/Main.strings +++ b/Snikket/de.lproj/Main.strings @@ -22,6 +22,9 @@ /* Class = "UILabel"; text = "Message Archiving"; ObjectID = "Ckp-Mb-v0c"; */ "Ckp-Mb-v0c.text" = "Nachrichtenarchivierung"; +/* Class = "UITableViewSection"; headerTitle = "Invite"; ObjectID = "dib-YA-Eiz"; */ +"dib-YA-Eiz.headerTitle" = "Invite"; + /* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "Dx3-QU-3cN"; */ "Dx3-QU-3cN.title" = "Zurück"; @@ -79,6 +82,12 @@ /* Class = "UILabel"; text = "Chat with"; ObjectID = "Qr0-8H-IJq"; */ "Qr0-8H-IJq.text" = "Chat with"; +/* Class = "UITextField"; placeholder = "Enter contact name"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.placeholder" = "Enter contact name"; + +/* Class = "UITextField"; text = "Send Invitation Link"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.text" = "Send Invitation Link"; + /* Class = "UINavigationItem"; title = "Contacts"; ObjectID = "SEz-IM-IWL"; */ "SEz-IM-IWL.title" = "Kontakte"; diff --git a/Snikket/de.lproj/Settings.strings b/Snikket/de.lproj/Settings.strings index ac2078e2..11f92d4d 100644 --- a/Snikket/de.lproj/Settings.strings +++ b/Snikket/de.lproj/Settings.strings @@ -10,6 +10,9 @@ /* Class = "UILabel"; text = "About"; ObjectID = "3vM-ad-4ap"; Note = "Action button: show app about screen"; */ "3vM-ad-4ap.text" = "Über"; +/* Class = "UITableViewController"; title = "Notification settings"; ObjectID = "4VG-XN-BdZ"; */ +"4VG-XN-BdZ.title" = "Notification settings"; + /* Class = "UILabel"; text = "Account name"; ObjectID = "7ho-Mu-thd"; */ "7ho-Mu-thd.text" = "Account name"; @@ -82,6 +85,9 @@ /* Class = "UILabel"; text = "Blocked contacts"; ObjectID = "MJ0-kw-1Kl"; */ "MJ0-kw-1Kl.text" = "Blockierte Kontakte"; +/* Class = "UILabel"; text = "Add to system call history"; ObjectID = "Ngk-vc-zET"; */ +"Ngk-vc-zET.text" = "Add to system call history"; + /* Class = "UILabel"; text = "\"Hidden\" group"; ObjectID = "P82-B8-768"; */ "P82-B8-768.text" = "\"Versteckte\" Gruppe"; @@ -97,6 +103,12 @@ /* Class = "UILabel"; text = "Medium"; ObjectID = "u45-W8-GP0"; */ "u45-W8-GP0.text" = "Medium"; +/* Class = "UITableViewSection"; headerTitle = "TELEPHONY"; ObjectID = "v8T-iN-1IT"; */ +"v8T-iN-1IT.headerTitle" = "TELEPHONY"; + +/* Class = "UILabel"; text = "Calls"; ObjectID = "wfP-Tn-CDA"; */ +"wfP-Tn-CDA.text" = "Calls"; + /* Class = "UITableViewController"; title = "Contacts settings"; ObjectID = "xRS-v5-T5C"; */ "xRS-v5-T5C.title" = "Kontakteinstellungen"; diff --git a/Snikket/en-GB.lproj/Localizable.strings b/Snikket/en-GB.lproj/Localizable.strings index f9eef5a6..681b27ba 100644 --- a/Snikket/en-GB.lproj/Localizable.strings +++ b/Snikket/en-GB.lproj/Localizable.strings @@ -417,6 +417,9 @@ /* No comment provided by engineer. */ "No messages yet. Say hi!" = "No messages yet. Say hi!"; +/* No comment provided by engineer. */ +"No Telephony Provider!" = "No Telephony Provider!"; + /* No comment provided by engineer. */ "None" = "None"; @@ -480,6 +483,9 @@ /* Menu item: select media to share from photo/video library */ "Photo & Video Library" = "Photo & Video Library"; +/* No comment provided by engineer. */ +"Please Select a Telephony Provider from Settings" = "Please Select a Telephony Provider from Settings"; + /* No comment provided by engineer. */ "Please try again!" = "Please try again!"; @@ -564,6 +570,9 @@ /* Shown above a choice list of the user's accounts */ "Select account to open chat from:" = "Select account to open chat from:"; +/* No comment provided by engineer. */ +"Select Account for Call" = "Select Account for Call"; + /* No comment provided by engineer. */ "Select photo" = "Select photo"; @@ -639,6 +648,12 @@ /* Error text - while uploading file */ "There was a server error processing the file upload. Please try again later." = "There was a server error processing the file upload. Please try again later."; +/* No comment provided by engineer. */ +"This is an audio call, and no video is available" = "This is an audio call, and no video is available"; + +/* No comment provided by engineer. */ +"This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages" = "This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages"; + /* No comment provided by engineer. */ "This will delete all the message history for this chat. Continue?" = "This will delete all the message history for this chat. Continue?"; @@ -672,6 +687,9 @@ /* No comment provided by engineer. */ "Video call" = "Video call"; +/* No comment provided by engineer. */ +"Video not available" = "Video not available"; + /* No comment provided by engineer. */ "Warning" = "Warning"; diff --git a/Snikket/en-GB.lproj/Main.strings b/Snikket/en-GB.lproj/Main.strings index df553a24..d837b3ff 100644 --- a/Snikket/en-GB.lproj/Main.strings +++ b/Snikket/en-GB.lproj/Main.strings @@ -22,6 +22,9 @@ /* Class = "UILabel"; text = "Message Archiving"; ObjectID = "Ckp-Mb-v0c"; */ "Ckp-Mb-v0c.text" = "Message Archiving"; +/* Class = "UITableViewSection"; headerTitle = "Invite"; ObjectID = "dib-YA-Eiz"; */ +"dib-YA-Eiz.headerTitle" = "Invite"; + /* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "Dx3-QU-3cN"; */ "Dx3-QU-3cN.title" = "Back"; @@ -79,6 +82,12 @@ /* Class = "UILabel"; text = "Chat with"; ObjectID = "Qr0-8H-IJq"; */ "Qr0-8H-IJq.text" = "Chat with"; +/* Class = "UITextField"; placeholder = "Enter contact name"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.placeholder" = "Enter contact name"; + +/* Class = "UITextField"; text = "Send Invitation Link"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.text" = "Send Invitation Link"; + /* Class = "UINavigationItem"; title = "Contacts"; ObjectID = "SEz-IM-IWL"; */ "SEz-IM-IWL.title" = "Contacts"; diff --git a/Snikket/en-GB.lproj/Settings.strings b/Snikket/en-GB.lproj/Settings.strings index af302709..56c46710 100644 --- a/Snikket/en-GB.lproj/Settings.strings +++ b/Snikket/en-GB.lproj/Settings.strings @@ -10,6 +10,9 @@ /* Class = "UILabel"; text = "About"; ObjectID = "3vM-ad-4ap"; Note = "Action button: show app about screen"; */ "3vM-ad-4ap.text" = "About"; +/* Class = "UITableViewController"; title = "Notification settings"; ObjectID = "4VG-XN-BdZ"; */ +"4VG-XN-BdZ.title" = "Notification settings"; + /* Class = "UILabel"; text = "Account name"; ObjectID = "7ho-Mu-thd"; */ "7ho-Mu-thd.text" = "Account name"; @@ -82,6 +85,9 @@ /* Class = "UILabel"; text = "Blocked contacts"; ObjectID = "MJ0-kw-1Kl"; */ "MJ0-kw-1Kl.text" = "Blocked contacts"; +/* Class = "UILabel"; text = "Add to system call history"; ObjectID = "Ngk-vc-zET"; */ +"Ngk-vc-zET.text" = "Add to system call history"; + /* Class = "UILabel"; text = "\"Hidden\" group"; ObjectID = "P82-B8-768"; */ "P82-B8-768.text" = "\"Hidden\" group"; @@ -97,6 +103,12 @@ /* Class = "UILabel"; text = "Medium"; ObjectID = "u45-W8-GP0"; */ "u45-W8-GP0.text" = "Medium"; +/* Class = "UITableViewSection"; headerTitle = "TELEPHONY"; ObjectID = "v8T-iN-1IT"; */ +"v8T-iN-1IT.headerTitle" = "TELEPHONY"; + +/* Class = "UILabel"; text = "Calls"; ObjectID = "wfP-Tn-CDA"; */ +"wfP-Tn-CDA.text" = "Calls"; + /* Class = "UITableViewController"; title = "Contacts settings"; ObjectID = "xRS-v5-T5C"; */ "xRS-v5-T5C.title" = "Contacts settings"; diff --git a/Snikket/en.lproj/Localizable.strings b/Snikket/en.lproj/Localizable.strings index f9eef5a6..681b27ba 100644 --- a/Snikket/en.lproj/Localizable.strings +++ b/Snikket/en.lproj/Localizable.strings @@ -417,6 +417,9 @@ /* No comment provided by engineer. */ "No messages yet. Say hi!" = "No messages yet. Say hi!"; +/* No comment provided by engineer. */ +"No Telephony Provider!" = "No Telephony Provider!"; + /* No comment provided by engineer. */ "None" = "None"; @@ -480,6 +483,9 @@ /* Menu item: select media to share from photo/video library */ "Photo & Video Library" = "Photo & Video Library"; +/* No comment provided by engineer. */ +"Please Select a Telephony Provider from Settings" = "Please Select a Telephony Provider from Settings"; + /* No comment provided by engineer. */ "Please try again!" = "Please try again!"; @@ -564,6 +570,9 @@ /* Shown above a choice list of the user's accounts */ "Select account to open chat from:" = "Select account to open chat from:"; +/* No comment provided by engineer. */ +"Select Account for Call" = "Select Account for Call"; + /* No comment provided by engineer. */ "Select photo" = "Select photo"; @@ -639,6 +648,12 @@ /* Error text - while uploading file */ "There was a server error processing the file upload. Please try again later." = "There was a server error processing the file upload. Please try again later."; +/* No comment provided by engineer. */ +"This is an audio call, and no video is available" = "This is an audio call, and no video is available"; + +/* No comment provided by engineer. */ +"This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages" = "This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages"; + /* No comment provided by engineer. */ "This will delete all the message history for this chat. Continue?" = "This will delete all the message history for this chat. Continue?"; @@ -672,6 +687,9 @@ /* No comment provided by engineer. */ "Video call" = "Video call"; +/* No comment provided by engineer. */ +"Video not available" = "Video not available"; + /* No comment provided by engineer. */ "Warning" = "Warning"; diff --git a/Snikket/en.lproj/Main.strings b/Snikket/en.lproj/Main.strings index 7af8efbc..064bf262 100644 --- a/Snikket/en.lproj/Main.strings +++ b/Snikket/en.lproj/Main.strings @@ -22,6 +22,9 @@ /* Class = "UILabel"; text = "Message Archiving"; ObjectID = "Ckp-Mb-v0c"; */ "Ckp-Mb-v0c.text" = "Message Archiving"; +/* Class = "UITableViewSection"; headerTitle = "Invite"; ObjectID = "dib-YA-Eiz"; */ +"dib-YA-Eiz.headerTitle" = "Invite"; + /* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "Dx3-QU-3cN"; */ "Dx3-QU-3cN.title" = "Back"; @@ -79,6 +82,12 @@ /* Class = "UILabel"; text = "Chat with"; ObjectID = "Qr0-8H-IJq"; */ "Qr0-8H-IJq.text" = "Chat with"; +/* Class = "UITextField"; placeholder = "Enter contact name"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.placeholder" = "Enter contact name"; + +/* Class = "UITextField"; text = "Send Invitation Link"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.text" = "Send Invitation Link"; + /* Class = "UINavigationItem"; title = "Contacts"; ObjectID = "SEz-IM-IWL"; */ "SEz-IM-IWL.title" = "Contacts"; diff --git a/Snikket/en.lproj/Settings.strings b/Snikket/en.lproj/Settings.strings index af302709..56c46710 100644 --- a/Snikket/en.lproj/Settings.strings +++ b/Snikket/en.lproj/Settings.strings @@ -10,6 +10,9 @@ /* Class = "UILabel"; text = "About"; ObjectID = "3vM-ad-4ap"; Note = "Action button: show app about screen"; */ "3vM-ad-4ap.text" = "About"; +/* Class = "UITableViewController"; title = "Notification settings"; ObjectID = "4VG-XN-BdZ"; */ +"4VG-XN-BdZ.title" = "Notification settings"; + /* Class = "UILabel"; text = "Account name"; ObjectID = "7ho-Mu-thd"; */ "7ho-Mu-thd.text" = "Account name"; @@ -82,6 +85,9 @@ /* Class = "UILabel"; text = "Blocked contacts"; ObjectID = "MJ0-kw-1Kl"; */ "MJ0-kw-1Kl.text" = "Blocked contacts"; +/* Class = "UILabel"; text = "Add to system call history"; ObjectID = "Ngk-vc-zET"; */ +"Ngk-vc-zET.text" = "Add to system call history"; + /* Class = "UILabel"; text = "\"Hidden\" group"; ObjectID = "P82-B8-768"; */ "P82-B8-768.text" = "\"Hidden\" group"; @@ -97,6 +103,12 @@ /* Class = "UILabel"; text = "Medium"; ObjectID = "u45-W8-GP0"; */ "u45-W8-GP0.text" = "Medium"; +/* Class = "UITableViewSection"; headerTitle = "TELEPHONY"; ObjectID = "v8T-iN-1IT"; */ +"v8T-iN-1IT.headerTitle" = "TELEPHONY"; + +/* Class = "UILabel"; text = "Calls"; ObjectID = "wfP-Tn-CDA"; */ +"wfP-Tn-CDA.text" = "Calls"; + /* Class = "UITableViewController"; title = "Contacts settings"; ObjectID = "xRS-v5-T5C"; */ "xRS-v5-T5C.title" = "Contacts settings"; diff --git a/Snikket/fr.lproj/Localizable.strings b/Snikket/fr.lproj/Localizable.strings index 671c6d1e..03cf7d48 100644 --- a/Snikket/fr.lproj/Localizable.strings +++ b/Snikket/fr.lproj/Localizable.strings @@ -261,6 +261,9 @@ "No attachments" = "Aucune pièce jointe"; "No messages yet. Say hi!" = "Aucun message, dites bonjour !"; +/* No comment provided by engineer. */ +"No Telephony Provider!" = "No Telephony Provider!"; + /* Encryption mode */ "None" = "None"; @@ -303,6 +306,11 @@ /* Menu item: select media to share from photo/video library */ "Photo & Video Library" = "Photo & Video Library"; + +/* No comment provided by engineer. */ +"Please Select a Telephony Provider from Settings" = "Please Select a Telephony Provider from Settings"; + +/* No comment provided by engineer. */ "Please try again!" = "Merci de réessayer !"; /* Alert title */ @@ -351,6 +359,9 @@ /* Shown above a choice list of the user's accounts */ "Select account to open chat from:" = "Select account to open chat from:"; +/* No comment provided by engineer. */ +"Select Account for Call" = "Select Account for Call"; + /* Action button: select (existing) photo for group chat picture */ "Select photo" = "Sélectionner une photo"; @@ -399,6 +410,14 @@ /* Error text - while uploading file */ "There was a server error processing the file upload. Please try again later." = "There was a server error processing the file upload. Please try again later."; + +/* No comment provided by engineer. */ +"This is an audio call, and no video is available" = "This is an audio call, and no video is available"; + +/* No comment provided by engineer. */ +"This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages" = "This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages"; + +/* No comment provided by engineer. */ "This will delete all the message history for this chat. Continue?" = "Vous allez supprimer tout l’historique des messages de cette discussion. Voulez-vous continuer ?"; /* Alert text */ @@ -418,6 +437,14 @@ /* followed by account name to select */ "using" = "using"; "Video call" = "Appel vidéo"; +<<<<<<< HEAD +======= + +/* No comment provided by engineer. */ +"Video not available" = "Video not available"; + +/* No comment provided by engineer. */ +>>>>>>> - #152 CallKit: Handle video button during audio call "Warning" = "Attention"; /* Placeholder is xmpp: URI */ diff --git a/Snikket/fr.lproj/Main.strings b/Snikket/fr.lproj/Main.strings index 2f768272..ed4c2c1a 100644 --- a/Snikket/fr.lproj/Main.strings +++ b/Snikket/fr.lproj/Main.strings @@ -22,6 +22,9 @@ /* Class = "UILabel"; text = "Message Archiving"; ObjectID = "Ckp-Mb-v0c"; */ "Ckp-Mb-v0c.text" = "Archivage des messages"; +/* Class = "UITableViewSection"; headerTitle = "Invite"; ObjectID = "dib-YA-Eiz"; */ +"dib-YA-Eiz.headerTitle" = "Invite"; + /* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "Dx3-QU-3cN"; */ "Dx3-QU-3cN.title" = "Retour"; @@ -79,6 +82,12 @@ /* Class = "UILabel"; text = "Chat with"; ObjectID = "Qr0-8H-IJq"; */ "Qr0-8H-IJq.text" = "Chatter avec"; +/* Class = "UITextField"; placeholder = "Enter contact name"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.placeholder" = "Enter contact name"; + +/* Class = "UITextField"; text = "Send Invitation Link"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.text" = "Send Invitation Link"; + /* Class = "UINavigationItem"; title = "Contacts"; ObjectID = "SEz-IM-IWL"; */ "SEz-IM-IWL.title" = "Contacts"; diff --git a/Snikket/fr.lproj/Settings.strings b/Snikket/fr.lproj/Settings.strings index 083907ae..e2d79b3c 100644 --- a/Snikket/fr.lproj/Settings.strings +++ b/Snikket/fr.lproj/Settings.strings @@ -10,6 +10,9 @@ /* Class = "UILabel"; text = "About"; ObjectID = "3vM-ad-4ap"; Note = "Action button: show app about screen"; */ "3vM-ad-4ap.text" = "À propos"; +/* Class = "UITableViewController"; title = "Notification settings"; ObjectID = "4VG-XN-BdZ"; */ +"4VG-XN-BdZ.title" = "Notification settings"; + /* Class = "UILabel"; text = "Account name"; ObjectID = "7ho-Mu-thd"; */ "7ho-Mu-thd.text" = "Nom du compte"; @@ -82,6 +85,9 @@ /* Class = "UILabel"; text = "Blocked contacts"; ObjectID = "MJ0-kw-1Kl"; */ "MJ0-kw-1Kl.text" = "Contacts bloqués"; +/* Class = "UILabel"; text = "Add to system call history"; ObjectID = "Ngk-vc-zET"; */ +"Ngk-vc-zET.text" = "Add to system call history"; + /* Class = "UILabel"; text = "\"Hidden\" group"; ObjectID = "P82-B8-768"; */ "P82-B8-768.text" = "Salon \"caché\""; @@ -97,6 +103,12 @@ /* Class = "UILabel"; text = "Medium"; ObjectID = "u45-W8-GP0"; */ "u45-W8-GP0.text" = "Medium"; +/* Class = "UITableViewSection"; headerTitle = "TELEPHONY"; ObjectID = "v8T-iN-1IT"; */ +"v8T-iN-1IT.headerTitle" = "TELEPHONY"; + +/* Class = "UILabel"; text = "Calls"; ObjectID = "wfP-Tn-CDA"; */ +"wfP-Tn-CDA.text" = "Calls"; + /* Class = "UITableViewController"; title = "Contacts settings"; ObjectID = "xRS-v5-T5C"; */ "xRS-v5-T5C.title" = "Contacts settings"; diff --git a/Snikket/roster/RosterItemEditViewController.swift b/Snikket/roster/RosterItemEditViewController.swift index fe6dd09e..1db44186 100644 --- a/Snikket/roster/RosterItemEditViewController.swift +++ b/Snikket/roster/RosterItemEditViewController.swift @@ -26,6 +26,7 @@ class RosterItemEditViewController: UITableViewController, UIPickerViewDataSourc var xmppService:XmppService! + @IBOutlet weak var invitationLinkIndicator: UIActivityIndicatorView! @IBOutlet var accountTextField: UITextField! @IBOutlet var jidTextField: UITextField! @IBOutlet var nameTextField: UITextField! @@ -69,6 +70,45 @@ class RosterItemEditViewController: UITableViewController, UIPickerViewDataSourc self.nameTextField.text = nil; } } + + func createInvitationLink() { + guard let account = BareJID(self.accountTextField.text), let client = xmppService.getClient(for: account) else { return } + + let inviteCommand = "urn:xmpp:invite#invite" + if let adHocModule: AdHocCommandsModule = client.modulesManager.getModule(AdHocCommandsModule.ID) { + adHocModule.execute(on: JID(account.domain), command: inviteCommand, action: .execute, data: nil) { response, data in + if let inviteLink = data?.getField(named: "landing-url")?.element.findChild(name: "value")?.value { + self.presentShareSheet(url: inviteLink) + } + } onError: { error in + self.toggleActivityIndicator(toggle: false) + } + + } + } + + func presentShareSheet(url: String) { + guard let url = URL(string: url) else { + self.toggleActivityIndicator(toggle: false) + return + } + + let items: [Any] = [url] + let ac = UIActivityViewController(activityItems: items, applicationActivities: nil) + DispatchQueue.main.async { + self.present(ac, animated: true) { + self.toggleActivityIndicator(toggle: false) + } + } + + } + + func toggleActivityIndicator(toggle: Bool) { + DispatchQueue.main.async { + if toggle { self.invitationLinkIndicator.startAnimating() } + else {self.invitationLinkIndicator.stopAnimating() } + } + } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() @@ -217,6 +257,13 @@ class RosterItemEditViewController: UITableViewController, UIPickerViewDataSourc func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { self.accountTextField.text = self.pickerView(pickerView, titleForRow: row, forComponent: component); + self.view.endEditing(true) } + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.section == 4, indexPath.row == 0, !invitationLinkIndicator.isAnimating { + toggleActivityIndicator(toggle: true) + self.createInvitationLink() + } + } } diff --git a/Snikket/roster/RosterViewController.swift b/Snikket/roster/RosterViewController.swift index dd853716..87b9a7e8 100644 --- a/Snikket/roster/RosterViewController.swift +++ b/Snikket/roster/RosterViewController.swift @@ -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); })); diff --git a/Snikket/settings/CallsSettingsViewController.swift b/Snikket/settings/CallsSettingsViewController.swift new file mode 100644 index 00000000..10b57157 --- /dev/null +++ b/Snikket/settings/CallsSettingsViewController.swift @@ -0,0 +1,53 @@ +// +// CallsSettingsViewController.swift +// Snikket +// +// Created by Muhammad Khalid on 29/10/2021. +// Copyright © 2021 Snikket. All rights reserved. +// + +import UIKit +import CallKit + +class CallsSettingsViewController: UITableViewController { + + @IBOutlet weak var callsSwitch: UISwitch! + + override func viewDidLoad() { + super.viewDidLoad() + + callsSwitch.isOn = Settings.addCallsToSystem.getBool() + } + + // MARK: - Table view data source + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + @IBAction func valueChanged(_ sender: UISwitch) { + Settings.addCallsToSystem.setValue(sender.isOn) + enableAddCallsToSystem(enable: sender.isOn) + } + + func enableAddCallsToSystem(enable: Bool) { + let config = CXProviderConfiguration(localizedName: "Snikket"); + if #available(iOS 13.0, *) { + if let image = UIImage(systemName: "message.fill") { + config.iconTemplateImageData = image.pngData(); + } + } else { + if let image = UIImage(named: "message.fill") { + config.iconTemplateImageData = image.pngData(); + } + } + config.includesCallsInRecents = enable; + config.supportsVideo = true; + config.maximumCallsPerCallGroup = 1; + config.maximumCallGroups = 1; + config.supportedHandleTypes = [.generic]; + + CallManager.instance?.provider = CXProvider(configuration: config); + CallManager.instance?.provider.setDelegate(CallManager.instance, queue: nil) + } +} diff --git a/Snikket/settings/SettingsViewController.swift b/Snikket/settings/SettingsViewController.swift index e61e043f..988beab3 100644 --- a/Snikket/settings/SettingsViewController.swift +++ b/Snikket/settings/SettingsViewController.swift @@ -170,6 +170,9 @@ class SettingsViewController: UITableViewController { let cell = tableView.dequeueReusableCell(withIdentifier: "ExperimentalSettingsViewCell", for: indexPath); cell.accessoryType = .disclosureIndicator; return cell; + case .calls: + let cell = tableView.dequeueReusableCell(withIdentifier: "CallsSettingsViewCell", for: indexPath) + return cell case .about: let cell = tableView.dequeueReusableCell(withIdentifier: "AboutSettingsViewCell", for: indexPath); return cell; @@ -396,13 +399,14 @@ class SettingsViewController: UITableViewController { case notifications case media case experimental + case calls case about static let groups: [SettingsGroup] = { if #available(iOS 13.0, *) { - return [.appearance, .chat, .contacts, .media, .about] + return [.appearance, .chat, .contacts, .media, .calls, .about] } else { - return [.chat, .contacts, .media, .about] + return [.chat, .contacts, .media, .calls, .about] } }() } diff --git a/Snikket/sv.lproj/Localizable.strings b/Snikket/sv.lproj/Localizable.strings index a150ec2a..162cf3a0 100644 --- a/Snikket/sv.lproj/Localizable.strings +++ b/Snikket/sv.lproj/Localizable.strings @@ -263,6 +263,9 @@ "No attachments" = "Inga bilagor"; "No messages yet. Say hi!" = "Inga meddelanden än. Säg hej!"; +/* No comment provided by engineer. */ +"No Telephony Provider!" = "No Telephony Provider!"; + /* Encryption mode */ "None" = "None"; @@ -305,6 +308,11 @@ /* Menu item: select media to share from photo/video library */ "Photo & Video Library" = "Foto- och Videobibliotek"; + +/* No comment provided by engineer. */ +"Please Select a Telephony Provider from Settings" = "Please Select a Telephony Provider from Settings"; + +/* No comment provided by engineer. */ "Please try again!" = "Vänligen försök igen!"; /* Alert title */ @@ -353,6 +361,9 @@ /* Shown above a choice list of the user's accounts */ "Select account to open chat from:" = "Välj konto att öppna chatt från:"; +/* No comment provided by engineer. */ +"Select Account for Call" = "Select Account for Call"; + /* Action button: select (existing) photo for group chat picture */ "Select photo" = "Välj foto"; @@ -401,6 +412,14 @@ /* Error text - while uploading file */ "There was a server error processing the file upload. Please try again later." = "Ett fel inträffade på servern vid hantering av filuppladdningen. Vänligen försök igen senare."; + +/* No comment provided by engineer. */ +"This is an audio call, and no video is available" = "This is an audio call, and no video is available"; + +/* No comment provided by engineer. */ +"This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages" = "This room is not capable of sending encrypted messages. Please change encryption settings to be able to send messages"; + +/* No comment provided by engineer. */ "This will delete all the message history for this chat. Continue?" = "Detta raderar all meddelandehistorik för den här chatten. Fortsätta?"; /* Alert text */ @@ -420,6 +439,11 @@ /* followed by account name to select */ "using" = "använder"; "Video call" = "Videosamtal"; + +/* No comment provided by engineer. */ +"Video not available" = "Video not available"; + +/* No comment provided by engineer. */ "Warning" = "Varning"; /* Placeholder is xmpp: URI */ diff --git a/Snikket/sv.lproj/Main.strings b/Snikket/sv.lproj/Main.strings index 5c6fc5a3..972002f8 100644 --- a/Snikket/sv.lproj/Main.strings +++ b/Snikket/sv.lproj/Main.strings @@ -22,6 +22,9 @@ /* Class = "UILabel"; text = "Message Archiving"; ObjectID = "Ckp-Mb-v0c"; */ "Ckp-Mb-v0c.text" = "Meddelandearkivering"; +/* Class = "UITableViewSection"; headerTitle = "Invite"; ObjectID = "dib-YA-Eiz"; */ +"dib-YA-Eiz.headerTitle" = "Invite"; + /* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "Dx3-QU-3cN"; */ "Dx3-QU-3cN.title" = "Tillbaka"; @@ -79,6 +82,12 @@ /* Class = "UILabel"; text = "Chat with"; ObjectID = "Qr0-8H-IJq"; */ "Qr0-8H-IJq.text" = "Chat with"; +/* Class = "UITextField"; placeholder = "Enter contact name"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.placeholder" = "Enter contact name"; + +/* Class = "UITextField"; text = "Send Invitation Link"; ObjectID = "Rg7-YE-y8H"; */ +"Rg7-YE-y8H.text" = "Send Invitation Link"; + /* Class = "UINavigationItem"; title = "Contacts"; ObjectID = "SEz-IM-IWL"; */ "SEz-IM-IWL.title" = "Kontakter"; diff --git a/Snikket/sv.lproj/Settings.strings b/Snikket/sv.lproj/Settings.strings index 8dfbbdf1..fbd4646d 100644 --- a/Snikket/sv.lproj/Settings.strings +++ b/Snikket/sv.lproj/Settings.strings @@ -10,6 +10,9 @@ /* Class = "UILabel"; text = "About"; ObjectID = "3vM-ad-4ap"; Note = "Action button: show app about screen"; */ "3vM-ad-4ap.text" = "Om"; +/* Class = "UITableViewController"; title = "Notification settings"; ObjectID = "4VG-XN-BdZ"; */ +"4VG-XN-BdZ.title" = "Notification settings"; + /* Class = "UILabel"; text = "Account name"; ObjectID = "7ho-Mu-thd"; */ "7ho-Mu-thd.text" = "Namn på kontot"; @@ -82,6 +85,9 @@ /* Class = "UILabel"; text = "Blocked contacts"; ObjectID = "MJ0-kw-1Kl"; */ "MJ0-kw-1Kl.text" = "Blockerade kontakter"; +/* Class = "UILabel"; text = "Add to system call history"; ObjectID = "Ngk-vc-zET"; */ +"Ngk-vc-zET.text" = "Add to system call history"; + /* Class = "UILabel"; text = "\"Hidden\" group"; ObjectID = "P82-B8-768"; */ "P82-B8-768.text" = "\"Dold\" grupp"; @@ -97,6 +103,12 @@ /* Class = "UILabel"; text = "Medium"; ObjectID = "u45-W8-GP0"; */ "u45-W8-GP0.text" = "Medium"; +/* Class = "UITableViewSection"; headerTitle = "TELEPHONY"; ObjectID = "v8T-iN-1IT"; */ +"v8T-iN-1IT.headerTitle" = "TELEPHONY"; + +/* Class = "UILabel"; text = "Calls"; ObjectID = "wfP-Tn-CDA"; */ +"wfP-Tn-CDA.text" = "Calls"; + /* Class = "UITableViewController"; title = "Contacts settings"; ObjectID = "xRS-v5-T5C"; */ "xRS-v5-T5C.title" = "Inställningar för kontakter"; diff --git a/Snikket/util/Settings.swift b/Snikket/util/Settings.swift index f0681dc6..951e74f4 100644 --- a/Snikket/util/Settings.swift +++ b/Snikket/util/Settings.swift @@ -50,6 +50,7 @@ public enum Settings: String { case EnableMarkdownFormatting = "markdown" case ShowEmoticons case messageStyling + case addCallsToSystem @available(iOS 13.0, *) case linkPreviews diff --git a/Snikket/voip/CallManager.swift b/Snikket/voip/CallManager.swift index 272cf535..8e3230f4 100644 --- a/Snikket/voip/CallManager.swift +++ b/Snikket/voip/CallManager.swift @@ -54,7 +54,7 @@ class CallManager: NSObject, CXProviderDelegate { private let pushRegistry: PKPushRegistry; - private let provider: CXProvider; + public var provider: CXProvider; private let callController: CXCallController; private(set) var currentCall: Call?; @@ -92,11 +92,11 @@ class CallManager: NSObject, CXProviderDelegate { config.iconTemplateImageData = image.pngData(); } } - config.includesCallsInRecents = false; + config.includesCallsInRecents = Settings.addCallsToSystem.getBool() config.supportsVideo = true; config.maximumCallsPerCallGroup = 1; config.maximumCallGroups = 1; - config.supportedHandleTypes = [.generic]; + config.supportedHandleTypes = [.generic, .phoneNumber]; provider = CXProvider(configuration: config); callController = CXCallController(); @@ -125,7 +125,11 @@ class CallManager: NSObject, CXProviderDelegate { update.supportsHolding = false provider.configuration.supportsVideo = call.media.contains(.video) update.hasVideo = AVCaptureDevice.authorizationStatus(for: .video) == .authorized && call.media.contains(.video) - update.remoteHandle = call.media.contains(.video) ? CXHandle(type: .generic, value: call.jid.stringValue) : nil + + let telephonyProvider = AccountSettings.telephonyProvider(call.account).getString() ?? "" + let handle = telephonyProvider == call.jid.domain ? CXHandle(type: .phoneNumber, value: (call.jid.localPart ?? "Unkown")) : CXHandle(type: .generic, value: call.jid.stringValue) + + update.remoteHandle = handle configureAudioSession() provider.reportNewIncomingCall(with: call.uuid, update: update, completion: { err in guard let error = err else { @@ -168,7 +172,10 @@ class CallManager: NSObject, CXProviderDelegate { let rosterModule: RosterModule? = XmppService.instance.getClient(for: call.account)?.modulesManager.getModule(RosterModule.ID); let name = rosterModule?.rosterStore.get(for: JID(call.jid))?.name ?? call.jid.stringValue; - let startCallAction = CXStartCallAction(call: call.uuid, handle: CXHandle(type: .generic, value: call.jid.stringValue)); + let telephonyProvider = AccountSettings.telephonyProvider(call.account).getString() ?? "" + let handle = telephonyProvider == call.jid.domain ? CXHandle(type: .phoneNumber, value: (call.jid.localPart ?? "Unkown")) : CXHandle(type: .generic, value: call.jid.stringValue) + + let startCallAction = CXStartCallAction(call: call.uuid, handle: handle) startCallAction.isVideo = call.media.contains(.video); startCallAction.contactIdentifier = name; let transaction = CXTransaction(action: startCallAction); @@ -556,7 +563,7 @@ class CallManager: NSObject, CXProviderDelegate { let controller = UIStoryboard(name: "VoIP", bundle: nil).instantiateViewController(withIdentifier: "VideoCallController") as! VideoCallController; self.delegate = controller; - topController?.show(controller, sender: self); + topController?.present(controller, animated: true, completion: nil) } func switchCameraDevice() { diff --git a/Snikket/voip/CallsAccountSelectionController.swift b/Snikket/voip/CallsAccountSelectionController.swift new file mode 100644 index 00000000..26666b8b --- /dev/null +++ b/Snikket/voip/CallsAccountSelectionController.swift @@ -0,0 +1,41 @@ +// +// CallsAccountSelectionController.swift +// Snikket +// +// Created by Muhammad Khalid on 02/11/2021. +// Copyright © 2021 Snikket. All rights reserved. +// + +import UIKit +import TigaseSwift + +class CallsAccountSelectionController: UITableViewController { + + var didSelectAccount: ((BareJID) -> Void)! + + var accounts = [BareJID]() + + override func viewDidLoad() { + super.viewDidLoad() + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { 1 } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { accounts.count } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = UITableViewCell(style: .default, reuseIdentifier: nil) + cell.textLabel?.text = self.accounts[indexPath.row].stringValue + cell.textLabel?.textAlignment = .center + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + self.dismiss(animated: true, completion: { + self.didSelectAccount(self.accounts[indexPath.row]) + }) + } +}