Compare commits

...

9 commits

Author SHA1 Message Date
Muhammad Khalid 8662c82a96 - #157 Remember that a contact supports audio/video 2022-04-11 14:22:17 +01:00
Muhammad Khalid e6f7b72ed2 - #154 Fall back to group JID if no name available 2022-04-11 14:22:17 +01:00
Muhammad Khalid b70b28f46f - #153 Call UI appears inside settings dialog 2022-04-11 14:22:17 +01:00
Muhammad Khalid 09d62574ba - #152 CallKit: Handle video button during audio call 2022-04-11 14:22:17 +01:00
Muhammad Khalid 29c9d6793c - #151 CallKit: Support initiating outgoing phone calls 2022-04-11 14:17:12 +01:00
Muhammad Khalid 07c015d833 - #150 CallKit: Configurable reporting of call history 2022-04-11 13:46:41 +01:00
Muhammad Khalid b0ac762af8 - #149 CallKit: Identify telephony calls using phone number handle type 2022-04-11 13:41:04 +01:00
Muhammad Khalid d11e9428c2 - Fixed Account Selection For Invitation Link 2022-04-11 13:41:04 +01:00
Muhammad Khalid 76c0fd0986 - #13 Added Invitation Creation 2022-04-11 13:41:04 +01:00
37 changed files with 816 additions and 76 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

@ -1,19 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Share View Controller-->
<scene sceneID="ceB-am-kn3">
<objects>
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModule="Tigase_Messenger___Share" customModuleProvider="target" sceneMemberID="viewController">
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModule="Snikket___Share" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="8bI-gs-bmD"/>
<viewControllerLayoutGuide type="bottom" id="d5i-Ba-RvD"/>
@ -32,21 +29,21 @@
<!--Accounts-->
<scene sceneID="taW-D3-3Yx">
<objects>
<tableViewController storyboardIdentifier="accountSelectionViewController" title="Accounts" useStoryboardIdentifierAsRestorationIdentifier="YES" id="6l2-wd-vXh" customClass="AccountsTableViewController" customModule="Tigase_Messenger___Share" customModuleProvider="target" sceneMemberID="viewController">
<tableViewController storyboardIdentifier="accountSelectionViewController" title="Accounts" useStoryboardIdentifierAsRestorationIdentifier="YES" id="6l2-wd-vXh" customClass="AccountsTableViewController" customModule="Snikket___Share" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="977-Qx-KPe">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="accountTableViewCell" selectionStyle="default" indentationWidth="10" reuseIdentifier="accountTableViewCell" id="SZs-Vf-W54" customClass="AccountTableViewCell" customModule="Tigase_Messenger___Share" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="accountTableViewCell" selectionStyle="default" indentationWidth="10" reuseIdentifier="accountTableViewCell" id="SZs-Vf-W54" customClass="AccountTableViewCell" customModule="Snikket___Share" customModuleProvider="target">
<rect key="frame" x="0.0" y="44.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="SZs-Vf-W54" id="iwn-zZ-n1r">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="95D-JK-fLM">
<rect key="frame" x="8" y="8" width="359" height="27.5"/>
<rect key="frame" x="16" y="11" width="343" height="22"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -78,21 +75,21 @@
<!--Recipients-->
<scene sceneID="bWt-BT-C6m">
<objects>
<tableViewController storyboardIdentifier="recipientsSelectionViewController" title="Recipients" useStoryboardIdentifierAsRestorationIdentifier="YES" id="wpy-g7-270" customClass="RecipientsSelectionViewController" customModule="Tigase_Messenger___Share" customModuleProvider="target" sceneMemberID="viewController">
<tableViewController storyboardIdentifier="recipientsSelectionViewController" title="Recipients" useStoryboardIdentifierAsRestorationIdentifier="YES" id="wpy-g7-270" customClass="RecipientsSelectionViewController" customModule="Snikket___Share" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="SH7-od-nvj">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="accountTableViewCell" selectionStyle="default" indentationWidth="10" reuseIdentifier="recipientTableViewCell" id="lwl-dC-64B" customClass="RecipientTableViewCell" customModule="Tigase_Messenger___Share" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="accountTableViewCell" selectionStyle="default" indentationWidth="10" reuseIdentifier="recipientTableViewCell" id="lwl-dC-64B" customClass="RecipientTableViewCell" customModule="Snikket___Share" customModuleProvider="target">
<rect key="frame" x="0.0" y="44.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="lwl-dC-64B" id="0s3-Da-XsL">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Geq-xy-Tr2">
<rect key="frame" x="8" y="8" width="359" height="27.5"/>
<rect key="frame" x="16" y="11" width="343" height="22"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>

View file

@ -7,7 +7,10 @@
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 */; };
3759635F26F72F1900831F4C /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3759636126F72F1900831F4C /* Welcome.storyboard */; };
3759636A26F72FD700831F4C /* Groupchat.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3759636C26F72FD700831F4C /* Groupchat.storyboard */; };
3759637126F7303100831F4C /* VoIP.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3759637326F7303100831F4C /* VoIP.storyboard */; };
@ -16,6 +19,7 @@
3759638626F7317D00831F4C /* Account.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3759638826F7317D00831F4C /* Account.storyboard */; };
3759638D26F7320F00831F4C /* MIX.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3759638F26F7320F00831F4C /* MIX.storyboard */; };
3759A58C26F8C7CC002987B2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3759A58E26F8C7CC002987B2 /* Localizable.strings */; };
3763450E272C6CEF000BC01F /* CallsSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3763450D272C6CEF000BC01F /* CallsSettingsViewController.swift */; };
3776C43526EDC5F00047750B /* MessageStyling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3776C43426EDC5F00047750B /* MessageStyling.swift */; };
3795F92426FB69370067361A /* BartyCrouch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3795F92326FB69370067361A /* BartyCrouch.swift */; };
3797D5BD26E9E42E0091DAF8 /* AvatarColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3797D5BC26E9E42E0091DAF8 /* AvatarColors.swift */; };
@ -304,7 +308,10 @@
/* 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>"; };
3759635C26F72EAA00831F4C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
3759635D26F72ED700831F4C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Main.strings; sourceTree = "<group>"; };
3759635E26F72ED700831F4C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/MainInterface.strings; sourceTree = "<group>"; };
@ -334,6 +341,7 @@
3759639426F7481200831F4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Base; path = Base.lproj/Info.plist; sourceTree = "<group>"; };
3759A58D26F8C7CC002987B2 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
3759A58F26F8C7CF002987B2 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
3763450D272C6CEF000BC01F /* CallsSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallsSettingsViewController.swift; sourceTree = "<group>"; };
3776C43426EDC5F00047750B /* MessageStyling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStyling.swift; sourceTree = "<group>"; };
3795F92326FB69370067361A /* BartyCrouch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BartyCrouch.swift; sourceTree = "<group>"; };
3797D5BC26E9E42E0091DAF8 /* AvatarColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarColors.swift; sourceTree = "<group>"; };
@ -652,6 +660,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
37359BDF2731427500066DC1 /* Intents.framework in Frameworks */,
FE1A34A7258CD3EE0058B86A /* WebRTC.xcframework in Frameworks */,
FE5079F01CD3CA91001A015C /* Security.framework in Frameworks */,
3797D5C026EA456F0091DAF8 /* HSLuvSwift in Frameworks */,
@ -674,6 +683,7 @@
FE1908902584D69400CA049F /* Frameworks */ = {
isa = PBXGroup;
children = (
37359BDE2731427500066DC1 /* Intents.framework */,
FE1A349F258CD3E10058B86A /* WebRTC.xcframework */,
FE1908962584D69400CA049F /* OpenSSL.xcframework */,
);
@ -690,6 +700,7 @@
FE2D481924505F1600C13CE5 /* CallManager.swift */,
FE2D481B24518C2800C13CE5 /* RTCCameraVideoCapturer_Format.swift */,
FE1A07472525EDD4004F38A0 /* ExternalServiceDiscovery_Service_extension.swift */,
374AB4C2273153E700E16682 /* CallsAccountSelectionController.swift */,
);
path = voip;
sourceTree = "<group>";
@ -779,26 +790,27 @@
FE507A0A1CDB7B3B001A015C /* settings */ = {
isa = PBXGroup;
children = (
FE6545611E9E7FDE006A14AC /* AccountDomainTableViewCell.swift */,
FE17808C23EB4C7F00A1EA76 /* AccountQRCodeController.swift */,
FEF80DB11CDBBBFE005645A7 /* AccountSettingsViewController.swift */,
FE507A0B1CDB7B3B001A015C /* AccountTableViewCell.swift */,
FE507A0C1CDB7B3B001A015C /* AddAccountController.swift */,
FE507A0D1CDB7B3B001A015C /* SettingsViewController.swift */,
FEF80DB11CDBBBFE005645A7 /* AccountSettingsViewController.swift */,
FE80BDAA1D953FC4001914B0 /* SetupViewController.swift */,
FE65455F1E9E7B85006A14AC /* RegisterAccountController.swift */,
FE6545611E9E7FDE006A14AC /* AccountDomainTableViewCell.swift */,
FE6545631E9E8B67006A14AC /* ServerSelectorTableViewCell.swift */,
FEDC678F238B05E4005C0FAB /* BlockedContactsController.swift */,
FE9E136C1F25F5F7005C0EE5 /* ChatSettingsViewController.swift */,
FE9E136E1F26049A005C0EE5 /* NotificationSettingsViewController.swift */,
FE9E13701F2606E9005C0EE5 /* ContactsSettingsViewController.swift */,
FE00157E2019090300490340 /* ExperimentalSettingsViewController.swift */,
FE0E31112537288A0030F8C5 /* MediaSettingsVIewController.swift */,
FE9E136E1F26049A005C0EE5 /* NotificationSettingsViewController.swift */,
FE719E7D2274D20D007CEEC9 /* OMEMOFingerprintsController.swift */,
E963721126D79D3A00332482 /* PrivacyPolicyTableViewCell.swift */,
FE65455F1E9E7B85006A14AC /* RegisterAccountController.swift */,
FE2809802167CE18002F5BD0 /* server_features_list.xml */,
FE2809822167CF1B002F5BD0 /* ServerFeaturesViewController.swift */,
FE719E7D2274D20D007CEEC9 /* OMEMOFingerprintsController.swift */,
FEDC678F238B05E4005C0FAB /* BlockedContactsController.swift */,
FE17808C23EB4C7F00A1EA76 /* AccountQRCodeController.swift */,
FE0E31112537288A0030F8C5 /* MediaSettingsVIewController.swift */,
E963721126D79D3A00332482 /* PrivacyPolicyTableViewCell.swift */,
FE6545631E9E8B67006A14AC /* ServerSelectorTableViewCell.swift */,
FE507A0D1CDB7B3B001A015C /* SettingsViewController.swift */,
FE80BDAA1D953FC4001914B0 /* SetupViewController.swift */,
373A801F271063E1000E50FE /* TelephonyProviderViewController.swift */,
3763450D272C6CEF000BC01F /* CallsSettingsViewController.swift */,
);
path = settings;
sourceTree = "<group>";
@ -908,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>";
@ -1304,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 */,
@ -1461,6 +1475,7 @@
373A8020271063E1000E50FE /* TelephonyProviderViewController.swift in Sources */,
FE3E38862428C21100D3A8E8 /* OSLog.swift in Sources */,
FECEF29423B7933A007EC323 /* MetadataCache.swift in Sources */,
3763450E272C6CEF000BC01F /* CallsSettingsViewController.swift in Sources */,
E9D384B426CA95FF009BEAF3 /* UIDeviceExtension.swift in Sources */,
FEB62C501DA80956001500D5 /* AvatarStore.swift in Sources */,
FE7D293423B919FF001A877D /* DownloadManager.swift in Sources */,
@ -1524,6 +1539,7 @@
FE2D481C24518C2800C13CE5 /* RTCCameraVideoCapturer_Format.swift in Sources */,
FE4071E421E2605900F09B58 /* VideoCallController.swift in Sources */,
FE9E13731F260B33005C0EE5 /* StepperTableViewCell.swift in Sources */,
374AB4C3273153E700E16682 /* CallsAccountSelectionController.swift in Sources */,
FE6545601E9E7B85006A14AC /* RegisterAccountController.swift in Sources */,
FE507A181CDB7B3B001A015C /* ChatViewController.swift in Sources */,
FEFB63AD1F31E4EE00EFB3E7 /* MainTabBarController.swift in Sources */,

View file

@ -39,6 +39,7 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

View file

@ -25,6 +25,7 @@ import TigaseSwift
import Shared
import WebRTC
import BackgroundTasks
import Intents
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
@ -769,6 +770,100 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
case register
}
}
}
// Making Call From System Calls App
extension AppDelegate {
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
let interaction = userActivity.interaction
if let startAudioCallIntent = interaction?.intent as? INStartAudioCallIntent {
let contact = startAudioCallIntent.contacts?.first
let contactHandle = contact?.personHandle
if let callTo = contactHandle?.value {
if contactHandle?.type == .phoneNumber {
// call from telephony configured account
getTelephonyConfiguredAccounts(completion: { [callTo] account, provider in
self.makeOutgoingCall(account: account, callTo: callTo + "@" + provider, type: .phoneNumber)
})
} else {
// show account selection to make call
showAccountSelection(accounts: AccountManager.getActiveAccounts()) { [callTo] account in
self.makeOutgoingCall(account: account, callTo: callTo, type: .unknown)
}
}
}
}
else if let _ = interaction?.intent as? INStartVideoCallIntent {
let alert : UIAlertController = UIAlertController(title: NSLocalizedString("Video not available", comment: ""), message: NSLocalizedString("This is an audio call, and no video is available", comment: ""), preferredStyle: .alert)
let ok = UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .cancel, handler: nil)
alert.addAction(ok)
DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: {
self.window?.rootViewController?.presentedViewController?.present(alert, animated: true, completion: nil)
})
}
return true
}
func getTelephonyConfiguredAccounts(completion: @escaping (BareJID,String) -> Void) {
var telephonyAccounts = [BareJID:String]()
let accounts = AccountManager.getActiveAccounts()
for account in accounts {
if let provider = AccountSettings.telephonyProvider(account).getString() {
telephonyAccounts[account] = provider
}
}
if telephonyAccounts.isEmpty {
// show alert
showNoProviderConfigured()
} else if telephonyAccounts.count == 1, let first = telephonyAccounts.first {
completion(first.key,first.value)
} else {
// show account selection sheet
showAccountSelection(accounts: Array(telephonyAccounts.keys), completion: { selectedAccount in
completion(selectedAccount ,telephonyAccounts[selectedAccount] ?? "")
})
}
}
func showNoProviderConfigured() {
let alert : UIAlertController = UIAlertController(title: NSLocalizedString("No Telephony Provider!", comment: ""), message: NSLocalizedString("Please Select a Telephony Provider from Settings", comment: ""), preferredStyle: .alert)
let ok = UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .cancel, handler: nil)
alert.addAction(ok)
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
func showAccountSelection(accounts: [BareJID], completion: @escaping (BareJID) -> Void) {
let alert : UIAlertController = UIAlertController(title: NSLocalizedString("Select Account for Call", comment: ""), message: nil, preferredStyle: .alert)
alert.view.backgroundColor = .black
alert.view.layer.cornerRadius = 8.0
let contactNumVC = CallsAccountSelectionController()
contactNumVC.accounts = accounts
contactNumVC.preferredContentSize = CGSize(width: alert.view.frame.width, height: (50.0 * CGFloat(accounts.count)))
alert.setValue(contactNumVC, forKeyPath: "contentViewController")
let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)
alert.addAction(cancel)
contactNumVC.didSelectAccount = { account in
print(account)
completion(account)
}
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
func makeOutgoingCall(account: BareJID, callTo: String, type: INPersonHandleType) {
guard let rootVC = self.window?.rootViewController else { return }
let jid = BareJID(callTo)
#if targetEnvironment(simulator)
#else
VideoCallController.call(jid: jid, from: account, media: [.audio], sender: rootVC)
#endif
}
}

View file

@ -782,14 +782,14 @@
<scene sceneID="7R8-sh-AnU">
<objects>
<tableViewController id="WDE-Vb-oKK" customClass="RosterItemEditViewController" customModule="Snikket" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" allowsSelection="NO" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="Ock-Af-3IY">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="Ock-Af-3IY">
<rect key="frame" x="0.0" y="0.0" width="428" height="926"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<sections>
<tableViewSection headerTitle="Account" id="Mfv-HJ-QDO">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="mk1-zp-AU3">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="mk1-zp-AU3">
<rect key="frame" x="0.0" y="49" width="428" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="mk1-zp-AU3" id="Da1-kS-KYt">
@ -814,7 +814,7 @@
</tableViewSection>
<tableViewSection headerTitle="JID" id="Qgj-eQ-geg">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="ubC-3x-1ej">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="ubC-3x-1ej">
<rect key="frame" x="0.0" y="142.66666603088379" width="428" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ubC-3x-1ej" id="6FY-Rq-hWY">
@ -839,7 +839,7 @@
</tableViewSection>
<tableViewSection headerTitle="Name" id="Kfl-J5-hdD">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="bnU-C3-Ei1">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="bnU-C3-Ei1">
<rect key="frame" x="0.0" y="236.33333206176758" width="428" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="bnU-C3-Ei1" id="sWs-wY-Vy8">
@ -864,7 +864,7 @@
</tableViewSection>
<tableViewSection headerTitle="PRESENCE" id="Q28-Ig-9NP">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="yky-H4-cbk">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="yky-H4-cbk">
<rect key="frame" x="0.0" y="329.99999809265137" width="428" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="yky-H4-cbk" id="Qga-yz-bXa">
@ -890,7 +890,7 @@
</constraints>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="GLY-Pk-gl9">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="GLY-Pk-gl9">
<rect key="frame" x="0.0" y="373.99999809265137" width="428" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="GLY-Pk-gl9" id="P7U-6w-pcx">
@ -918,6 +918,37 @@
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Invite" id="dib-YA-Eiz">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="pth-Xm-NXb">
<rect key="frame" x="0.0" y="467.66666412353516" width="428" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pth-Xm-NXb" id="EmN-0E-Hpp">
<rect key="frame" x="0.0" y="0.0" width="428" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Send Invitation Link" placeholder="Enter contact name" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Rg7-YE-y8H">
<rect key="frame" x="20" y="0.0" width="388" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits"/>
</textField>
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="FPK-6B-DCN">
<rect key="frame" x="378" y="12" width="20" height="20"/>
<color key="color" name="AddToContactsBar"/>
</activityIndicatorView>
</subviews>
<constraints>
<constraint firstItem="FPK-6B-DCN" firstAttribute="centerY" secondItem="EmN-0E-Hpp" secondAttribute="centerY" id="HlI-Sf-kPN"/>
<constraint firstItem="Rg7-YE-y8H" firstAttribute="leading" secondItem="EmN-0E-Hpp" secondAttribute="leadingMargin" id="Yid-O7-fNs"/>
<constraint firstItem="Rg7-YE-y8H" firstAttribute="top" secondItem="EmN-0E-Hpp" secondAttribute="top" id="hll-jG-K6h"/>
<constraint firstAttribute="trailingMargin" secondItem="Rg7-YE-y8H" secondAttribute="trailing" id="iO2-ER-q2P"/>
<constraint firstAttribute="trailingMargin" secondItem="FPK-6B-DCN" secondAttribute="trailing" constant="10" id="jQD-5E-6Ad"/>
<constraint firstAttribute="bottom" secondItem="Rg7-YE-y8H" secondAttribute="bottom" id="rnb-WT-t71"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="WDE-Vb-oKK" id="52x-2u-5zh"/>
@ -938,6 +969,7 @@
</navigationItem>
<connections>
<outlet property="accountTextField" destination="gXY-yq-Y2K" id="HAo-5R-FQQ"/>
<outlet property="invitationLinkIndicator" destination="FPK-6B-DCN" id="zl9-LQ-OPw"/>
<outlet property="jidTextField" destination="BM3-28-huR" id="rnA-hS-bcu"/>
<outlet property="nameTextField" destination="OGf-mX-8z3" id="tdd-eS-Ybc"/>
<outlet property="receivePresenceUpdatesSwitch" destination="QIs-qT-dLK" id="y20-Tc-yVK"/>

View file

@ -515,9 +515,36 @@
<segue destination="FGQ-GL-dYt" kind="show" id="gsA-2D-Fg6"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="aboutSettingsViewCall" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="AboutSettingsViewCell" id="00j-hl-4km" userLabel="AboutSettingsViewCall">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="CallsSettingsViewCell" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="CallsSettingsViewCell" id="k4E-By-FcW">
<rect key="frame" x="0.0" y="445.5" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="k4E-By-FcW" id="u2g-bv-lyd">
<rect key="frame" x="0.0" y="0.0" width="384.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Calls" textAlignment="natural" lineBreakMode="wordWrap" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wfP-Tn-CDA">
<rect key="frame" x="20" y="11" width="356.5" height="22"/>
<accessibility key="accessibilityConfiguration" identifier="accountName"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="wfP-Tn-CDA" firstAttribute="leading" secondItem="u2g-bv-lyd" secondAttribute="leadingMargin" id="0bb-UP-oUQ"/>
<constraint firstAttribute="bottomMargin" secondItem="wfP-Tn-CDA" secondAttribute="bottom" id="7Ss-yP-q7l"/>
<constraint firstAttribute="trailingMargin" secondItem="wfP-Tn-CDA" secondAttribute="trailing" id="KAy-LK-qLI"/>
<constraint firstItem="wfP-Tn-CDA" firstAttribute="top" secondItem="u2g-bv-lyd" secondAttribute="topMargin" id="SJl-yF-XMB"/>
</constraints>
</tableViewCellContentView>
<accessibility key="accessibilityConfiguration" identifier="aboutSettingsViewCall"/>
<connections>
<segue destination="4VG-XN-BdZ" kind="show" id="9J1-2I-oGz"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="aboutSettingsViewCall" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="AboutSettingsViewCell" id="00j-hl-4km" userLabel="AboutSettingsViewCall">
<rect key="frame" x="0.0" y="489.5" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="00j-hl-4km" id="BKo-8a-1ti">
<rect key="frame" x="0.0" y="0.0" width="384.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
@ -1187,7 +1214,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="h70-11-ntf" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2689" y="1685"/>
<point key="canvasLocation" x="2570" y="1797"/>
</scene>
<!--Experimental Settings Scene-->
<scene sceneID="4hq-he-9by">
@ -1385,7 +1412,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Tlr-f3-jiC" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1839" y="1742"/>
<point key="canvasLocation" x="1865" y="1797"/>
</scene>
<!--AboutController-->
<scene sceneID="5Mf-Za-3AY">
@ -1397,9 +1424,63 @@
</objects>
<point key="canvasLocation" x="2050" y="2202"/>
</scene>
<!--Calls settings-->
<scene sceneID="hhD-HQ-XQ1">
<objects>
<tableViewController title="Notification settings" id="4VG-XN-BdZ" userLabel="Calls settings" customClass="CallsSettingsViewController" customModule="Snikket" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="1sU-wb-PeQ">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<sections>
<tableViewSection headerTitle="TELEPHONY" id="v8T-iN-1IT">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="AddToSystemCallHistoryCell" selectionStyle="default" indentationWidth="10" reuseIdentifier="AddToSystemCallHistoryCell" id="I8r-iy-q2W" userLabel="AddToSystemCallHistoryCell">
<rect key="frame" x="0.0" y="49.5" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="I8r-iy-q2W" id="NJh-pm-678">
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add to system call history" textAlignment="natural" lineBreakMode="wordWrap" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ngk-vc-zET">
<rect key="frame" x="20" y="12" width="195.5" height="20.5"/>
<accessibility key="accessibilityConfiguration" identifier="accountName"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UL8-Yi-SF4">
<rect key="frame" x="345" y="6.5" width="51" height="31"/>
<connections>
<action selector="valueChanged:" destination="4VG-XN-BdZ" eventType="valueChanged" id="biy-dX-JX4"/>
</connections>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="leadingMargin" secondItem="Ngk-vc-zET" secondAttribute="leading" id="AJa-Ff-gti"/>
<constraint firstItem="Ngk-vc-zET" firstAttribute="centerY" secondItem="NJh-pm-678" secondAttribute="centerY" id="OmK-Xl-nOm"/>
<constraint firstItem="UL8-Yi-SF4" firstAttribute="centerY" secondItem="NJh-pm-678" secondAttribute="centerY" id="SYD-ix-fy4"/>
<constraint firstItem="UL8-Yi-SF4" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Ngk-vc-zET" secondAttribute="trailing" constant="8" id="Xkk-ZF-rBn"/>
<constraint firstAttribute="trailingMargin" secondItem="UL8-Yi-SF4" secondAttribute="trailing" id="aFH-qx-7yp"/>
</constraints>
</tableViewCellContentView>
<accessibility key="accessibilityConfiguration" identifier="AddToSystemCallHistoryCell"/>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
</tableView>
<navigationItem key="navigationItem" id="b0W-ey-5kA"/>
<connections>
<outlet property="callsSwitch" destination="UL8-Yi-SF4" id="Z8U-Y8-fjZ"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="6ji-YQ-XOK" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="445" y="1797"/>
</scene>
</scenes>
<inferredMetricsTieBreakers>
<segue reference="TOL-19-lPZ"/>
<segue reference="cof-sd-KJv"/>
</inferredMetricsTieBreakers>
<resources>
<namedColor name="chatslistBackground">

View file

@ -1,17 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_0" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Video Call Controller-->
<scene sceneID="F1u-Sh-GDH">
<objects>
<viewController storyboardIdentifier="VideoCallController" modalPresentationStyle="fullScreen" useStoryboardIdentifierAsRestorationIdentifier="YES" id="sh6-q3-LhK" customClass="VideoCallController" customModule="Snikket" customModuleProvider="target" sceneMemberID="viewController">
<viewController storyboardIdentifier="VideoCallController" modalPresentationStyle="overFullScreen" useStoryboardIdentifierAsRestorationIdentifier="YES" id="sh6-q3-LhK" customClass="VideoCallController" customModule="Snikket" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Y9t-qn-5HE" customClass="RTCMTLVideoView">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -825,6 +826,24 @@
</objects>
<point key="canvasLocation" x="61.682242990654203" y="-310.36717062634989"/>
</scene>
<!--Calls Account Selection Controller-->
<scene sceneID="XHS-ke-cDy">
<objects>
<tableViewController id="Kqh-v3-exI" customClass="CallsAccountSelectionController" customModule="Snikket" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" id="muR-BX-DTq">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<connections>
<outlet property="dataSource" destination="Kqh-v3-exI" id="Qt1-PG-wkI"/>
<outlet property="delegate" destination="Kqh-v3-exI" id="tmu-ry-rkW"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="u2n-Tw-xqd" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1018" y="-290"/>
</scene>
</scenes>
<resources>
<image name="appLogo" width="1024" height="1024"/>
@ -837,5 +856,8 @@
<systemColor name="scrollViewTexturedBackgroundColor">
<color red="0.43529411764705878" green="0.44313725490196082" blue="0.47450980392156861" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -58,6 +58,8 @@
<string>Used to save attachements from conversations</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to select avatar</string>
<key>NSUserActivityTypes</key>
<string>INStartCallIntent</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>

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

@ -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";

View file

@ -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";

View file

@ -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";

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

@ -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).";

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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 lhistorique 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 */

View file

@ -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";

View file

@ -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";

View file

@ -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()
}
}
}

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);
}));

View file

@ -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)
}
}

View file

@ -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]
}
}()
}

View file

@ -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 */

View file

@ -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";

View file

@ -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";

View file

@ -50,6 +50,7 @@ public enum Settings: String {
case EnableMarkdownFormatting = "markdown"
case ShowEmoticons
case messageStyling
case addCallsToSystem
@available(iOS 13.0, *)
case linkPreviews

View file

@ -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() {

View file

@ -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])
})
}
}