Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Sign in / Register
Toggle navigation
J
jami-client-ios
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Insights
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
27
Issues
27
List
Boards
Labels
Milestones
Security & Compliance
Security & Compliance
Dependency List
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
savoirfairelinux
jami-client-ios
Commits
40bf3d2c
Commit
40bf3d2c
authored
Mar 26, 2019
by
Kateryna Kostiuk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
support sip account
Change-Id: I1af53252c214742bc23093c90a36ad4f4d09b9f7
parent
32ec4d2d
Changes
87
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
87 changed files
with
2505 additions
and
483 deletions
+2505
-483
Ring/Ring.xcodeproj/project.pbxproj
Ring/Ring.xcodeproj/project.pbxproj
+53
-1
Ring/Ring/Account/AccountModelHelper.swift
Ring/Ring/Account/AccountModelHelper.swift
+29
-0
Ring/Ring/Account/VCardUtils.swift
Ring/Ring/Account/VCardUtils.swift
+0
-18
Ring/Ring/AppDelegate.swift
Ring/Ring/AppDelegate.swift
+4
-13
Ring/Ring/Bridging/AccountCreation/AccountAdapter.h
Ring/Ring/Bridging/AccountCreation/AccountAdapter.h
+3
-0
Ring/Ring/Bridging/AccountCreation/AccountAdapter.mm
Ring/Ring/Bridging/AccountCreation/AccountAdapter.mm
+5
-0
Ring/Ring/Bridging/CallsAdapter.h
Ring/Ring/Bridging/CallsAdapter.h
+1
-0
Ring/Ring/Bridging/CallsAdapter.mm
Ring/Ring/Bridging/CallsAdapter.mm
+4
-0
Ring/Ring/Bridging/Ring-Bridging-Header.h
Ring/Ring/Bridging/Ring-Bridging-Header.h
+3
-1
Ring/Ring/Bridging/Utils.h
Ring/Ring/Bridging/Utils.h
+1
-2
Ring/Ring/Bridging/Utils.mm
Ring/Ring/Bridging/Utils.mm
+15
-2
Ring/Ring/Calls/ButtonsContainerView.swift
Ring/Ring/Calls/ButtonsContainerView.swift
+8
-0
Ring/Ring/Calls/ButtonsContainerView.xib
Ring/Ring/Calls/ButtonsContainerView.xib
+24
-1
Ring/Ring/Calls/ButtonsContainerViewModel.swift
Ring/Ring/Calls/ButtonsContainerViewModel.swift
+3
-1
Ring/Ring/Calls/CallViewController.storyboard
Ring/Ring/Calls/CallViewController.storyboard
+1
-1
Ring/Ring/Calls/CallViewController.swift
Ring/Ring/Calls/CallViewController.swift
+9
-0
Ring/Ring/Calls/CallViewModel.swift
Ring/Ring/Calls/CallViewModel.swift
+22
-4
Ring/Ring/Constants/Generated/Images.swift
Ring/Ring/Constants/Generated/Images.swift
+4
-0
Ring/Ring/Constants/Generated/Strings.swift
Ring/Ring/Constants/Generated/Strings.swift
+41
-0
Ring/Ring/Contact/ContactViewModel.swift
Ring/Ring/Contact/ContactViewModel.swift
+55
-31
Ring/Ring/Database/DBManager.swift
Ring/Ring/Database/DBManager.swift
+30
-24
Ring/Ring/Dialpad/DialpadViewController.storyboard
Ring/Ring/Dialpad/DialpadViewController.storyboard
+155
-0
Ring/Ring/Dialpad/DialpadViewController.swift
Ring/Ring/Dialpad/DialpadViewController.swift
+139
-0
Ring/Ring/Dialpad/DialpadViewModel.swift
Ring/Ring/Dialpad/DialpadViewModel.swift
+66
-0
Ring/Ring/Extensions/String+Helpers.swift
Ring/Ring/Extensions/String+Helpers.swift
+4
-0
Ring/Ring/Extensions/UIViewController+Ring.swift
Ring/Ring/Extensions/UIViewController+Ring.swift
+15
-18
Ring/Ring/Features/ContactRequests/ContactRequestItem.swift
Ring/Ring/Features/ContactRequests/ContactRequestItem.swift
+4
-1
Ring/Ring/Features/ContactRequests/ContactRequestsViewModel.swift
...g/Features/ContactRequests/ContactRequestsViewModel.swift
+6
-1
Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
...atures/Conversations/Conversation/Cells/MessageCell.swift
+5
-3
Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
...nversations/Conversation/ConversationViewController.swift
+25
-20
Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
...es/Conversations/Conversation/ConversationViewModel.swift
+50
-38
Ring/Ring/Features/Conversations/Conversation/MessageAccessoryView.swift
...res/Conversations/Conversation/MessageAccessoryView.swift
+3
-1
Ring/Ring/Features/Conversations/Conversation/MessageViewModel.swift
...eatures/Conversations/Conversation/MessageViewModel.swift
+6
-4
Ring/Ring/Features/Conversations/ConversationsCoordinator.swift
...ing/Features/Conversations/ConversationsCoordinator.swift
+22
-2
Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.storyboard
...onversations/SmartList/SmartlistViewController.storyboard
+46
-0
Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
...res/Conversations/SmartList/SmartlistViewController.swift
+107
-6
Ring/Ring/Features/Conversations/SmartList/SmartlistViewModel.swift
...Features/Conversations/SmartList/SmartlistViewModel.swift
+56
-26
Ring/Ring/Features/Me/Me/AccountHeader.xib
Ring/Ring/Features/Me/Me/AccountHeader.xib
+11
-8
Ring/Ring/Features/Me/Me/BannedContactCell.swift
Ring/Ring/Features/Me/Me/BannedContactCell.swift
+2
-2
Ring/Ring/Features/Me/Me/BlockListViewModel.swift
Ring/Ring/Features/Me/Me/BlockListViewModel.swift
+19
-18
Ring/Ring/Features/Me/Me/MeViewController.swift
Ring/Ring/Features/Me/Me/MeViewController.swift
+196
-4
Ring/Ring/Features/Me/Me/MeViewModel.swift
Ring/Ring/Features/Me/Me/MeViewModel.swift
+213
-15
Ring/Ring/Features/Walkthrough/CreateSipAccount/CreateSipAccountViewController.storyboard
...reateSipAccount/CreateSipAccountViewController.storyboard
+239
-0
Ring/Ring/Features/Walkthrough/CreateSipAccount/CreateSipAccountViewController.swift
...ugh/CreateSipAccount/CreateSipAccountViewController.swift
+122
-0
Ring/Ring/Features/Walkthrough/CreateSipAccount/CreateSipAccountViewModel.swift
...kthrough/CreateSipAccount/CreateSipAccountViewModel.swift
+52
-0
Ring/Ring/Features/Walkthrough/WalkthroughCoordinator.swift
Ring/Ring/Features/Walkthrough/WalkthroughCoordinator.swift
+4
-0
Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.storyboard
...ures/Walkthrough/Welcome/WelcomeViewController.storyboard
+18
-0
Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.swift
.../Features/Walkthrough/Welcome/WelcomeViewController.swift
+9
-0
Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewModel.swift
.../Ring/Features/Walkthrough/Welcome/WelcomeViewModel.swift
+6
-0
Ring/Ring/Helpers/JamiURI.swift
Ring/Ring/Helpers/JamiURI.swift
+130
-0
Ring/Ring/Models/AccountCredentialsModel.swift
Ring/Ring/Models/AccountCredentialsModel.swift
+8
-0
Ring/Ring/Models/AccountModel.swift
Ring/Ring/Models/AccountModel.swift
+31
-10
Ring/Ring/Models/CallModel.swift
Ring/Ring/Models/CallModel.swift
+5
-5
Ring/Ring/Models/ContactModel.swift
Ring/Ring/Models/ContactModel.swift
+21
-14
Ring/Ring/Models/ConversationModel.swift
Ring/Ring/Models/ConversationModel.swift
+14
-6
Ring/Ring/Models/MessageModel.swift
Ring/Ring/Models/MessageModel.swift
+3
-3
Ring/Ring/Protocols/ConversationNavigation.swift
Ring/Ring/Protocols/ConversationNavigation.swift
+6
-3
Ring/Ring/QRCode/ScanViewController.swift
Ring/Ring/QRCode/ScanViewController.swift
+1
-1
Ring/Ring/QRCode/ScanViewModel.swift
Ring/Ring/QRCode/ScanViewModel.swift
+3
-2
Ring/Ring/Resources/Images.xcassets/back_button.imageset/Contents.json
...ources/Images.xcassets/back_button.imageset/Contents.json
+3
-0
Ring/Ring/Resources/Images.xcassets/call_button.imageset/Contents.json
...ources/Images.xcassets/call_button.imageset/Contents.json
+3
-0
Ring/Ring/Resources/Images.xcassets/dialpad.imageset/Contents.json
.../Resources/Images.xcassets/dialpad.imageset/Contents.json
+26
-0
Ring/Ring/Resources/Images.xcassets/dialpad.imageset/icons8-keypad-1.png
...rces/Images.xcassets/dialpad.imageset/icons8-keypad-1.png
+0
-0
Ring/Ring/Resources/Images.xcassets/dialpad.imageset/icons8-keypad-2.png
...rces/Images.xcassets/dialpad.imageset/icons8-keypad-2.png
+0
-0
Ring/Ring/Resources/Images.xcassets/dialpad.imageset/icons8-keypad.png
...ources/Images.xcassets/dialpad.imageset/icons8-keypad.png
+0
-0
Ring/Ring/Resources/Images.xcassets/ic_hide_input.imageset/Contents.json
...rces/Images.xcassets/ic_hide_input.imageset/Contents.json
+26
-0
Ring/Ring/Resources/Images.xcassets/ic_hide_input.imageset/ic_hide_input-1.png
...mages.xcassets/ic_hide_input.imageset/ic_hide_input-1.png
+0
-0
Ring/Ring/Resources/Images.xcassets/ic_hide_input.imageset/ic_hide_input-2.png
...mages.xcassets/ic_hide_input.imageset/ic_hide_input-2.png
+0
-0
Ring/Ring/Resources/Images.xcassets/ic_hide_input.imageset/ic_hide_input.png
.../Images.xcassets/ic_hide_input.imageset/ic_hide_input.png
+0
-0
Ring/Ring/Resources/Images.xcassets/ic_show_input.imageset/Contents.json
...rces/Images.xcassets/ic_show_input.imageset/Contents.json
+26
-0
Ring/Ring/Resources/Images.xcassets/ic_show_input.imageset/ic_show_input-1.png
...mages.xcassets/ic_show_input.imageset/ic_show_input-1.png
+0
-0
Ring/Ring/Resources/Images.xcassets/ic_show_input.imageset/ic_show_input-2.png
...mages.xcassets/ic_show_input.imageset/ic_show_input-2.png
+0
-0
Ring/Ring/Resources/Images.xcassets/ic_show_input.imageset/ic_show_input.png
.../Images.xcassets/ic_show_input.imageset/ic_show_input.png
+0
-0
Ring/Ring/Resources/Images.xcassets/phone_book.imageset/Contents.json
...sources/Images.xcassets/phone_book.imageset/Contents.json
+26
-0
Ring/Ring/Resources/Images.xcassets/phone_book.imageset/icons8-address_book_2-1.png
....xcassets/phone_book.imageset/icons8-address_book_2-1.png
+0
-0
Ring/Ring/Resources/Images.xcassets/phone_book.imageset/icons8-address_book_2-2.png
....xcassets/phone_book.imageset/icons8-address_book_2-2.png
+0
-0
Ring/Ring/Resources/Images.xcassets/phone_book.imageset/icons8-address_book_2.png
...es.xcassets/phone_book.imageset/icons8-address_book_2.png
+0
-0
Ring/Ring/Resources/en.lproj/Localizable.strings
Ring/Ring/Resources/en.lproj/Localizable.strings
+20
-0
Ring/Ring/Services/AccountsService.swift
Ring/Ring/Services/AccountsService.swift
+51
-14
Ring/Ring/Services/CallsService.swift
Ring/Ring/Services/CallsService.swift
+12
-6
Ring/Ring/Services/ContactsService.swift
Ring/Ring/Services/ContactsService.swift
+38
-24
Ring/Ring/Services/ConversationsManager.swift
Ring/Ring/Services/ConversationsManager.swift
+31
-34
Ring/Ring/Services/ConversationsService.swift
Ring/Ring/Services/ConversationsService.swift
+71
-62
Ring/Ring/Services/GeneratedInteractionsManager.swift
Ring/Ring/Services/GeneratedInteractionsManager.swift
+19
-20
Ring/Ring/Services/PresenceService.swift
Ring/Ring/Services/PresenceService.swift
+1
-1
Ring/Ring/Services/ProfilesService.swift
Ring/Ring/Services/ProfilesService.swift
+13
-10
Ring/Ring/TabBar/ChatTabBarItemViewModel.swift
Ring/Ring/TabBar/ChatTabBarItemViewModel.swift
+2
-2
No files found.
Ring/Ring.xcodeproj/project.pbxproj
View file @
40bf3d2c
This diff is collapsed.
Click to expand it.
Ring/Ring/Account/AccountModelHelper.swift
View file @
40bf3d2c
...
...
@@ -27,6 +27,7 @@ import SwiftyBeaver
struct
AccountModelHelper
{
fileprivate
static
let
ringIdPrefix
=
"ring:"
fileprivate
static
let
sipIdPrefix
=
"sip:"
fileprivate
var
account
:
AccountModel
...
...
@@ -145,6 +146,34 @@ struct AccountModelHelper {
}
}
public
var
uri
:
String
?
{
if
self
.
account
.
type
==
AccountType
.
sip
{
let
name
=
self
.
account
.
details
!
.
get
(
withConfigKeyModel
:
ConfigKeyModel
.
init
(
withKey
:
.
accountUsername
))
let
server
=
self
.
account
.
details
!
.
get
(
withConfigKeyModel
:
ConfigKeyModel
.
init
(
withKey
:
.
accountHostname
))
let
port
=
self
.
account
.
details
!
.
get
(
withConfigKeyModel
:
ConfigKeyModel
.
init
(
withKey
:
.
localPort
))
var
uri
:
String
if
!
name
.
isEmpty
{
uri
=
AccountModelHelper
.
sipIdPrefix
+
name
if
!
server
.
isEmpty
{
uri
+=
"@"
+
server
if
!
port
.
isEmpty
{
uri
+=
":"
+
port
}
return
uri
}
else
{
return
uri
}
}
return
nil
}
else
{
guard
let
ringId
=
self
.
ringId
else
{
return
nil
}
return
AccountModelHelper
.
ringIdPrefix
.
appending
(
ringId
)
}
}
public
var
havePassword
:
Bool
{
let
noPassword
:
String
=
self
.
account
.
details
?
.
get
(
withConfigKeyModel
:
ConfigKeyModel
(
withKey
:
ConfigKey
.
archiveHasPassword
))
??
"false"
return
noPassword
==
"true"
?
true
:
false
...
...
Ring/Ring/Account/VCardUtils.swift
View file @
40bf3d2c
...
...
@@ -32,24 +32,6 @@ enum VCardFiles: String {
case
myProfile
}
class
VCardUtils
{
class
func
saveVCard
(
vCard
:
CNContact
,
withName
name
:
String
,
inFolder
folder
:
String
)
->
Observable
<
Void
>
{
return
Observable
.
create
{
observable
in
if
let
directoryURL
=
VCardUtils
.
getFilePath
(
forFile
:
name
,
inFolder
:
folder
,
createIfNotExists
:
true
)
{
do
{
let
data
=
try
CNContactVCardSerialization
.
dataWithImageAndUUID
(
from
:
vCard
,
andImageCompression
:
nil
)
try
data
.
write
(
to
:
directoryURL
)
observable
.
on
(
.
completed
)
}
catch
{
observable
.
on
(
.
error
(
ContactServiceError
.
saveVCardFailed
))
}
}
else
{
observable
.
on
(
.
error
(
ContactServiceError
.
saveVCardFailed
))
}
return
Disposables
.
create
{
}
}
}
class
func
loadVCard
(
named
name
:
String
,
inFolder
folder
:
String
,
contactService
:
ContactsService
?
=
nil
)
->
Single
<
CNContact
>
{
return
Single
.
create
(
subscribe
:
{
single
in
if
let
contactRequest
=
contactService
?
.
contactRequest
(
withRingId
:
name
)
{
...
...
Ring/Ring/AppDelegate.swift
View file @
40bf3d2c
...
...
@@ -25,8 +25,9 @@ import UIKit
import
SwiftyBeaver
import
RxSwift
import
Chameleon
import
Contacts
//
import Contacts
import
PushKit
import
ContactsUI
// swiftlint:disable identifier_name
...
...
@@ -162,14 +163,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
self
.
log
.
error
(
"Can't get current account!"
)
return
}
self
.
contactsService
.
loadContacts
(
withAccount
:
currentAccount
)
self
.
contactsService
.
loadContactRequests
(
withAccount
:
currentAccount
)
self
.
presenceService
.
subscribeBuddies
(
withAccount
:
currentAccount
,
withContacts
:
self
.
contactsService
.
contacts
.
value
)
if
let
ringID
=
AccountModelHelper
(
withAccount
:
currentAccount
)
.
ringId
{
self
.
conversationManager
?
.
prepareConversationsForAccount
(
accountId
:
currentAccount
.
id
,
accountUri
:
ringID
)
}
self
.
reloadDataFor
(
account
:
currentAccount
)
if
self
.
accountService
.
proxyEnabled
()
{
self
.
registerVoipNotifications
()
...
...
@@ -203,10 +196,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
self
.
contactsService
.
loadContacts
(
withAccount
:
account
)
self
.
contactsService
.
loadContactRequests
(
withAccount
:
account
)
self
.
presenceService
.
subscribeBuddies
(
withAccount
:
account
,
withContacts
:
self
.
contactsService
.
contacts
.
value
)
if
let
ringID
=
AccountModelHelper
(
withAccount
:
account
)
.
ringId
{
self
.
conversationManager
?
.
prepareConversationsForAccount
(
accountId
:
account
.
id
,
accountUri
:
ringID
)
}
self
.
conversationManager
?
.
prepareConversationsForAccount
(
accountId
:
account
.
id
)
}
func
applicationDidEnterBackground
(
_
application
:
UIApplication
)
{
...
...
Ring/Ring/Bridging/AccountCreation/AccountAdapter.h
View file @
40bf3d2c
...
...
@@ -50,6 +50,9 @@
-
(
void
)
setAccountDetails
:(
NSString
*
)
accountID
details
:(
NSDictionary
*
)
details
;
-
(
void
)
setAccountCredentials
:(
NSString
*
)
accountID
credentials
:(
NSArray
*
)
credentials
;
-
(
void
)
setAccountActive
:(
NSString
*
)
accountID
active
:(
bool
)
active
;
...
...
Ring/Ring/Bridging/AccountCreation/AccountAdapter.mm
View file @
40bf3d2c
...
...
@@ -109,6 +109,11 @@ static id <AccountAdapterDelegate> _delegate;
setAccountDetails(std::string([accountID UTF8String]),[Utils dictionnaryToMap:details]);
}
- (void)setAccountCredentials:(NSString *)accountID
credentials:(NSArray*) credentials {
setCredentials(std::string([accountID UTF8String]), [Utils arrayOfDictionnarisToVectorOfMap:credentials]);
}
- (void)setAccountActive:(NSString *)accountID
active:(bool)active {
setAccountActive(std::string([accountID UTF8String]), active);
...
...
Ring/Ring/Bridging/CallsAdapter.h
View file @
40bf3d2c
...
...
@@ -38,5 +38,6 @@
-
(
NSArray
<
NSString
*>*
)
calls
;
-
(
void
)
sendTextMessageWithCallID
:(
NSString
*
)
callId
message
:(
NSDictionary
*
)
message
accountId
:(
NSString
*
)
accountId
sMixed
:(
bool
)
isMixed
;
-
(
BOOL
)
muteMedia
:(
NSString
*
)
callId
mediaType
:(
NSString
*
)
media
muted
:(
bool
)
muted
;
-
(
void
)
playDTMF
:(
NSString
*
)
code
;
@end
Ring/Ring/Bridging/CallsAdapter.mm
View file @
40bf3d2c
...
...
@@ -155,6 +155,10 @@ static id <CallsAdapterDelegate> _delegate;
return unhold(std::string([callId UTF8String]));
}
- (void) playDTMF:(NSString*)code {
playDTMF(std::string([code UTF8String]));
}
- (NSString*)placeCallWithAccountId:(NSString*)accountId toRingId:(NSString*)ringId details:(NSDictionary*)details {
std::string callId;
callId = placeCall(std::string([accountId UTF8String]), std::string([ringId UTF8String]), [Utils dictionnaryToMap:details]);
...
...
Ring/Ring/Bridging/Ring-Bridging-Header.h
View file @
40bf3d2c
...
...
@@ -36,7 +36,9 @@
#import "VideoAdapter.h"
#import "AudioAdapter.h"
#import <CommonCrypto/CommonCrypto.h>
#import <Contacts/Contacts.h>
//#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
#import <UserNotifications/UserNotifications.h>
#import "CallsAdapter.h"
#import <PushKit/PushKit.h>
#import <UserNotifications/UserNotifications.h>
...
...
Ring/Ring/Bridging/Utils.h
View file @
40bf3d2c
...
...
@@ -34,6 +34,5 @@
+
(
NSArray
*
)
vectorOfMapsToArray
:(
const
std
::
vector
<
std
::
map
<
std
::
string
,
std
::
string
>>&
)
vectorOfMaps
;
+
(
NSData
*
)
dataFromVectorOfUInt8
:(
std
::
vector
<
uint8_t
>
)
vectorOfUInt8
;
+
(
std
::
vector
<
uint8_t
>
)
vectorOfUInt8FromData
:(
NSData
*
)
data
;
+
(
std
::
vector
<
std
::
map
<
std
::
string
,
std
::
string
>>
)
arrayOfDictionnarisToVectorOfMap
:(
NSArray
*
)
dictionaries
;
@end
Ring/Ring/Bridging/Utils.mm
View file @
40bf3d2c
...
...
@@ -52,10 +52,24 @@
resMap.insert(std::pair<std::string, std::string>(
std::string([key UTF8String]),
std::string([[dict objectForKey:key] UTF8String])));
return resMap;
}
+ (std::vector<std::map<std::string, std::string>>)arrayOfDictionnarisToVectorOfMap:(NSArray*)dictionaries {
std::vector<std::map<std::string, std::string>> resVector;
for (NSDictionary* dictionary in dictionaries) {
std::map<std::string, std::string> resMap;
for (id key in dictionary) {
resMap.insert(std::pair<std::string,
std::string>(
std::string([key UTF8String]),
std::string([[dictionary objectForKey:key] UTF8String])));
}
resVector.push_back(resMap);
}
return resVector;
}
+ (NSArray*)vectorOfMapsToArray:
(const std::vector<std::map<std::string, std::string>>&)vectorOfMaps {
NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:vectorOfMaps.size()];
...
...
@@ -88,7 +102,6 @@
for ( int i = 0; i < data.length; i++ ) {
vector.push_back(bytes[i]);
}
return vector;
}
...
...
Ring/Ring/Calls/ButtonsContainerView.swift
View file @
40bf3d2c
...
...
@@ -32,6 +32,7 @@ class ButtonsContainerView: UIView, NibLoadable {
@IBOutlet
weak
var
muteAudioButton
:
UIButton
!
@IBOutlet
weak
var
muteVideoButton
:
UIButton
!
@IBOutlet
weak
var
pauseCallButton
:
UIButton
!
@IBOutlet
weak
var
dialpadButton
:
UIButton
!
@IBOutlet
weak
var
switchSpeakerButton
:
UIButton
!
@IBOutlet
weak
var
cancelButton
:
UIButton
!
@IBOutlet
weak
var
spaceButton
:
UIButton
!
...
...
@@ -90,6 +91,7 @@ class ButtonsContainerView: UIView, NibLoadable {
muteAudioButton
.
isHidden
=
true
muteVideoButton
.
isHidden
=
true
pauseCallButton
.
isHidden
=
true
dialpadButton
.
isHidden
=
true
switchSpeakerButton
.
isHidden
=
true
cancelButton
.
isHidden
=
false
}
...
...
@@ -102,6 +104,9 @@ class ButtonsContainerView: UIView, NibLoadable {
if
self
.
viewModel
?
.
isAudioOnly
??
false
{
muteVideoButton
.
isHidden
=
true
spaceButton
.
isHidden
=
true
if
self
.
viewModel
?
.
isSipCall
??
false
{
dialpadButton
.
isHidden
=
false
}
}
else
{
muteVideoButton
.
isHidden
=
false
}
...
...
@@ -118,6 +123,9 @@ class ButtonsContainerView: UIView, NibLoadable {
if
self
.
viewModel
?
.
isAudioOnly
??
false
{
muteVideoButton
.
isHidden
=
true
spaceButton
.
isHidden
=
true
if
self
.
viewModel
?
.
isSipCall
??
false
{
dialpadButton
.
isHidden
=
false
}
}
else
{
muteVideoButton
.
isHidden
=
false
}
...
...
Ring/Ring/Calls/ButtonsContainerView.xib
View file @
40bf3d2c
...
...
@@ -20,6 +20,7 @@
<outlet
property=
"container"
destination=
"a9g-pf-bHy"
id=
"6bw-CB-5qN"
/>
<outlet
property=
"containerHeightConstraint"
destination=
"Gjk-7U-rEe"
id=
"G5G-Uh-zRV"
/>
<outlet
property=
"containerView"
destination=
"iN0-l3-epB"
id=
"mcP-kY-dVO"
/>
<outlet
property=
"dialpadButton"
destination=
"izN-w3-Pc8"
id=
"JWv-ys-ugD"
/>
<outlet
property=
"muteAudioButton"
destination=
"tXL-FB-O0X"
id=
"6Bh-x3-veQ"
/>
<outlet
property=
"muteVideoButton"
destination=
"W7F-nH-kda"
id=
"MWK-JU-544"
/>
<outlet
property=
"pauseCallButton"
destination=
"MPk-dB-dhR"
id=
"W4G-AB-WFw"
/>
...
...
@@ -159,10 +160,31 @@
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</button>
<button
hidden=
"YES"
opaque=
"NO"
contentMode=
"scaleToFill"
contentHorizontalAlignment=
"center"
contentVerticalAlignment=
"center"
lineBreakMode=
"middleTruncation"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"izN-w3-Pc8"
>
<rect
key=
"frame"
x=
"345"
y=
"0.0"
width=
"50"
height=
"50"
/>
<constraints>
<constraint
firstAttribute=
"height"
constant=
"50"
id=
"PII-PT-xhP"
/>
<constraint
firstAttribute=
"width"
constant=
"50"
id=
"wje-Ic-6hu"
/>
</constraints>
<color
key=
"tintColor"
red=
"0.0"
green=
"0.0"
blue=
"0.0"
alpha=
"0.5"
colorSpace=
"custom"
customColorSpace=
"sRGB"
/>
<state
key=
"normal"
image=
"dialpad"
/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute
type=
"boolean"
keyPath=
"roundedCorners"
value=
"YES"
/>
<userDefinedRuntimeAttribute
type=
"number"
keyPath=
"borderWidth"
>
<real
key=
"value"
value=
"2"
/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute
type=
"color"
keyPath=
"borderColor"
>
<color
key=
"value"
red=
"0.0"
green=
"0.0"
blue=
"0.0"
alpha=
"0.5"
colorSpace=
"custom"
customColorSpace=
"sRGB"
/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute
type=
"number"
keyPath=
"cornerRadius"
>
<real
key=
"value"
value=
"25"
/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</button>
</subviews>
<color
key=
"backgroundColor"
white=
"0.0"
alpha=
"0.0"
colorSpace=
"calibratedWhite"
/>
<constraints>
<constraint
firstAttribute=
"width"
priority=
"250"
constant=
"2
0
0"
id=
"ZuV-LV-CYZ"
/>
<constraint
firstAttribute=
"width"
priority=
"250"
constant=
"2
3
0"
id=
"ZuV-LV-CYZ"
/>
<constraint
firstAttribute=
"height"
constant=
"50"
id=
"gaC-GZ-ftw"
/>
</constraints>
</stackView>
...
...
@@ -217,6 +239,7 @@
</objects>
<resources>
<image
name=
"audio_running"
width=
"48"
height=
"48"
/>
<image
name=
"dialpad"
width=
"75"
height=
"75"
/>
<image
name=
"disable_speakerphone"
width=
"48"
height=
"48"
/>
<image
name=
"pause_call"
width=
"48"
height=
"48"
/>
<image
name=
"stop_call"
width=
"48"
height=
"48"
/>
...
...
Ring/Ring/Calls/ButtonsContainerViewModel.swift
View file @
40bf3d2c
...
...
@@ -33,17 +33,19 @@ class ButtonsContainerViewModel {
let
callID
:
String
let
disposeBag
=
DisposeBag
()
var
isAudioOnly
:
Bool
var
isSipCall
:
Bool
let
avalaibleCallOptions
=
BehaviorSubject
<
CallOptions
>
(
value
:
.
none
)
lazy
var
observableCallOptions
:
Observable
<
CallOptions
>
=
{
[
unowned
self
]
in
return
self
.
avalaibleCallOptions
.
asObservable
()
}()
init
(
isAudioOnly
:
Bool
,
with
callService
:
CallsService
,
audioService
:
AudioService
,
callID
:
String
)
{
init
(
isAudioOnly
:
Bool
,
with
callService
:
CallsService
,
audioService
:
AudioService
,
callID
:
String
,
isSipCall
:
Bool
)
{
self
.
callService
=
callService
self
.
audioService
=
audioService
self
.
callID
=
callID
self
.
isAudioOnly
=
isAudioOnly
self
.
isSipCall
=
isSipCall
checkCallOptions
()
}
...
...
Ring/Ring/Calls/CallViewController.storyboard
View file @
40bf3d2c
...
...
@@ -369,6 +369,6 @@
<resources>
<image
name=
"ic_contact_picture"
width=
"512"
height=
"512"
/>
<image
name=
"left_arrow"
width=
"138.24000549316406"
height=
"138.24000549316406"
/>
<image
name=
"switch_camera"
width=
"
100"
height=
"100
"
/>
<image
name=
"switch_camera"
width=
"
75"
height=
"75
"
/>
</resources>
</document>
Ring/Ring/Calls/CallViewController.swift
View file @
40bf3d2c
...
...
@@ -187,6 +187,15 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased {
self
?
.
removeFromScreen
()
})
.
disposed
(
by
:
self
.
disposeBag
)
self
.
buttonsContainer
.
dialpadButton
.
rx
.
tap
.
subscribe
(
onNext
:
{
[
weak
self
]
in
// guard let bag = self?.viewModel.injectionBag else {return}
// let dialpadViewController = DialpadViewController.instantiate(with: bag)
// dialpadViewController.viewModel.inCallDialpad = true
// self?.present(dialpadViewController, animated: true, completion: nil)
self
?
.
viewModel
.
showDialpad
()
})
.
disposed
(
by
:
self
.
disposeBag
)
self
.
buttonsContainer
.
muteAudioButton
.
rx
.
tap
.
subscribe
(
onNext
:
{
[
weak
self
]
in
self
?
.
viewModel
.
toggleMuteAudio
()
...
...
Ring/Ring/Calls/CallViewModel.swift
View file @
40bf3d2c
...
...
@@ -51,20 +51,32 @@ class CallViewModel: Stateable, ViewModel {
guard
let
call
=
self
.
call
else
{
return
}
guard
let
account
=
self
.
accountService
.
currentAccount
else
{
return
}
isHeadsetConnected
=
self
.
audioService
.
isHeadsetConnected
.
value
isAudioOnly
=
call
.
isAudioOnly
containerViewModel
=
ButtonsContainerViewModel
(
isAudioOnly
:
self
.
isAudioOnly
,
with
:
self
.
callService
,
audioService
:
self
.
audioService
,
callID
:
call
.
callId
)
let
type
=
account
.
type
==
AccountType
.
sip
containerViewModel
=
ButtonsContainerViewModel
(
isAudioOnly
:
self
.
isAudioOnly
,
with
:
self
.
callService
,
audioService
:
self
.
audioService
,
callID
:
call
.
callId
,
isSipCall
:
type
)
}
}
// data for ViewController binding
lazy
var
contactImageData
:
Observable
<
Data
?
>
?
=
{
guard
let
call
=
self
.
call
,
let
account
=
self
.
accountService
.
currentAccount
else
{
guard
let
call
=
self
.
call
,
let
account
=
self
.
accountService
.
getAccount
(
fromAccountId
:
call
.
accountId
)
else
{
return
nil
}
return
self
.
profileService
.
getProfile
(
ringId
:
call
.
participantRingId
,
let
type
=
account
.
type
==
AccountType
.
sip
?
URIType
.
sip
:
URIType
.
ring
guard
let
uriString
=
JamiURI
.
init
(
schema
:
type
,
infoHach
:
call
.
participantUri
,
account
:
account
)
.
uriString
else
{
return
nil
}
return
self
.
profileService
.
getProfile
(
uri
:
uriString
,
createIfNotexists
:
true
,
accountId
:
account
.
id
)
.
filter
({
profile
in
guard
let
photo
=
profile
.
photo
else
{
...
...
@@ -288,6 +300,7 @@ class CallViewModel: Stateable, ViewModel {
}()
var
containerViewModel
:
ButtonsContainerViewModel
?
let
injectionBag
:
InjectionBag
required
init
(
with
injectionBag
:
InjectionBag
)
{
self
.
callService
=
injectionBag
.
callService
...
...
@@ -296,6 +309,7 @@ class CallViewModel: Stateable, ViewModel {
self
.
videoService
=
injectionBag
.
videoService
self
.
audioService
=
injectionBag
.
audioService
self
.
profileService
=
injectionBag
.
profileService
self
.
injectionBag
=
injectionBag
callService
.
currentCall
.
filter
({
[
weak
self
]
call
in
return
call
.
callId
==
self
?
.
call
?
.
callId
...
...
@@ -416,4 +430,8 @@ class CallViewModel: Stateable, ViewModel {
videoService
.
setCameraOrientation
(
orientation
:
orientation
,
callID
:
self
.
call
?
.
callId
)
}
func
showDialpad
()
{
self
.
stateSubject
.
onNext
(
ConversationState
.
showDialpad
(
inCall
:
true
))
}
}
Ring/Ring/Constants/Generated/Images.swift
View file @
40bf3d2c
...
...
@@ -35,6 +35,7 @@ internal enum Asset {
internal
static
let
conversationIcon
=
ImageAsset
(
name
:
"conversation_icon"
)
internal
static
let
cross
=
ImageAsset
(
name
:
"cross"
)
internal
static
let
device
=
ImageAsset
(
name
:
"device"
)
internal
static
let
dialpad
=
ImageAsset
(
name
:
"dialpad"
)
internal
static
let
disableSpeakerphone
=
ImageAsset
(
name
:
"disable_speakerphone"
)
internal
static
let
doneIcon
=
ImageAsset
(
name
:
"done_icon"
)
internal
static
let
downloadIcon
=
ImageAsset
(
name
:
"download_icon"
)
...
...
@@ -42,11 +43,14 @@ internal enum Asset {
internal
static
let
fallbackAvatar
=
ImageAsset
(
name
:
"fallback_avatar"
)
internal
static
let
icContactPicture
=
ImageAsset
(
name
:
"ic_contact_picture"
)
internal
static
let
icConversationRemove
=
ImageAsset
(
name
:
"ic_conversation_remove"
)
internal
static
let
icHideInput
=
ImageAsset
(
name
:
"ic_hide_input"
)
internal
static
let
icShowInput
=
ImageAsset
(
name
:
"ic_show_input"
)
internal
static
let
infoArrow
=
ImageAsset
(
name
:
"info_arrow"
)
internal
static
let
jamiIcon
=
ImageAsset
(
name
:
"jamiIcon"
)
internal
static
let
leftArrow
=
ImageAsset
(
name
:
"left_arrow"
)
internal
static
let
moreSettings
=
ImageAsset
(
name
:
"more_settings"
)
internal
static
let
pauseCall
=
ImageAsset
(
name
:
"pause_call"
)
internal
static
let
phoneBook
=
ImageAsset
(
name
:
"phone_book"
)
internal
static
let
qrCode
=
ImageAsset
(
name
:
"qr_code"
)
internal
static
let
qrCodeScan
=
ImageAsset
(
name
:
"qr_code_scan"
)
internal
static
let
revokeDevice
=
ImageAsset
(
name
:
"revoke_device"
)
...
...
Ring/Ring/Constants/Generated/Strings.swift
View file @
40bf3d2c
...
...
@@ -12,6 +12,41 @@ import Foundation
// swiftlint:disable nesting type_body_length type_name
internal
enum
L10n
{
internal
enum
Account
{
/// Account Status
internal
static
let
accountStatus
=
L10n
.
tr
(
"Localizable"
,
"account.accountStatus"
)
/// Create Sip Account
internal
static
let
createSipAccount
=
L10n
.
tr
(
"Localizable"
,
"account.createSipAccount"
)
/// Enable Account
internal
static
let
enableAccount
=
L10n
.
tr
(
"Localizable"
,
"account.enableAccount"
)
/// Enter Password
internal
static
let
passwordLabel
=
L10n
.
tr
(
"Localizable"
,
"account.passwordLabel"
)
/// Port
internal
static
let
port
=
L10n
.
tr
(
"Localizable"
,
"account.port"
)
/// Enter Port Number
internal
static
let
portLabel
=
L10n
.
tr
(
"Localizable"
,
"account.portLabel"
)
/// Enter Address
internal
static
let
serverLabel
=
L10n
.
tr
(
"Localizable"
,
"account.serverLabel"
)
/// Password
internal
static
let
sipPassword
=
L10n
.
tr
(
"Localizable"
,
"account.sipPassword"
)
/// SIP Server
internal
static
let
sipServer
=
L10n
.
tr
(
"Localizable"
,
"account.sipServer"
)
/// User Name
internal
static
let
sipUsername
=
L10n
.
tr
(
"Localizable"
,
"account.sipUsername"
)
/// Connecting
internal
static
let
statusConnecting
=
L10n
.
tr
(
"Localizable"
,
"account.statusConnecting"
)
/// Connection Error
internal
static
let
statusConnectionerror
=
L10n
.
tr
(
"Localizable"
,
"account.statusConnectionerror"
)
/// Offline
internal
static
let
statusOffline
=
L10n
.
tr
(
"Localizable"
,
"account.statusOffline"
)
/// Online
internal
static
let
statusOnline
=
L10n
.
tr
(
"Localizable"
,
"account.statusOnline"
)
/// Unknown
internal
static
let
statusUnknown
=
L10n
.
tr
(
"Localizable"
,
"account.statusUnknown"
)
/// Enter Username
internal
static
let
usernameLabel
=
L10n
.
tr
(
"Localizable"
,
"account.usernameLabel"
)
}
internal
enum
AccountPage
{
/// Block List
internal
static
let
blockedContacts
=
L10n
.
tr
(
"Localizable"
,
"accountPage.blockedContacts"
)
...
...
@@ -80,6 +115,8 @@ internal enum L10n {
}
internal
enum
Actions
{
/// Back
internal
static
let
backAction
=
L10n
.
tr
(
"Localizable"
,
"actions.backAction"
)
/// Block
internal
static
let
blockAction
=
L10n
.
tr
(
"Localizable"
,
"actions.blockAction"
)
/// Cancel
...
...
@@ -350,6 +387,8 @@ internal enum L10n {
internal
static
let
noConversation
=
L10n
.
tr
(
"Localizable"
,
"smartlist.noConversation"
)
/// No network connectivity
internal
static
let
noNetworkConnectivity
=
L10n
.
tr
(
"Localizable"
,
"smartlist.noNetworkConnectivity"
)
/// Selected contact does not have any number
internal
static
let
noNumber
=
L10n
.
tr
(
"Localizable"
,
"smartlist.noNumber"
)
/// No results
internal
static
let
noResults
=
L10n
.
tr
(
"Localizable"
,
"smartlist.noResults"
)
/// Search Result
...
...
@@ -358,6 +397,8 @@ internal enum L10n {
internal
static
let
searchBarPlaceholder
=
L10n
.
tr
(
"Localizable"
,
"smartlist.searchBarPlaceholder"
)
/// Searching...
internal
static
let
searching
=
L10n
.
tr
(
"Localizable"
,
"smartlist.searching"
)
/// Select one of the numbers
internal
static
let
selectOneNumber
=
L10n
.
tr
(
"Localizable"
,
"smartlist.selectOneNumber"
)
/// Yesterday
internal
static
let
yesterday
=
L10n
.
tr
(
"Localizable"
,
"smartlist.yesterday"
)
}
...
...
Ring/Ring/Contact/ContactViewModel.swift
View file @
40bf3d2c
...
...
@@ -41,26 +41,43 @@ class ContactViewModel: ViewModel, Stateable {
private
let
accountService
:
AccountsService
private
let
conversationService
:
ConversationsService
private
let
nameService
:
NameService
var
tableSection
=
Observable
<
[
SectionModel
<
String
,
ContactActions
>
]
>
.
just
([
SectionModel
(
model
:
"ProfileInfoCell"
,
items
:
[
ContactActions
(
title
:
L10n
.
ContactPage
.
startAudioCall
,
image
:
Asset
.
callButton
),
ContactActions
(
title
:
L10n
.
ContactPage
.
startVideoCall
,
image
:
Asset
.
videoRunning
),
ContactActions
(
title
:
L10n
.
ContactPage
.
sendMessage
,
image
:
Asset
.
conversationIcon
)])])
lazy
var
tableSection
:
Observable
<
[
SectionModel
<
String
,
ContactActions
>
]
>
=
{
let
jamiSettings
=
[
SectionModel
(
model
:
"ProfileInfoCell"
,
items
:
[
ContactActions
(
title
:
L10n
.
ContactPage
.
startAudioCall
,
image
:
Asset
.
callButton
),
ContactActions
(
title
:
L10n
.
ContactPage
.
startVideoCall
,
image
:
Asset
.
videoRunning
),
ContactActions
(
title
:
L10n
.
ContactPage
.
sendMessage
,
image
:
Asset
.
conversationIcon
)])]
let
sipSettings
=
[
SectionModel
(
model
:
"ProfileInfoCell"
,
items
:
[
ContactActions
(
title
:
L10n
.
ContactPage
.
startAudioCall
,
image
:
Asset
.
callButton
)])]
guard
let
account
=
self
.
accountService
.
currentAccount
,
account
.
type
==
AccountType
.
ring
else
{
return
Observable
<
[
SectionModel
<
String
,
ContactActions
>
]
>
.
just
(
sipSettings
)
}
return
Observable
<
[
SectionModel
<
String
,
ContactActions
>
]
>
.
just
(
jamiSettings
)
}()
var
conversation
:
ConversationModel
!
{
didSet
{
if
let
profile
=
conversation
.
participantProfile
,
let
alias
=
profile
.
alias
,
!
alias
.
isEmpty
{
self
.
displayName
.
value
=
alias
}
if
let
contact
=
self
.
contactService
.
contact
(
withRingId
:
conversation
.
recipientRingId
),
guard
let
account
=
self
.
accountService
.
getAccount
(
fromAccountId
:
conversation
.
accountId
)
else
{
return
}
if
let
contact
=
self
.
contactService
.
contact
(
withUri
:
conversation
.
participantUri
),
let
name
=
contact
.
userName
{
self
.
userName
.
value
=
name
}
else
{
self
.
userName
.
value
=
conversation
.
recipientRingId
self
.
userName
.
value
=
conversation
.
hash
}
if
account
.
type
==
AccountType
.
ring
{
self
.
nameService
.
usernameLookupStatus
.
filter
({
[
unowned
self
]
lookupNameResponse
in
return
lookupNameResponse
.
address
!=
nil
&&
lookupNameResponse
.
address
==
self
.
conversation
.
recipientRingId
lookupNameResponse
.
address
==
self
.
conversation
.
participantUri
})
.
subscribe
(
onNext
:
{
[
unowned
self
]
lookupNameResponse
in
if
let
name
=
lookupNameResponse
.
name
,
!
name
.
isEmpty
{
self
.
userName
.
value
=
name
...
...
@@ -68,24 +85,31 @@ class ContactViewModel: ViewModel, Stateable {
self
.
userName
.
value
=
address
}
})
.
disposed
(
by
:
disposeBag
)
self
.
nameService
.
lookupAddress
(
withAccount
:
""
,
nameserver
:
""
,
address
:
conversation
.
recipientRingId
)
self
.
nameService
.
lookupAddress
(
withAccount
:
""
,
nameserver
:
""
,
address
:
conversation
.
hash
)
}
// add option block contact and clear conversation if contact exists
if
self
.
contactService
.
contact
(
withRingId
:
conversation
.
recipientRingId
)
!=
nil
{
self
.
tableSection
=
Observable
<
[
SectionModel
<
String
,
ContactActions
>
]
>
.
just
([
SectionModel
(
model
:
"ProfileInfoCell"
,
items
:
[
ContactActions
(
title
:
L10n
.
ContactPage
.
startAudioCall
,
image
:
Asset
.
callButton
),
ContactActions
(
title
:
L10n
.
ContactPage
.
startVideoCall
,
image
:
Asset
.
videoRunning
),
ContactActions
(
title
:
L10n
.
ContactPage
.
sendMessage
,
image
:
Asset
.
conversationIcon
),
ContactActions
(
title
:
L10n
.
ContactPage
.
clearConversation
,
image
:
Asset
.
clearConversation
),
ContactActions
(
title
:
L10n
.
ContactPage
.
removeConversation
,
image
:
Asset
.
icConversationRemove
),
ContactActions
(
title
:
L10n
.
ContactPage
.
blockContact
,
image
:
Asset
.
blockIcon
)])])
if
self
.
contactService
.
contact
(
withUri
:
conversation
.
participantUri
)
!=
nil
{
if
account
.
type
==
AccountType
.
ring
{
self
.
tableSection
=
Observable
<
[
SectionModel
<
String
,
ContactActions
>
]
>
.
just
([
SectionModel
(
model
:
"ProfileInfoCell"
,
items
:
[
ContactActions
(
title
:
L10n
.
ContactPage
.
startAudioCall
,
image
:
Asset
.
callButton
),
ContactActions
(
title
:
L10n
.
ContactPage
.
startVideoCall
,
image
:
Asset
.
videoRunning
),
ContactActions
(
title
:
L10n
.
ContactPage
.
sendMessage
,
image
:
Asset
.
conversationIcon
),
ContactActions
(
title
:
L10n
.
ContactPage
.
clearConversation
,
image
:
Asset
.
clearConversation
),
ContactActions
(
title
:
L10n
.
ContactPage
.
removeConversation
,
image
:
Asset
.
icConversationRemove
),
ContactActions
(
title
:
L10n
.
ContactPage
.
blockContact
,
image
:
Asset
.
blockIcon
)])])
}
else
{
self
.
tableSection
=
Observable
<
[
SectionModel
<
String
,
ContactActions
>
]
>
.
just
([
SectionModel
(
model
:
"ProfileInfoCell"
,
items
:
[
ContactActions
(
title
:
L10n
.
ContactPage
.
startAudioCall
,
image
:
Asset
.
callButton
),
ContactActions
(
title
:
L10n
.
ContactPage
.
clearConversation
,
image
:
Asset
.
clearConversation
),
ContactActions
(
title
:
L10n
.
ContactPage
.
removeConversation
,
image
:
Asset
.
icConversationRemove
)])])
}
}
self
.
contactService
.
getContactRequestVCard
(
forContactWithRingId
:
conversation
.
recipientRingId
)
.
getContactRequestVCard
(
forContactWithRingId
:
conversation
.
participantUri
)
.
subscribe
(
onSuccess
:
{
[
unowned
self
]
vCard
in
if
!
VCardUtils
.
getName
(
from
:
vCard
)
.
isEmpty
{
self
.
displayName
.
value
=
VCardUtils
.
getName
(
from
:
vCard
)
...
...
@@ -96,7 +120,7 @@ class ContactViewModel: ViewModel, Stateable {
self
.
profileImageData
.
value
=
imageData
})
.
disposed
(
by
:
self
.
disposeBag
)
self
.
profileService
.
getProfile
(
ringId
:
conversation
.
recipientRingId
,
self
.
profileService
.
getProfile
(
uri
:
conversation
.
participantUri
,
createIfNotexists
:
false
,
accountId
:
conversation
.
accountId
)
.
subscribe
(
onNext
:
{
[
unowned
self
]
profile
in
...
...
@@ -131,38 +155,38 @@ class ContactViewModel: ViewModel, Stateable {
}
func
startCall
()
{
self
.
stateSubject
.
onNext
(
ConversationState
.
startCall
(
contactRingId
:
conversation
.
recipientRingId
,
.
startCall
(
contactRingId
:
conversation
.
participantUri
,
userName
:
self
.
userName
.
value
))
}
func
startAudioCall
()
{
self
.
stateSubject
.
onNext
(
ConversationState
.
startAudioCall
(
contactRingId
:
conversation
.
recipientRingId
,
.
startAudioCall
(
contactRingId
:
conversation
.
participantUri
,
userName
:
self
.
userName
.
value
))
}
func
deleteConversation
()
{
self
.
conversationService
.
clearHistory
(
conversation
:
conversation
,
keepConversation
:
false
)
keepConversation
:
false
)
}
func
clearConversation
()
{
self
.
conversationService
.
clearHistory
(
conversation
:
conversation
,
keepConversation
:
true
)
keepConversation
:
true
)
}
func
blockContact
()
{
let
contactRingId
=
conversation
.
recipientRingId
let
contactRingId
=
conversation
.
participantUri
let
accountId
=
conversation
.
accountId
let
removeCompleted
=
self
.
contactService
.
removeContact
(
with
RingId
:
contactRingId
,
let
removeCompleted
=
self
.
contactService
.
removeContact
(
with
Uri
:
contactRingId
,
ban
:
true
,
withAccountId
:
accountId
)
removeCompleted
.
asObservable
()
.
subscribe
(
onCompleted
:
{
[
unowned
self
]
in
self
.
conversationService
.
clearHistory
(
conversation
:
self
.
conversation
,
keepConversation
:
false
)
keepConversation
:
false
)
})
.
disposed
(
by
:
self
.
disposeBag
)
}
}
Ring/Ring/Database/DBManager.swift
View file @
40bf3d2c
...
...
@@ -247,7 +247,7 @@ class DBManager {
throw
DataAccessError
.
datastoreConnectionError
}
try
dataBase
.
transaction
{
let
author
:
String
?
=
incoming
?
self
!.
ringUri
(
from
:
contactUri
)
:
nil
let
author
:
String
?
=
incoming
?
contactUri
:
nil
guard
let
conversationID
=
try
self
?
.
getConversationsFor
(
contactUri
:
contactUri
,
createIfNotExists
:
true
,
dataBase
:
dataBase
)
else
{
...
...
@@ -308,6 +308,17 @@ class DBManager {
}
}