Compare commits

...
Sign in to create a new pull request.

546 commits

Author SHA1 Message Date
Christophe Deschamps
b5f9daba55 Tapping on message and missed call notification with app not started navigation 2024-02-13 13:25:13 +01:00
Christophe Deschamps
d70c60d5fa Handle [misc]max_calls configuration flag inside the application 2023-09-19 13:04:52 +02:00
Benoit Martins
79d5e0ab8b Fix indentation 2023-09-04 15:57:01 +02:00
Benoit Martins
c8ee392c84 Remove prints 2023-09-04 15:22:41 +02:00
Benoit Martins
691e80843d Fix phone number presence 2023-09-04 15:22:41 +02:00
QuentinArguillere
aee35b7af6 Update changelog and version for 5.1.1 2023-09-04 12:22:55 +02:00
QuentinArguillere
03da576549 Remove wrong background color for multiple accounts in the side menu 2023-09-04 12:07:05 +02:00
Christophe Deschamps
e51e26dedc Prevent phone number normalisation when dial_prefix_for_calls_and_chats is disabled on the default account 2023-09-01 15:08:12 +02:00
QuentinArguillere
b8f46f3ce5 Refactorize create_account flexiapi workflow to include the recover_account functions too 2023-09-01 14:25:40 +02:00
Christophe Deschamps
aee74e3e0a Missed call log - added Aborted and Early aborted conditions 2023-08-22 14:22:04 +00:00
QuentinArguillere
bc5e610cdb update translations from the weblate. Also added to the linphone.xcodeproj the Localisable.string files for : pl, ese, sv, pt_BR, zh-TW, zh-CN, it, uk, tr, ka, ez_AR, cs, hu 2023-08-21 14:53:13 +02:00
QuentinArguillere
f7137e7b00 Remove old use of UIColor.secondarySystemBackgroundColor that is only available on iOS 13 or higher 2023-08-21 10:39:43 +02:00
QuentinArguillere
adb013bd59 Updated changelog for 5.1.0 release 2023-08-18 16:56:56 +02:00
Christophe Deschamps
4a429c85ae Fix calls not working after core is destroyed by the app (remote prov) 2023-08-17 11:39:59 +02:00
Benoit Martins
d96408e777 Remove lime warning popup 2023-08-17 10:17:22 +02:00
Benoit Martins
575f2f13b8 Reload the entire collectionView when a presence notification is received 2023-08-16 16:41:35 +02:00
Benoit Martins
6fb558f605 Check if contact.friend is not nil in updatePresenceImage 2023-08-16 13:25:23 +02:00
Benoit Martins
6d09abd45c Fix background color of ContentMessageView when display mode (Dark and Light mode) is switched 2023-08-16 11:27:54 +02:00
Benoit Martins
4926c65079 Change color of voice recording in dark mode 2023-08-16 11:15:29 +02:00
Benoit Martins
baabde7e20 Fix pdf viewer in VFS mode 2023-08-16 10:34:26 +02:00
Benoit Martins
b320ff61fe Fix voice recording in VFS mode 2023-08-16 10:27:50 +02:00
QuentinArguillere
1a6b147df4 Add LinphoneRegistrationRefreshing status to the registration state switches to avoid crash 2023-08-10 17:33:42 +02:00
QuentinArguillere
55a3792882 Commented the part that removed the recordingView subviews, which seemed to break the voice recording UI. 2023-08-01 17:36:07 +02:00
QuentinArguillere
f272df4f88 Rename "visible" parameter to "hidden" to better match the purpose of the function 2023-08-01 17:35:23 +02:00
QuentinArguillere
206a21f5e6 Added CopyableLabel.swift file to the xcodeproj to re-enable the "long press to copy" action for sip adresses and contact names 2023-08-01 17:32:52 +02:00
QuentinArguillere
a3665c6af2 Stop the core when app is terminated to make sure the Main Core doesn't stay in Shutdown state, which would block the App Extension when receiving push notifications 2023-07-24 18:06:26 +02:00
Benoit Martins
85bb79ce87 Fix ephemeral timer in MultilineMessageCell 2023-07-21 13:44:48 +02:00
Benoit Martins
bf0ffaeb96 Fix click on secure badge 2023-07-21 11:02:57 +02:00
Benoit Martins
e00b28b862 Remove linphone_chat_message_cbs_set_participant_imdn_state_changed callback in UIChatCell 2023-07-20 14:46:30 +02:00
Benoit Martins
4ca9500d47 Fix Message View 2023-07-20 14:46:19 +02:00
Benoit Martins
ba292570d4 Fix Secure badge 2023-07-20 14:45:57 +02:00
Benoit Martins
fdc80ab7fa Fix secureBadge with safeArea
Fix presence in ContactsListTableVIew
2023-07-20 14:43:31 +02:00
Benoit Martins
8b34e48d49 Remove updateIMDNList in UIChatCell and hide drop down menu when app moved to background/foreground 2023-07-20 14:43:29 +02:00
Benoit Martins
c804be7bb8 Check if contactAddress.friend is not nil 2023-07-20 14:42:56 +02:00
Benoit Martins
c2c8e014a7 Fix Message View 2023-07-20 14:33:46 +02:00
Benoit Martins
bf539b8743 Remove linphone_chat_message_cbs_set_participant_imdn_state_changed callback in UIChatCell 2023-07-20 14:32:36 +02:00
Benoit Martins
c39aa1855f Revert "UI changes in conversation view"
This reverts commit 946b9e7a6b.
2023-07-20 10:22:23 +02:00
Benoit Martins
0e61ee7df5 Revert "Fix MessageView"
This reverts commit 197c1b3cdf.
2023-07-20 10:22:22 +02:00
Benoit Martins
0fa9673ef7 Revert "The topbar in chatConversationViewSwift remains displayed when the keyboard is open"
This reverts commit caac9c479d.
2023-07-20 10:22:21 +02:00
Benoit Martins
1cf5996886 Revert "Fix secureBadge with safeArea"
This reverts commit 28ed9b8366.
2023-07-20 10:22:19 +02:00
Benoit Martins
3a33cd63b0 Revert "Check if contactAddress.friend is not nil"
This reverts commit f457c3b6a6.
2023-07-20 10:22:16 +02:00
Benoit Martins
4d6ba1cf0f Revert "Remove updateIMDNList in UIChatCell and hide drop down menu when app moved to background/foreground"
This reverts commit 31dc0345e9.
2023-07-20 10:22:11 +02:00
Benoit Martins
31dc0345e9 Remove updateIMDNList in UIChatCell and hide drop down menu when app moved to background/foreground 2023-07-17 17:16:25 +02:00
Benoit Martins
f457c3b6a6 Check if contactAddress.friend is not nil 2023-07-17 17:16:25 +02:00
Benoit Martins
28ed9b8366 Fix secureBadge with safeArea
Fix presence in ContactsListTableVIew
2023-07-17 17:16:25 +02:00
Benoit Martins
caac9c479d The topbar in chatConversationViewSwift remains displayed when the keyboard is open 2023-07-17 17:16:25 +02:00
Benoit Martins
197c1b3cdf Fix MessageView 2023-07-17 17:16:25 +02:00
Benoit Martins
946b9e7a6b UI changes in conversation view 2023-07-17 17:16:25 +02:00
QuentinArguillere
9509f2652f Use flexiapi account creator 2023-07-11 17:04:15 +02:00
Benoit Martins
0f1ab8bf37 Remove AudioPlayer.stopSharedPlayer() in onCallClick 2023-07-03 10:47:58 +02:00
Benoit Martins
a60a49bca3 Reset AudioPlayer before starting a call 2023-07-03 10:47:58 +02:00
Benoit Martins
ee328e2c46 Set scaleAspectFit for imageViewBubble and imageVideoViewBubble in MultilineMessageCell 2023-06-29 15:07:51 +02:00
Benoit Martins
914da62b4f FIx UserNotificationCenter click
Disable Screenshot secure mode
2023-06-28 14:40:16 +02:00
Benoit Martins
c0dd1af80b Hide screenshot mode popup 2023-06-28 13:12:00 +02:00
Benoit Martins
930baed6d0 Fix floating scroll button 2023-06-28 13:10:29 +02:00
Benoit Martins
dd023b5b9d Remove prints 2023-06-28 13:10:29 +02:00
Benoit Martins
2bfdf89642 Remove CGRectMake 2023-06-28 13:10:29 +02:00
Benoit Martins
9bdd7f65fe Fix TextViewer and add popup for other file types 2023-06-28 13:10:29 +02:00
Benoit Martins
54e772a47f Fix pdf viewer and plain text file 2023-06-28 13:10:29 +02:00
Benoit Martins
6a8a35bad6 Add pdf viewer 2023-06-28 13:10:29 +02:00
Benoit Martins
cdca235f39 Fix fullscreen video player 2023-06-28 13:10:29 +02:00
Benoit Martins
edb9635986 Fix Avplayer with audio 2023-06-28 13:10:29 +02:00
Benoit Martins
3eb82120e4 Add audio with AVPlayer 2023-06-28 13:10:29 +02:00
Benoit Martins
0724d66e7d Add AVPlayer 2023-06-28 13:10:29 +02:00
Benoit Martins
3c1a905e46 Finish ImageViewer 2023-06-28 13:10:29 +02:00
Benoit Martins
4f7f713fd6 Add ImageViewer 2023-06-28 13:10:29 +02:00
Benoit Martins
3dc945dccf Remove deprecated keyWindow 2023-06-23 09:55:08 +02:00
Benoit Martins
41eb23e825 Fix screenshot secure mode 2023-06-23 09:45:20 +02:00
Benoit Martins
7ec518a114 Fix screenshot secure mode
Check if linphone_friend_get_address is not nil in ChatConversationCreateTableView
2023-06-23 09:45:20 +02:00
Benoit Martins
f1b69a388d Fix VoipExtraButtonsView when call is paused 2023-06-23 09:40:45 +02:00
Benoit Martins
5ae1293d09 Fix ChatConversationInfoView for deleting participants and changing admins 2023-06-23 09:14:42 +02:00
Christophe Deschamps
ea976712d1 Do not change the DropDown style generically to avoid conflict with drop down in chat 2023-06-21 08:53:45 +02:00
Christophe Deschamps
c368b247e7 Updated the StreamCapability/StreamAvailability detection of participant device in conference (modelled from Anroid) 2023-06-20 18:40:00 +02:00
Benoit Martins
eb5305107e Disable screenshot secure mode 2023-06-19 16:27:19 +02:00
Benoit Martins
22a248e03a Fix crash when app moved to background 2023-06-19 10:52:11 +02:00
benoit.martins
5fe7f44e10 Add missing translation 2023-06-16 15:09:44 +02:00
Benoit Martins
47eee70b66 Fix message bubble click 2023-06-16 14:29:58 +02:00
Benoit Martins
d439520e1f Fix Index out of range for imagesGridCollectionView 2023-06-16 14:29:58 +02:00
Benoit Martins
44df35297c Change icon image in pictureButton 2023-06-16 14:29:58 +02:00
benoit.martins
d2900419ba Remove ControlsViewModel subclassing 2023-06-16 14:29:58 +02:00
benoit.martins
3c9582b1c6 Remove print in BackActionsNavigationView 2023-06-16 14:29:58 +02:00
benoit.martins
db5a6b685a Increase width of messageTextView in MessageView 2023-06-16 14:29:58 +02:00
benoit.martins
70d92254f8 Hide emojisButton and increase width of messageText when user is writing in MessageView 2023-06-16 14:29:58 +02:00
Benoit Martins
3d99102426 Fix Crashlytics bugs 2023-06-16 14:29:58 +02:00
Benoit Martins
989471fca2 Fix addDelegate crash in Avatar class (Check if presenceModel is not nil) 2023-06-16 14:24:02 +02:00
Benoit Martins
2e0fd1f898 Disable screenshot in secure room 2023-06-16 14:03:48 +02:00
Benoit Martins
2b06b47d99 Change chat bubble color 2023-06-15 13:48:03 +02:00
benoit.martins
535267aa6e Fix long messages in ChatConversationImdnView 2023-06-13 10:09:41 +02:00
Benoit Martins
6cfca71db3 Change bubble_chat_dropDown_infos to "Delivery Status" 2023-06-13 10:09:41 +02:00
Benoit Martins
989257f802 Fix refresh messages received when application switches to background/foreground
Fix reloadItem when receive presence notification
2023-06-13 10:09:41 +02:00
Benoit Martins
e70190dc2c Remove Ipad condition in ChatListView and ChatListTableView
Fix contact authorization status popup
2023-06-13 10:09:41 +02:00
benoit.martins
9a97af80e5 Add Copyright Belledonne Communications text in files 2023-06-13 10:09:41 +02:00
Benoit Martins
ffc5b2cb22 Fix emoji.png 2023-06-13 10:09:41 +02:00
Benoit Martins
00c5b44d44 Fix 2023-06-13 10:09:41 +02:00
Benoit Martins
b9ebd3300c Change Emoji Picker lib 2023-06-13 10:09:41 +02:00
Benoit Martins
8555affdec Change project.pbxproj 2023-06-13 10:09:41 +02:00
Benoit Martins
31b11e5317 Change IPHONEOS_DEPLOYMENT_TARGET to 11.2 in Podfile 2023-06-13 10:09:41 +02:00
Benoit Martins
c711911184 Add emoji button and change emoji picket lib (Now use MCEmojiPicker) 2023-06-13 10:09:41 +02:00
Benoit Martins
68a908d19a Add EmojisPicker lib 2023-06-13 10:09:41 +02:00
benoit.martins
b7d645bb74 Add emojis picker 2023-06-13 10:09:41 +02:00
Benoit Martins
c41ef3323d Fix some crashes reported by crashlytics (InitDataSource and refreshData) 2023-06-13 10:09:41 +02:00
Benoit Martins
f4e4f79bb7 Fix sendButton state in ChatConversationViewSwift
Fix voice recording bubble
2023-06-13 10:09:41 +02:00
Benoit Martins
9a1273a02b Change keyboardDismissMode to interactive 2023-06-13 10:09:41 +02:00
Benoit Martins
9a01f1d663 Remove project.pbxproj changes 2023-06-13 10:09:41 +02:00
Benoit Martins
14e6f382b8 Fix voice recording message
Fix collectionViewMedia in ChatConversationViewSwift
2023-06-13 10:09:41 +02:00
benoit.martins
25813dc15f Fix crash when receive message with multiple media
Fix presence latestActivityTimestamp
2023-06-13 10:09:41 +02:00
benoit.martins
962ab4c267 Rebase 2023-06-13 10:09:41 +02:00
Benoit Martins
1baa68f240 Remove reloadData when ChatConversationTableViewSwift view did appear 2023-06-13 10:09:41 +02:00
Benoit Martins
9a2885ed78 Fix avatar image in MultilineMessageCell (Use always default avatar when address not in contact list) 2023-06-13 10:09:41 +02:00
Benoit Martins
88e497a783 Remove print in Avatar Class 2023-06-13 10:09:41 +02:00
Benoit Martins
139ac987d8 Fix minor problems with presence 2023-06-13 10:09:41 +02:00
benoit.martins
5f297b5dec Add RemoveAllDelegate in AvatarBridge 2023-06-13 10:09:41 +02:00
benoit.martins
4ec3d89d42 Add presence delegate in ChatConversationViewSwift
Fix presence delegate not removed from Avatar class
2023-06-13 10:09:41 +02:00
benoit.martins
cb9707a231 Displaying presence in BackActionNavigationView 2023-06-13 10:09:41 +02:00
Benoit Martins
b045117ed7 Add LinphoneFriendPresenceUpdate observer in ChatConversationTableViewSwift
Remove LinphoneFriendPresenceUpdate observer of NotificationCenter when view disappear
2023-06-13 10:09:41 +02:00
Benoit Martins
ac9f26b5aa Add user avatar presence in chat room swift 2023-06-13 10:09:41 +02:00
Benoit Martins
78d7f0029a Change in ChatConversationView.xib and project file 2023-06-13 10:09:41 +02:00
Benoit Martins
af93f13ea7 Change Project file 2023-06-13 10:09:41 +02:00
Benoit Martins
57f374d440 Refresh item of collectionView when download is finished 2023-06-13 10:09:41 +02:00
benoit.martins
b3d07835ee Add Download Media UI in Bubble Chat Message 2023-06-13 10:09:41 +02:00
Benoit Martins
d4b9f4b976 New UI for messageBubble (Swift) 2023-06-13 10:09:41 +02:00
Benoit Martins
dfa697e0d7 Add all ChatConversation callbacks (delegates) 2023-06-13 10:09:41 +02:00
Benoit Martins
b57ae83662 Add CustomAlertController and functions called in alertController (Start group call and go to Device list view) 2023-06-13 10:09:41 +02:00
Benoit Martins
06cf997eb5 Add DropDown menu 2023-06-13 10:09:41 +02:00
Benoit Martins
9c268b9ae4 Add Secure Badge and participants authentication Custom PopUp 2023-06-13 10:09:41 +02:00
Benoit Martins
312e6a359d First View of ChatConversationSwift 2023-06-13 10:09:41 +02:00
Benoit Martins
c0acf23d00 Add ChatConversationViewModel 2023-06-13 10:09:41 +02:00
Benoit Martins
847bda153d Rebase Release 5.1 2023-06-13 10:09:41 +02:00
Benoit Martins
2a4db9759d Rebase 2023-06-13 10:09:41 +02:00
Benoit Martins
ac376631d1 Remove print in file_transfer_progress_indication_recv 2023-06-13 10:09:41 +02:00
Benoit Martins
053b39083c Add default image when filepath is empty
Remove FileTransfer Callbacks when leave chatroom
Fix editMode
2023-06-13 10:09:40 +02:00
Benoit Martins
26b51208ba Fix upload and download media loader 2023-06-13 10:09:40 +02:00
Benoit Martins
cdf517b7a9 Fix upload and download media loader 2023-06-13 10:09:40 +02:00
Benoit Martins
392d218c4f Check if url can be created in createThumbnailOfVideoFromFileURL (MultilineMessageCell and ChatConversationViewModel) 2023-06-13 10:09:40 +02:00
Benoit Martins
ae974b933c Check of previousEvent is nil in isFirstIndexInTableView 2023-06-13 10:09:40 +02:00
Benoit Martins
e0e41c63e5 Fix file_transfer_progress_indication_recv when indexTransferProgress is equal to -1 2023-06-13 10:09:40 +02:00
benoit.martins
999d989951 Fix media sent from galery 2023-06-13 10:09:40 +02:00
Benoit Martins
1cb2a47e9b Fix unlimited cell creation in ChatConversationViewSwift
Fix reloadData when orientation is changed
2023-06-13 10:09:40 +02:00
Benoit Martins
37981ca4c9 Add Github/License for SwipeCellKit in Podfile 2023-06-13 10:09:40 +02:00
Benoit Martins
c7008e37bd Add SwipeCellKit gitlab repository in Podfile 2023-06-13 10:09:40 +02:00
benoit.martins
472380749c Hide keyboard when scroll CollectionView (ChatConversationTableView) 2023-06-13 10:09:40 +02:00
benoit.martins
a6c06975ec Scroll to the selected media after displaying it 2023-06-13 10:09:40 +02:00
benoit.martins
1a26b1d6cb Replace UICollectionLayoutListConfiguration instead SwipeCollectionView to swipe items from the collectionview 2023-06-13 10:09:40 +02:00
Benoit Martins
2ebf4e03fa Fix deleteItemCheckBox and fix collectionViewImagesGrid.insertItems for one item (MultilineMessageCell) 2023-06-13 10:09:40 +02:00
Benoit Martins
a9d18f2495 Remove reply action for event message 2023-06-13 10:09:40 +02:00
Benoit Martins
332358d322 Add actions when click on swipeActions 2023-06-13 10:09:40 +02:00
benoit.martins
768f505559 Add leading and trailing SwipeActions for bubbles 2023-06-13 10:09:40 +02:00
Benoit Martins
afeef1d93c Open and close keyboard when user interacts with bubbles 2023-06-13 10:09:40 +02:00
Benoit Martins
5054fa8d71 Change UIAlertDialog of Photo permission in ChatConversationViewModel 2023-06-13 10:09:40 +02:00
Benoit Martins
cd9778b3a1 Remove all prints (replaced by Logs) 2023-06-13 10:09:40 +02:00
Benoit Martins
01fe584083 Disable NotificationService when receive message in active chatroom 2023-06-13 10:09:40 +02:00
benoit.martins
96fa6df872 Read_only_native_address_book condition for ChatConversationSwift (Config RC) 2023-06-13 10:09:40 +02:00
Benoit Martins
d41f2c21e3 Add audio_video_conference_factory_address condition to display voip conference buttons in ChatRoomConverstaionSwift 2023-06-13 10:09:40 +02:00
Benoit Martins
2276565c1c Add email, phone number and url link in MultilineMessageCell 2023-06-13 10:09:40 +02:00
Benoit Martins
2c87421757 Fix refreshData when chat room has no message 2023-06-13 10:09:40 +02:00
benoit.martins
8b69f58442 Remove collectionView.performBatchUpdates for Xcode 14.3 2023-06-13 10:09:40 +02:00
buildbot
f9cbfa1731 (commit by Quentin) fix xcode 13 build 2023-06-13 10:09:40 +02:00
Benoit Martins
7f1720ea89 Change in ChatConversationView.xib and project file 2023-06-13 10:09:40 +02:00
benoit.martins
67554b43f4 Increase size of bubble text when it's only composed of emojis 2023-06-13 10:09:40 +02:00
benoit.martins
c619d61d8c Fix GridCollectionView with text 2023-06-13 10:09:40 +02:00
Benoit Martins
448a567bfe Fix CollectionView when receive new message (IndexPath Reversed) 2023-06-13 10:09:40 +02:00
Benoit Martins
216fdd3bd5 Fix collectionView 2023-06-13 10:09:40 +02:00
Benoit Martins
9d9b54ded3 Change when receive isComposing event
Fix minor bugs
2023-06-13 10:09:40 +02:00
Benoit Martins
43375e2ab1 Fix UICollectionView when receive a new message 2023-06-13 10:09:40 +02:00
Benoit Martins
6a500e19fa Fix loader when sending media 2023-06-13 10:09:40 +02:00
Benoit Martins
0e3dbc4125 Fix VFS media (delete file after exportPlainFile) 2023-06-13 10:09:40 +02:00
Benoit Martins
c8e7e4591a Can delete multiple messages on Edit mode 2023-06-13 10:09:40 +02:00
Benoit Martins
1fd242122f Add checkbox for delete messages 2023-06-13 10:09:40 +02:00
Benoit Martins
9bc1d5018e Fix scrollToItem after QLPreview
Add editMode on ChatConversationTableViewSwift
2023-06-13 10:09:40 +02:00
Benoit Martins
346e84615f Fix QLPreviewController 2023-06-13 10:09:40 +02:00
Benoit Martins
e7f9c24309 Add QLPreviewController for displaying media in native viewer
Fix some problems with images in bubbleChat
2023-06-13 10:09:40 +02:00
benoit.martins
65a908d37a Fix not UTF8 URL in message with one media 2023-06-13 10:09:40 +02:00
Benoit Martins
61a7b7a562 Add image player when click on bubble view 2023-06-13 10:09:40 +02:00
Benoit Martins
7bec5efb9a Fix Ephemeral timer 2023-06-13 10:09:40 +02:00
Benoit Martins
9e630d7366 Add Ephemeral Timer for messages 2023-06-13 10:09:40 +02:00
Benoit Martins
ad7859d048 Add Avatar Image and Date Label for messages 2023-06-13 10:09:40 +02:00
Benoit Martins
15a7a3b298 Add loader when upload files 2023-06-13 10:09:40 +02:00
benoit.martins
6275697028 Mark as read when detect the bottom of collectionView
Change IMDN icon with ChatMessageState Callback
2023-06-13 10:09:40 +02:00
benoit.martins
94721fad50 Change DownloadMessageCell image based on file type
Refresh collectionViewImagesGrid item when downloaded is complete
2023-06-13 10:09:40 +02:00
benoit.martins
d739052d1a Reload CollectionView (messages) when a single item has been downloaded 2023-06-13 10:09:40 +02:00
Benoit Martins
d1ae0af1f3 Fix collectionViewImagesGrid in MultilineMessageCell 2023-06-13 10:09:40 +02:00
Benoit Martins
8aedb3e621 Remove ChatConversationTableView (Objective C) of ChatConversationViewSwift
Add FloatingScrollButton in ChatConversationTableViewSwift
Add file_transfer_progress_indication callback
2023-06-13 10:09:40 +02:00
Benoit Martins
b079d12f0a Reload collectionView when new message is received 2023-06-13 10:09:40 +02:00
Benoit Martins
e4eff6aba9 Change Progress bar to CircularProgressBar (Like Android) in Download Bubble Chat Message 2023-06-13 10:09:40 +02:00
Benoit Martins
fc4d7659bb Refresh item of collectionView when download is finished 2023-06-13 10:09:40 +02:00
benoit.martins
bc35ce7cfc Add download feature for Bubble Chat Message 2023-06-13 10:09:40 +02:00
benoit.martins
bce0191d66 Add Download Media UI in Bubble Chat Message 2023-06-13 10:09:40 +02:00
Benoit Martins
7a1e566d52 Display multiple images in Bubble Chat Message 2023-06-13 10:09:40 +02:00
Benoit Martins
2560571608 Fix Bubble Chat Message with Media and Text 2023-06-13 10:09:40 +02:00
Benoit Martins
c0ffa210ec Add safe area constraints of BackActionNavigationVIew 2023-06-13 10:09:39 +02:00
Benoit Martins
12560d7910 Add Event Message (like "You have left the group", ...) in collectionView 2023-06-13 10:09:39 +02:00
Benoit Martins
d41767187e Add InfoMessage and DeleteMessage to DropDownMenu of CollectionView 2023-06-13 10:09:39 +02:00
benoit.martins
017f316ff1 Add DropDownMenu to CollectionView cells 2023-06-13 10:09:39 +02:00
Benoit Martins
1e6b52adb2 Add long click to bubble chat message 2023-06-13 10:09:39 +02:00
benoit.martins
1730a50a56 Fix Scrolling Reply Bubble Chat 2023-06-13 10:09:39 +02:00
Benoit Martins
5e6e302fd1 Fix Reply Bubble Chat (UI and add click) 2023-06-13 10:09:39 +02:00
Benoit Martins
63d05e5fe5 Add Meeting Bubble Chat 2023-06-13 10:09:39 +02:00
Benoit Martins
ea663e93ab Add Reply Bubble Chat 2023-06-13 10:09:39 +02:00
Benoit Martins
f9698d33a6 Add Transfer Bubble Chat 2023-06-13 10:09:39 +02:00
Benoit Martins
2a4a0dbdfd Fix Audio Player (Duplicate Audio Cell) 2023-06-13 10:09:39 +02:00
Benoit Martins
46b62bf4a3 Fix audio player 2023-06-13 10:09:39 +02:00
Benoit Martins
2dd4750ba1 Fix cell generation of UICollectionView 2023-06-13 10:09:39 +02:00
Benoit Martins
70671d973d Fix images in UICollectionView bug (add prepareForReuse in MultilineMessageCell for refresh cells) 2023-06-13 10:09:39 +02:00
Benoit Martins
52b14654c9 BubbleChat UI updates for image, video and audio messages 2023-06-13 10:09:39 +02:00
Benoit Martins
f4a3261866 BubbleChat UI updates 2023-06-13 10:09:39 +02:00
Benoit Martins
4ef451de2a New UI for messageBubble (Swift) 2023-06-13 10:09:39 +02:00
Benoit Martins
b4b51c8e77 Fix voiceRecorder message with text 2023-06-13 10:09:39 +02:00
Benoit Martins
efb9cbd282 Fix markAsRead and ChatConversationViewModel updates 2023-06-13 10:09:39 +02:00
Benoit Martins
1a1bd86588 Fin Delete color button (reply and mediaSelector) 2023-06-13 10:09:39 +02:00
Benoit Martins
04086fb5f2 Fix light and dark mode 2023-06-13 10:09:39 +02:00
Benoit Martins
54bfcb22e0 Add all ChatConversation callbacks (delegates) 2023-06-13 10:09:39 +02:00
Benoit Martins
8a4f1046c6 Add isReadOnly check to hide views (messageView, callButton, ...) 2023-06-13 10:09:39 +02:00
Benoit Martins
f373067247 Move floatingScrollButton behind to sideMenu 2023-06-13 10:09:39 +02:00
Benoit Martins
9d5873095f Voice recording finished 2023-06-13 10:09:39 +02:00
Benoit Martins
b6e613221e Add progress bar during voice recording 2023-06-13 10:09:39 +02:00
Benoit Martins
af9339fe23 Add voiceRecorder 2023-06-13 10:09:39 +02:00
Benoit Martins
7368d07440 FloatingScrollDownButton UI update (aligned with Android) 2023-06-13 10:09:39 +02:00
Benoit Martins
f8d93b8070 Fix isComposingView animation 2023-06-13 10:09:39 +02:00
Benoit Martins
e2233674ae Add Sharing Media feature 2023-06-13 10:09:39 +02:00
Benoit Martins
989ae6db8f Add recording duration of audio files 2023-06-13 10:09:39 +02:00
Benoit Martins
699d8e7027 Add scrollable mediaList to reply block 2023-06-13 10:09:39 +02:00
Benoit Martins
9930b7d85d Dynamic size of reply block 2023-06-13 10:09:39 +02:00
Benoit Martins
6a42b749c2 Add title label (ChatMessage address) and message content in reply block 2023-06-13 10:09:39 +02:00
Benoit Martins
7a10c045c1 Fix isComposingView block 2023-06-13 10:09:39 +02:00
Benoit Martins
92f9982cd0 Add reply block (not finished) and changes animated views 2023-06-13 10:09:39 +02:00
Benoit Martins
4db1c328d9 Add Transfer Feature 2023-06-13 10:09:39 +02:00
Benoit Martins
0ed5d8e371 Add Transfer Feature Test 2023-06-13 10:09:39 +02:00
Benoit Martins
e7ebd60998 Disable MediaButton and SendButton when medias are loading 2023-06-13 10:09:39 +02:00
Benoit Martins
bbe5bcdee7 Add LoadFile progress for Image, Camera, Media and Document Picker 2023-06-13 10:09:39 +02:00
Benoit Martins
9b3ae7f004 Add text with loading spinner, and reduce function to get media data 2023-06-13 10:09:39 +02:00
Benoit Martins
8df45e8a96 Add DispatchWorkItem to cancel running threads (DispatchQueue) 2023-06-13 10:09:39 +02:00
Benoit Martins
1c8b755ce0 Add loading spinner for to wait for media data 2023-06-13 10:09:39 +02:00
Benoit Martins
caf9a510e0 Add Upload media (Photos, Videos, Files) feature 2023-06-13 10:09:39 +02:00
Benoit Martins
e813651818 Finished mediaList preview for Image, Video and other file types (pdf, wav, m4a, ...) 2023-06-13 10:09:39 +02:00
Benoit Martins
a271dfd465 Add preview for document picker files, photos and videos taking with camera 2023-06-13 10:09:39 +02:00
Benoit Martins
889a1fc125 Add play image if preview is video in list Media chatConversationview 2023-06-13 10:09:39 +02:00
Benoit Martins
6f8970c2f2 Add list of media (Photo) in chatConversationViewSwift for sending media 2023-06-13 10:09:39 +02:00
Benoit Martins
7725dd2307 add ephemeral indicator in messageview 2023-06-13 10:09:38 +02:00
Benoit Martins
6e6ed5bb98 Minor changes 2023-06-13 10:09:38 +02:00
Benoit Martins
9219946024 Write media to iOS gallery (Download) feature 2023-06-13 10:09:38 +02:00
Benoit Martins
e44f118347 isComposing feature (send and receive) 2023-06-13 10:09:38 +02:00
Benoit Martins
4f3e5ed3e5 Add chatRoomDelegate, now we can receive image, video, text and voice recording messages instantly 2023-06-13 10:09:38 +02:00
Benoit Martins
4ece0f396f Add participants list in chat conversation view in title group.
Add Send message feature 2023-06-13 10:09:38 +02:00
Benoit Martins
3977c0ebd3 Select or deselect all messages in chat conversation view swift.
Add delete feature. 2023-06-13 10:09:38 +02:00
Benoit Martins
bac7bb95f2 Add ChatConversationTableView in ChatConversationViewSwift (Message, BubbleChat, ...) 2023-06-13 10:09:38 +02:00
Benoit Martins
ac5160c1c1 Add all actions for dropdown menu in chat conversation.
Now long press for open debug info (like android)
2023-06-13 10:09:38 +02:00
Benoit Martins
c1ef2f558a Minor changes 2023-06-13 10:09:38 +02:00
Benoit Martins
4e96033d04 Minor changes + add no ask again switch in Devices List alertController 2023-06-13 10:09:38 +02:00
Benoit Martins
f3532e7124 Delete UIAlertController Extension 2023-06-13 10:09:38 +02:00
Benoit Martins
c96b7d6002 Add CustomAlertController and functions called in alertController (Start group call and go to Device list view) 2023-06-13 10:09:38 +02:00
Benoit Martins
fe3bf1035f Add item to dropdown menu with images 2023-06-13 10:09:38 +02:00
Benoit Martins
a6a811b059 Add DropDown menu 2023-06-13 10:09:38 +02:00
Benoit Martins
0ee5e37374 Add Secure Badge and participants authentication Custom PopUp 2023-06-13 10:09:38 +02:00
Benoit Martins
47ca331e96 Add message file picker UI (Camera, Gallery, Documents) 2023-06-13 10:09:38 +02:00
Benoit Martins
cd5e186e26 First View of ChatConversationSwift 2023-06-13 10:09:38 +02:00
Benoit Martins
7af4ac2633 Add ChatConversationViewModel 2023-06-13 10:09:38 +02:00
Benoit Martins
66b1a5a85f Rebase Release 5.1 2023-06-13 10:09:38 +02:00
QuentinArguillere
8d12a8af89 Stop forcing "transient_provisioning" to 1 when fetching a remote configuration in the assistant 2023-06-08 16:24:38 +02:00
QuentinArguillere
77edc0972e Revert expire duration back to 1 year for now 2023-06-02 10:34:31 +02:00
benoit.martins
fd58ddf276 Fix lpConfigBoolForKey:@"account_push_presence_preference" 2023-05-25 11:54:35 +02:00
Benoit Martins
dbc93b7cf0 Move push_presence_preference to Contacts settings 2023-05-25 11:54:35 +02:00
Benoit Martins
0357a601d6 Change if condition (for changeView) in ContactsListView 2023-05-25 11:49:23 +02:00
Benoit Martins
e8594c397c Fix only_show_sip_contacts_list and hide_sip_contacts_list config (RC) 2023-05-25 11:29:05 +02:00
Benoit Martins
30dd6926e3 Remove auto enable_rtp_bundle when app is launched 2023-05-16 14:44:00 +02:00
benoit.martins
2dac2cef6b Add bundle_mode_preference toggle in account settings 2023-05-16 14:43:54 +02:00
Benoit Martins
5523ddf0f1 Read_only_native_address_book condition (Config RC) 2023-05-16 13:53:07 +02:00
Benoit Martins
9eb2e5609e Disable video feature in config RC 2023-05-16 13:53:07 +02:00
Benoit Martins
75f841acc1 Add audio_video_conference_factory_address condition to display voip conference button 2023-05-16 13:53:07 +02:00
Benoit Martins
63fa4f10dd Add disable_chat_feature in configRC 2023-05-16 13:53:07 +02:00
benoit.martins
30a916b514 Change UIAlertController condiiton to display Debug popup in DialerView 2023-05-16 13:36:11 +02:00
Benoit Martins
4153f04e62 Change text to display (linphone_config_dump instead of linphoneRC file) 2023-05-16 13:36:11 +02:00
Benoit Martins
90c26b3f8c Add Debug Popup Code for displaying and sharing LinphoneRC file (#1234# in Dialer) 2023-05-16 13:35:32 +02:00
Benoit Martins
bff4491da7 Fix publish presence setting
Add log_collection_upload_server_url and update_presence_model_timestamp_before_publish_expires_refresh in LinphoneRC
Add publish and pusblish_expires in assistant_linphone.rc (create and existing)
2023-05-16 12:11:21 +02:00
benoit.martins
919cca1726 Fix phone (no sip) presence
Add pushpresence setting
2023-05-16 12:11:21 +02:00
Benoit Martins
cd553df74e Add presence delegate for all views 2023-05-16 12:11:21 +02:00
Benoit Martins
15481cf227 Add delegate presence (callback)
Set Consolidated presence of core when app enter in background or foreground
2023-05-16 12:11:21 +02:00
benoit.martins
595ce13409 fix 2023-05-16 12:11:21 +02:00
benoit.martins
e5e49530dd Change presence value in AvatarBridge with PresenceModel.consolidatedPresence 2023-05-16 12:11:21 +02:00
benoit.martins
26fcac9bef Change Avatar Image on all views 2023-05-16 12:11:21 +02:00
benoit.martins
e984af2418 Change imageForAddress and imageForContact in FastAddressBook 2023-05-16 12:11:21 +02:00
benoit.martins
b927680689 Add led presence in Avatar view 2023-05-16 12:11:21 +02:00
benoit.martins
46af917c6e Add IMDN callback and refresh IMDN icon in UIChatCell 2023-05-16 12:11:21 +02:00
benoit.martins
b6686dd2da Display IMDN in UIChatCell (ChatsListTableView) 2023-05-16 12:11:21 +02:00
benoit.martins
743f23a2bc Re-indent with Xcode 2023-05-05 13:44:38 +02:00
Benoit Martins
9f234fc63d Change display name of Callkit when received attended transfer call 2023-05-02 09:53:35 +02:00
Benoit Martins
9d031dbc47 Remove useless prints 2023-05-02 09:20:20 +02:00
Benoit Martins
b3aa1538ae Fix CallKit for Attended Transfer 2023-04-27 17:20:37 +02:00
Benoit Martins
a0ccbdf27e Add attended transfer call in VoipExtraButtonsView 2023-04-26 16:09:18 +02:00
QuentinArguillere
1f2828814d Revert changes to pbxproj from previous commit 2023-04-25 13:29:33 +02:00
QuentinArguillere
a38d80d7d5 Check value of “auto_apply_provisionning_config_uri_handler” : if true, automatically apply a remote configuration opened from a URL scheme. Otherwise, display the usual confirmation dialog 2023-04-25 10:06:07 +02:00
QuentinArguillere
39be810ecb Fix url scheme handler for app : now can properly do a remote configuration when opening a linphone-config:URL from another app 2023-04-24 14:37:36 +02:00
Benoit Martins
bfe70ee790 Add missing translation files 2023-04-21 11:32:27 +02:00
QuentinArguillere
952e01b421 Light refactoring of linphone specific settings for accounts 2023-04-20 14:33:02 +02:00
QuentinArguillere
7864e48a45 Add Organization label to contacts 2023-04-18 11:36:16 +02:00
QuentinArguillere
2936ac9801 Update iOS deployment target to 11.0 to fix Xcode 14.3 build error 2023-04-07 12:15:23 +02:00
QuentinArguillere
0298f986ca Update sip “expires” of existing accounts to be 1 month (2629800 seconds) 2023-04-07 12:12:52 +02:00
QuentinArguillere
61047e3ea0 Make addresses and contact names copyable with a long-press in history details view and contact details view 2023-04-06 11:00:03 +02:00
QuentinArguillere
75c676ddb0 Implement didReceivedRemoteNotification to manage background push in order to trigger a register for accounts when receiving a service notification 2023-03-27 16:42:26 +02:00
QuentinArguillere
5edea95381 Implement didReceivedRemoteNotification to manage background push in order to trigger a register for accounts when receiving a service notification 2023-03-17 17:43:16 +01:00
QuentinArguillere
ca141f40c3 Update version to 5.1.0 2023-03-17 17:39:19 +01:00
QuentinArguillere
8f4a80500e Update changelog and podfile for 5.0.2 release 2023-03-16 11:19:36 +01:00
Christophe Deschamps
0913df3ac8 Hide non secure contacts when creating chatroom and lime is forced 2023-03-14 12:21:06 +01:00
Benoit Martins
b82f8bb84e Fix video player in RecordingsList 2023-03-14 11:59:18 +01:00
QuentinArguillere
470ec60d99 When deleting account, replace previous system alert pop up with a custom confirmation dialog that includes (if the account was a linphone account) a link to susbscribe.linphone.org for permanent deletion 2023-03-13 17:15:12 +01:00
Christophe Deschamps
211714167a Hide in call - more button - (3 dosts) when call stats or numpad is displayed 2023-03-09 11:51:18 +01:00
QuentinArguillere
590ebdbd66 Fix crash when creating a chatroom. Crash was caused by a weak reference on a search result in the magic search singleton. 2023-03-06 11:12:55 +01:00
Simon Morlat
a1dfc7c6c3 Remove msx264 references (no longer maintained). 2023-03-03 09:40:14 +01:00
Simon Morlat
8315ac543e Fix memory leaks. 2023-02-13 12:00:08 +01:00
Christophe Deschamps
bac9d2b98e Avatar icon when creating a contact (and more generally with empty display name) 2023-02-07 12:31:10 +01:00
QuentinArguillere
8cbeac0e54 Fix bad “Codecs” translation for English version that would end up written in arabic 2023-02-02 09:23:56 +01:00
QuentinArguillere
45c596dcec Update changeling, pod file and xcodeproj for 5.0.1 2023-02-02 09:23:27 +01:00
Christophe Deschamps
eca3dbe9d9 When pressing camera in audio only mode conference, enable video in SendReceive or ReceiveOnly mode in accordance with video activation policy of core 2023-01-31 17:08:35 +01:00
Benoit Martins
79cb76ac75 Add margin for chat bubble text in chat conversation view 2023-01-17 10:29:24 +01:00
Christophe Deschamps
d34ba5df7c Fix participant video display when second participant joins with video activated 2023-01-12 15:54:16 +01:00
Christophe Deschamps
8d873e496d Fix second particpant joining 2023-01-12 15:54:16 +01:00
Simon Morlat
aefe5e1ad0 Fix an issue where Callkit was accidentally requesting termination of a call while resuming another one. 2023-01-11 15:08:51 +01:00
Christophe Deschamps
5fe2af9d50 Hide active speaker miniature 2023-01-10 10:57:30 +00:00
Benoit Martins
fd627b4c4a Align encryptedButton with messages in chatConverstaionView 2023-01-10 10:03:00 +01:00
Benoit Martins
4c93d335ff Acquire a new reference to the chat message if old reference is nil 2023-01-09 10:38:35 +01:00
Benoit Martins
c47a50f5d1 Check if VFS mode is desactivated before writing media to gallery 2023-01-09 10:38:35 +01:00
Benoit Martins
ac4397cbbe Remove constraints auto download and write to gallery in setting view 2023-01-09 10:38:35 +01:00
QuentinArguillere
64c0e84cfa Set lime server URL for linphone accounts 2023-01-03 15:14:13 +01:00
QuentinArguillere
29bcbf64c0 Remove mistaken line from changeling 2022-12-06 17:43:49 +01:00
QuentinArguillere
b99327dbe5 Update Changelog and Podfile for 5.0.0 release 2022-12-06 14:28:22 +01:00
Benoit Martins
952b27c94f Minor changes of VFS_enabled_mode 2022-12-06 12:04:20 +01:00
Benoit Martins
5407a18b57 Save VFS and Auto_download_mode changes 2022-12-06 12:04:20 +01:00
Benoit Martins
9e52922fff In chat setting, when user enable VFS or set auto_download_mode on Never, disable auto_write_to_gallery_mode item.
When enable auto_write_to_gallery_mode, app disable VFS and auto_download_mode items.
2022-12-06 12:04:20 +01:00
Christophe Deschamps
4ade9f2c60 Automatically initiate video call (if remote party is in auti accept mode) 2022-12-06 11:40:54 +01:00
QuentinArguillere
abf598b654 Use linphone_core_search_chat_room rather than linphone_core_get_chat_room, in order to fix chatrooms being empty when using multiple accounts 2022-12-05 16:40:31 +01:00
Christophe Deschamps
0a05baea1e Fix pause screen not showing in some situation in Paused conferences 2022-12-05 10:33:34 +01:00
QuentinArguillere
4cd9da44de Add security to participant_imdn_status callback to avoid potential crash 2022-12-05 10:08:00 +01:00
Christophe Deschamps
a341bb6aec - Allow date picker to select today's date in the first place
- supports pre-ios14 device for date/time picking
2022-12-05 09:32:17 +01:00
Christophe Deschamps
ff5bafb7c0 When adding calls to a conference - enter the conference again if it was paused 2022-12-04 18:38:59 +01:00
Christophe Deschamps
9ba95b024c Disable call merge into conference if not admin of conference 2022-12-04 18:20:36 +01:00
Christophe Deschamps
05b905a3f1 Hide audio route selection view when clicked outsize 2022-12-02 17:09:11 +01:00
Christophe Deschamps
e8c2e92fc9 Added call back when bluetooth device is added or removed 2022-12-02 16:50:23 +01:00
Christophe Deschamps
82289f4523 Fix user interaction on send via chat switch on conference scheduling 2022-12-02 16:32:22 +01:00
Christophe Deschamps
6365c66d55 Fix ConferenceParticipantDeviceData not updated in certain circonstances 2022-12-02 16:14:17 +01:00
QuentinArguillere
61e645c238 Add post_quantum_secure shield icon to the project resources (file was actually already there but not included in the project) 2022-12-02 16:08:15 +01:00
Christophe Deschamps
9d5836b991 Hide video stats in conference call with video sending disabled 2022-12-02 15:28:54 +01:00
Christophe Deschamps
b78b4a1e6b Fix navigation when hanging up conference after editing participants list 2022-12-02 11:12:57 +01:00
Christophe Deschamps
6850282208 Conference waiting room : Dismiss layout picked if view is clicked elsewhere 2022-12-02 11:03:50 +01:00
Christophe Deschamps
9803678d6a Avoid unecessary setting of outgoing/incoming mutable value 2022-12-02 10:30:12 +01:00
QuentinArguillere
f2b36ed7f8 When Poping views, make sure we add the targeted one if we couldn’t already find it in the stack 2022-12-02 10:16:33 +01:00
QuentinArguillere
d39fb0661b Update version to 5.0.0 for incoming release 2022-12-01 17:44:46 +01:00
QuentinArguillere
b378682d0c Enable/disable phone’s idle timer when entering/leaving a conference 2022-12-01 17:39:53 +01:00
Benoit Martins
7da10d500f Change "VIEW(ChatConversationView).sharingMedia = nil" to "_sharingMedia = nil" in CharConversationView 2022-12-01 16:32:49 +01:00
Benoit Martins
4b5eaa3bc5 Fix image sharing from gallery, and fix view navigation 2022-12-01 16:32:49 +01:00
Benoit Martins
78c21a5c2b Change job iOS Tag to run on : macos-xcode13 2022-12-01 16:18:27 +01:00
Benoit Martins
fecbb85a81 Fix imdmIcon and ephemeral (icon/timer) in conversation when user want to transfer or reply messages 2022-12-01 16:02:02 +01:00
Benoit Martins
8582d93555 Fix for iPhone SE, the Security Badge of UIConfirmationDialog not displaying 2022-11-30 09:27:44 +01:00
Christophe Deschamps
a74d042a6a Restart video previow upon rotation to avoid crash 2022-11-28 16:42:40 +00:00
Christophe Deschamps
ad9163320c Landcape handling of video self view in 1-1 calls 2022-11-28 16:42:40 +00:00
Benoit Martins
5ab6a7ce1b Remove DTMF sound in Dialer View 2022-11-28 17:06:20 +01:00
QuentinArguillere
7ccdcbebcf Ensure that the result of linphone_event_log_get_chat_message(_event) is not nil before trying to use it 2022-11-28 17:00:29 +01:00
Benoit Martins
0fe94354d7 Fix ChatConversationView having no message after playing video received in chat 2022-11-28 16:52:59 +01:00
QuentinArguillere
3dc7d4fb15 Make sure we have callbacks before proceeding with chatroom deletions (could cause a crash when deleting chatrooms quickly after login and/or changing views) 2022-11-28 14:19:31 +01:00
Benoit Martins
a98aa42ca4 Disable features (Group chat and Security Chat) without Linphone account 2022-11-28 12:01:49 +01:00
Benoit Martins
84a817783d Removed IASKPSTitleValueSpecifierViewCell to align each cell of SettingView 2022-11-28 11:45:57 +01:00
Benoit Martins
6e846f092c Hide record button in conference views 2022-11-23 15:33:08 +01:00
Christophe Deschamps
fd9afd66fa Fix crash on marking chatroom as read 2022-11-23 13:34:10 +01:00
Christophe Deschamps
e5505a836c Merge branch 'fix/various_refacto_sync_android' into fix/various_refacto_sync_android2 2022-11-23 10:43:00 +01:00
Christophe Deschamps
781a9b07d1 Fix video freeze when alone in conference A/S mode 2022-11-23 09:21:21 +01:00
Christophe Deschamps
6a4ef41ab5 Various fixes in view model update propagation 2022-11-23 08:59:42 +01:00
Christophe Deschamps
c09519bcc1 Fixed dual spinner joining conference + set color to make it visible 2022-11-22 23:51:40 +01:00
Christophe Deschamps
9ab5a0f106 Enable full screen joining video conference with video 2022-11-22 23:51:40 +01:00
Christophe Deschamps
eff9964b12 Refactored to ConferenceWaitingRoomView 2022-11-22 23:51:40 +01:00
Christophe Deschamps
0202c7aa6b UTF8 handling in conference names in history 2022-11-22 23:51:40 +01:00
Christophe Deschamps
4cb99a62a0 Added local group call subject when merging calls 2022-11-22 23:51:40 +01:00
Christophe Deschamps
fc3f48363f Avoid getting back to waiting room after conf ends 2022-11-22 23:51:40 +01:00
Christophe Deschamps
3800aafd1f Full screen toggle 2022-11-22 23:51:40 +01:00
Christophe Deschamps
3a3c04bb23 Fix resuming call putting other calls on hold 2022-11-22 23:51:40 +01:00
Christophe Deschamps
8607469f68 Refactorisation of call views + various fixes 2022-11-22 23:51:15 +01:00
Christophe Deschamps
987ea21e05 Multi call various fixes 2022-11-22 23:50:58 +01:00
QuentinArguillere
b6ff317551 Check that contact address has a valid username when trying to match phone numbers 2022-11-22 17:25:23 +01:00
QuentinArguillere
9977644872 Add small 1px margin to make sure we scroll when Composing message appear while we just opened a chatroom 2022-11-22 17:24:44 +01:00
QuentinArguillere
d447158a25 Set _chatRoom to NULL when ChatConversationView disappears to avoir keeping invalid references 2022-11-22 17:24:10 +01:00
Benoit Martins
c3746801ac Remove Incoming condition in IncomingOutgoingCommonView for reset outgoing call timer 2022-11-22 15:50:35 +01:00
Benoit Martins
dbd56b5c38 Merge remote-tracking branch 'refs/remotes/origin/release/4.7' 2022-11-22 15:41:56 +01:00
Simon Morlat
c49013aa2b Fix an issue where audio does not work when a VoIP Call is resumed after a GSM call has been terminated by the remote party. 2022-11-22 14:34:20 +01:00
Benoit Martins
fc9c9b9508 Set fullscreen when start or join a conference 2022-11-22 14:28:22 +01:00
Benoit Martins
6cb4ea55f6 Fix scrollBadge and markAsRead in chat conversation 2022-11-22 11:12:27 +01:00
QuentinArguillere
54fb56d93c Fix crash when entering a chat conversation with audio messages that were not properly downloaded 2022-11-22 11:01:28 +01:00
Benoit Martins
ac49ee5d56 Merge remote-tracking branch 'refs/remotes/origin/release/4.7' 2022-11-22 09:57:43 +01:00
QuentinArguillere
03af1afac1 When calling setComposingVisible, check that the “is composing” message is visible as well as blocking text before scrolling to the bottom of the chat conversation view 2022-11-21 17:26:38 +01:00
Christophe Deschamps
233865747e Reworked IMDN cell calculation to make it independent from EventList 2022-11-21 15:56:30 +01:00
Christophe Deschamps
1291e7dee4 Protect _chatRoom dependent sub function calls 2022-11-21 14:54:19 +01:00
Benoit Martins
61ec8a37dd Merge remote-tracking branch 'refs/remotes/origin/release/4.7' 2022-11-21 13:20:55 +01:00
Benoit Martins
bd42b8855c Add hide_link_phone_number in RC setting for hide link_account view 2022-11-21 13:16:05 +01:00
Benoit Martins
7a78a14bbf Add hide_link_phone_number in RC setting for hide link_account view 2022-11-21 12:07:18 +01:00
Benoit Martins
236a8ee52f Fix recording list. Change of cell background color 2022-11-21 11:43:31 +01:00
Christophe Deschamps
62f7d8a620 0010414: Ios Build 2.1 (3) Probléme d'affichage de la ligne de notification d'écriture du correspondant. 2022-11-21 11:25:44 +01:00
Christophe Deschamps
8a47583130 set composig visible when _chatRoom is resolved 2022-11-21 11:23:01 +01:00
Christophe Deschamps
59098c6db0 Texts update 2022-11-18 09:29:23 +01:00
Christophe Deschamps
3043fc5c7a Do not force speaker on video activation/deactivation in conference 2022-11-18 09:27:26 +01:00
Christophe Deschamps
3e6bffd723 Added further missing translations 2022-11-18 09:00:50 +01:00
Christophe Deschamps
0cd72844b6 Missing translation 2022-11-18 08:46:19 +01:00
Christophe Deschamps
d5a6a233af Fix freeze in call by swiping screen right 2022-11-17 18:20:30 +01:00
Christophe Deschamps
65573ba1be Switch from audio only to active speaker using toggle video button (instead of disabling it) 2022-11-17 17:59:14 +01:00
Benoit Martins
669851065a Fix scrollToBottom for ChatConversation TableView 2022-11-17 17:24:22 +01:00
Benoit Martins
6fa24fff6d ScrollToBottom the ChatConversation TableView when composeLabel is visible 2022-11-17 17:24:22 +01:00
Benoit Martins
670dabaf77 Update popup ZRTP 2022-11-17 17:15:59 +01:00
Christophe Deschamps
93eecbc304 Appearance (dark/light) handling 2022-11-17 16:08:34 +00:00
Christophe Deschamps
e02580bade Removed redundant post of kLinphoneMessageReceived notification when chat conversation is opened 2022-11-17 13:44:27 +01:00
Christophe Deschamps
581d2dbf50 Removed ChatConversationTableView entire reloading upon entry addition 2022-11-17 13:44:27 +01:00
Christophe Deschamps
f7ad67390a Fix PQ Call Stats 2022-11-17 13:20:39 +01:00
Benoit Martins
c72d8913b8 Add a new button in the account link popup to never ask again user to link his account 2022-11-17 10:43:30 +01:00
Christophe Deschamps
490f9e96db Hide remote video view in 1-1 call when it is paused by remote 2022-11-15 18:11:02 +01:00
QuentinArguillere
5fb42ce09f When configuring a linphone account, set the core media encryption to SRTP by default 2022-11-15 16:30:07 +01:00
Christophe Deschamps
736059f699 Fix compilation 2022-11-15 07:35:11 +01:00
Christophe Deschamps
b63779b65e Enable camera in background context when app goes in background 2022-11-15 07:30:37 +01:00
Christophe Deschamps
0fc1f024d3 Enable camera on conference calls when app comes to foreground 2022-11-14 21:19:11 +01:00
QuentinArguillere
8b5668e8ce Prevent from from going to sleep when video is active in call 2022-11-14 16:46:55 +01:00
Christophe Deschamps
8909ae7279 Fix meeting icon in size menu 2022-11-10 17:56:49 +01:00
Christophe Deschamps
be5e303b09 Handle pause in A/S view when 1 or 2 participants 2022-11-10 17:30:27 +01:00
Christophe Deschamps
82704471ac Fix layout change when reaching more than 6 participants 2022-11-10 08:31:56 +01:00
Christophe Deschamps
988840d9a9 Fix compilation 2022-11-09 10:24:45 +01:00
Christophe Deschamps
a120a067c9 Revert "Fix crash upon device rotation when playing back voice memo"
This reverts commit d326b7f56e.
2022-11-08 18:22:56 +01:00
Christophe Deschamps
555428d62d Fix layout of chat conversation upon rotation 2022-11-08 18:09:40 +01:00
Christophe Deschamps
d326b7f56e Fix crash upon device rotation when playing back voice memo 2022-11-08 18:07:53 +01:00
Christophe Deschamps
59c90fe65a Handle meeting invite notification creation/update/cancellation 2022-11-08 15:25:12 +01:00
QuentinArguillere
3edcfb4222 Fix contact list in chat/conference creation view in order to include contacts from ldap/remote provisioning that have a sip uri 2022-11-08 11:55:54 +01:00
QuentinArguillere
77c4fb1747 Fix potential background crash when link popup was supposed to appear 2022-11-04 19:43:45 +01:00
QuentinArguillere
50f656d1ee Rework of non-native contacts: fix bug that would not display sip adresses in detail view, and fix bug that would lose the “createdFromLdapOrProvisioning” tag of non-native contacts after first launch. 2022-11-04 15:22:55 +01:00
Christophe Deschamps
06cbe9fa1d Fix avatars light/dark mode 2022-11-03 17:04:28 +01:00
QuentinArguillere
f3bc7add35 Check for nil chatroom in ChatConversationView.m::CellForRowAtIndexPath to avoid recurring crashes in background. Temporary fix. 2022-11-03 15:29:28 +01:00
Christophe Deschamps
9fcfe2b8de Cosmetic on chat contextual menu 2022-11-03 14:50:31 +01:00
Christophe Deschamps
d04f961559 Handle ICSs in chat list last message 2022-11-03 14:14:08 +01:00
QuentinArguillere
1e1c0fd3d3 Fix magic search to also display contacts that were created through remote provisioning, not just LDAP or native 2022-11-03 13:51:13 +01:00
Christophe Deschamps
7ddfff9c32 Unified avatar with VoIP 2022-11-03 13:35:38 +01:00
Christophe Deschamps
ecdb22dc5d (Ugly) work around to display differentiated avatars for numbers and usernames, until rest of the app is re-written in swift 2022-11-03 12:56:44 +01:00
Christophe Deschamps
d340db5680 Fix removal of UIChatCreateCollectionViewCell.xib 2022-11-03 12:05:24 +01:00
Christophe Deschamps
960046b87e Coscmetic on group chat info view 2022-11-03 10:13:14 +01:00
Christophe Deschamps
79a2235368 Cosmetic on conference list display 2022-11-03 10:09:47 +01:00
Christophe Deschamps
df53cc73e9 Avatar icon colour fixes 2022-11-03 08:39:02 +01:00
Christophe Deschamps
44cf121007 Cosmetic fixes on conference summary view 2022-11-03 08:37:37 +01:00
Christophe Deschamps
14ddbaa58a New message indicator icon in orange background 2022-11-03 00:28:44 +01:00
Christophe Deschamps
0c687d1dce Removed separator in popup menus (chat conversation, and chat bubble) 2022-11-03 00:09:41 +01:00
Christophe Deschamps
f00daf1997 Do not hide keyboard upon contact selection in group chat/call creation 2022-11-02 23:58:02 +01:00
Christophe Deschamps
c80ad228ef Reworked UICollectionView for displaying selected contacts in group chat and group calls 2022-11-02 23:47:49 +01:00
Christophe Deschamps
70b2671f19 No default date/time when scheduling a conference 2022-11-02 21:51:46 +01:00
Christophe Deschamps
3c8af14495 Conference subject hint changing if groupcall or meeting 2022-11-02 21:51:26 +01:00
Christophe Deschamps
51f23e91bb Implement onActiveSpeakerParticipantDevice api on conference 2022-11-01 22:29:06 +01:00
Christophe Deschamps
cd7951e590 Fix chat room creation view split 2022-10-21 17:21:20 +02:00
Christophe Deschamps
a6638d3c9b Update new class header 2022-10-21 10:57:31 +02:00
Christophe Deschamps
0e947803ce Set unique file name per message to avoid local display conflicts 2022-10-21 10:53:05 +02:00
Christophe Deschamps
666b2c7f48 Fix conference creation button state in conference list 2022-10-19 10:31:30 +02:00
Christophe Deschamps
ac32d80b51 Voipdialog anchor on iPads 2022-10-19 10:27:14 +02:00
Christophe Deschamps
e2dc5d4ad3 Show tabbar in chat on iPads (no back button) 2022-10-19 10:23:53 +02:00
Christophe Deschamps
eda3fa114a Merge branch 'fix/conf_fixes' into release/4.7 2022-10-19 09:59:24 +02:00
Christophe Deschamps
fd3afda60c Bulk bug fixes conference 2022-10-19 09:57:52 +02:00
Christophe Deschamps
670ad21770 Conference creation on iPad 2022-10-19 09:53:58 +02:00
Christophe Deschamps
0353180bd0 Conference creation on iPad 2022-10-19 09:53:01 +02:00
Christophe Deschamps
b402f08006 Send cancel conference iCS 2022-10-19 08:55:38 +02:00
QuentinArguillere
b495e4b8bb Disable basic chat button in contact history when force_lime_chat_rooms=1 2022-10-17 13:25:35 +02:00
Christophe Deschamps
a0a1e1a417 Bulk bug fixes conference 2022-10-14 18:31:23 +02:00
QuentinArguillere
821f2e30b7 Rename : “only_secure_chatrooms”=>”force_lime_chat_rooms” and “fetch_native_contacts”=>”enable_native_address_book” to match android 2022-10-14 10:13:48 +02:00
Christophe Deschamps
d0f83d6d1d Fix freeze tapping settings in waiting room 2022-10-12 17:30:20 +02:00
Christophe Deschamps
f705e14664 Removed double tap listener on audio click / landscape 2022-10-12 07:27:14 +02:00
Christophe Deschamps
35c772db3a Meeting edition fixes 2022-10-11 17:10:55 +02:00
QuentinArguillere
a57da3d499 Add [rtp]accept_any_encryption=1 and [video]max_conference_size=vga to linphonerc-factory 2022-10-11 16:41:18 +02:00
QuentinArguillere
b9ef7a83b5 Go to chatrooms after receiving “on_conference_joined” callback rather than when chatroom is created 2022-10-07 16:03:26 +02:00
Christophe Deschamps
559a9d8bc3 Handle video/no video updates from Active Speaker 2022-10-03 14:56:21 +02:00
Christophe Deschamps
f8d3a196f5 Fix display of conferences in history on ipads 2022-09-29 13:41:51 +02:00
Christophe Deschamps
298778e20d Fix AS layout not updating when joining a conf with more than 2 participants already 2022-09-29 13:23:36 +02:00
QuentinArguillere
b4103d2f4f Add “only_secure_chatrooms” parameter to rc. When set to “1”, only encrypted chatrooms can be created 2022-09-27 17:21:16 +02:00
QuentinArguillere
4c75c4222d Add “fetch_native_contacts” parameters to the rc-factory. If set to 0, we won’t ask for permission to use the phone native contacts 2022-09-26 10:46:58 +02:00
Christophe Deschamps
d8163fb55b Option to schedule meeting from group chat 2022-09-23 00:45:02 +02:00
Christophe Deschamps
68597369ed Send cancel information when deleting a meeting self-organized 2022-09-23 00:40:20 +02:00
Christophe Deschamps
388e3482a9 Multiple deletion of meetings (function activated by long click on meeting cell) 2022-09-22 23:58:36 +02:00
Christophe Deschamps
811a859430 Swipe to delete on conferences view 2022-09-22 23:58:25 +02:00
Christophe Deschamps
96543cdaca Fix (for good) background color for Me participant + repositionned the Me sticker bottom right in AS Landscape iso top right 2022-09-19 16:05:02 +02:00
Christophe Deschamps
23633d1ea4 Send conference invitation via secure chat when possible 2022-09-19 15:43:27 +02:00
Christophe Deschamps
cf78ae8ff9 Display a message when attempting to launch cancelled conference from history 2022-09-19 15:18:15 +02:00
Christophe Deschamps
2b252a04ff Added handling of meeting cancellation and edition 2022-09-19 11:37:55 +02:00
Christophe Deschamps
d54c9ef5a9 Set special color for local participants in conference 2022-09-19 11:37:42 +02:00
Christophe Deschamps
aaea844c4c Added remote mute indicator in AS Conference view with 2 participants 2022-09-19 11:37:36 +02:00
Christophe Deschamps
507060fb31 Video conference : use video preview when alone and in active speaker view 2022-09-08 17:38:36 +02:00
Christophe Deschamps
863731f775 Wrap display name of participants in conference grid mode 2022-09-08 13:16:10 +02:00
Christophe Deschamps
6a8c5a4440 Tidy up Avatar 2022-09-08 13:16:03 +02:00
QuentinArguillere
360c88b764 Change uri of video conference factory to “sip:videoconference-factory@sip.linphone.org” 2022-09-01 18:01:31 +02:00
QuentinArguillere
a4bfa37454 Remove line committed by mistake 2022-08-30 15:32:13 +02:00
QuentinArguillere
68bece526b Put set LDAP search loading view to be semi transparent, and add a message when more results are available 2022-08-30 15:32:08 +02:00
QuentinArguillere
8efce6e446 Do not apply international prefix when parsing uri that will not be used for a chat/call 2022-08-30 15:06:09 +02:00
Christophe Deschamps
4333e97932 Add more space to call view in landscape mode 2022-08-24 09:34:40 +02:00
Christophe Deschamps
77b9287195 Conference Active Speaker adjustments :
- Leave local participant always first (portrait) or top (landscape)
- Layout for 0, 1 and more participants
2022-08-24 09:17:11 +02:00
QuentinArguillere
a4bc64f2b3 Use linphone_core_interpret_url_2 and use the account params useInternationalPrefixForCallsAndChat 2022-08-23 16:30:17 +02:00
QuentinArguillere
2a54eae049 Add Post quantum ZRTP support, encryption section to the call stats. Add zrtp_key_agreements_suites for post quantum in the factory rc 2022-08-23 16:01:43 +02:00
Christophe Deschamps
2279a23db1 Added dropdown patch into Podfile 2022-08-19 16:01:37 +02:00
Christophe Deschamps
8743a01b88 Filter for terminated/scheduled conferences 2022-08-19 12:23:31 +02:00
Christophe Deschamps
8ed7ba7bee IMDM cell cosmetics 2022-08-19 12:21:48 +02:00
Christophe Deschamps
240d28e234 Display Meeting in recording list instead of conference server address 2022-08-19 12:21:40 +02:00
Christophe Deschamps
d352034e5e Display avatar icon instead of initials when username is a phone number 2022-08-19 12:21:28 +02:00
Christophe Deschamps
3c12854dc6 Conference participants list cosmetics 2022-08-19 12:21:19 +02:00
Christophe Deschamps
47b7820b58 Meeting invitations bubble :
- Fix description displaying (dynamic height)
- Fix reply/forward header overlap
- Remove copy text option from contextual menu of ICS
- Improved chat bubble context menu icons quality
- Do not show IMDM option menu in 1-1 chat room
- Remove extra space at bottom of contextual menu in chat bubbles
2022-08-19 12:21:10 +02:00
Christophe Deschamps
ed56de2527 Send conference invitations only if scheduled for laster 2022-08-19 12:20:32 +02:00
Christophe Deschamps
57399ec722 Conference scheduling graphical fixes :
- mandatory indicator icon truncated
- text entry colors (hint/text)
- Send via option moved inside scheduling form
- mandatory indicator placement
- conference summary cosmetics
2022-08-19 12:20:24 +02:00
Christophe Deschamps
57b676c775 - Ability to mute/unmute when outside a conference
- Call stats & Numpad views above controls
- Group call icon in call list cosmetic
- Calls List : fix icon size & layout issue on some iOS Devices
- Black background on video full screen conference
2022-08-19 12:20:14 +02:00
Christophe Deschamps
07e0f0ca80 Fix conference resume button 2022-08-19 12:20:06 +02:00
Christophe Deschamps
981a7c5a60 Cosmetic on dots menu & micro icon on conversation view 2022-08-19 12:19:56 +02:00
Christophe Deschamps
8ba4230c19 Conference Active Speaker view landscape mode 2022-08-19 12:19:48 +02:00
Christophe Deschamps
12f9de3384 Landscape layout in conference waiting room
If video is activated in waiting room with audio only mode selected, active speaker mode becomes selected
2022-08-19 12:19:39 +02:00
Christophe Deschamps
6af2602639 Fix local video content mode in 1-1 video calls 2022-08-19 12:19:25 +02:00
Christophe Deschamps
81964daa0c Prevent infinite loop on displaying ICS invitation 2022-08-19 12:19:06 +02:00
Quentin Monnier
7cdcdd4a4d bug fix :
-display/hide call stats when clicking on the network quality icon in the status bar of the Active Call View
2022-08-19 11:13:14 +02:00
Quentin Monnier
be1e726a0c bug fix:
-resume the active call by clicking on the play button and not by clicking anywhere on the screen when it is paused
2022-08-19 11:13:08 +02:00
Quentin Monnier
8d3fead61d bug fix:
-shows the "backToCallButton" when accessing the "TransferCallView" and the "AddCallView" from the "ExtraButtonMenu" in active calls
-delete the first blank character in the entered DTMF
-disable the hide action of the "ExtraButtonMenu" when clicking between buttons, in the background
-closes the "NumpadView" and the "CallStatsView" when the call ends
-displays the "StatusBar" in "Incoming/OutgoingCallView"
-define the height of the "EneteredDtmfTextView" (no longer automatic since the blank character has been removed)
2022-08-19 11:13:02 +02:00
QuentinArguillere
5dda082a75 Do not display accounts that have the “hidden” custom parameters enabled 2022-08-11 09:39:27 +02:00
QuentinArguillere
a77d6bb1b6 Fix chatroom when entering background then re-entering foreground during a call 2022-07-28 15:36:45 +02:00
QuentinArguillere
dcc832436e Allow the removal of account international prefix when it has been set 2022-07-28 15:36:28 +02:00
Christophe Deschamps
1559bf46c7 Activate CallKit & Audio Session upon immediate conf locally created 2022-07-27 17:43:41 +02:00
QuentinArguillere
4ec4723fbb When destroying the linphone core, also destroy the magic search singleton This fixes bugs that would break the LDAP contact search after a remote provisioning. 2022-07-27 15:23:05 +02:00
QuentinArguillere
d25cbbf609 To avoid possible race condition, reload contacts in the global state change callbacks 2022-07-27 15:22:59 +02:00
Christophe Deschamps
90c367ccca Workarounds for active speaker: do not display 'me' device name when speaking + showing ourselves when alone 2022-07-22 12:09:49 +02:00
Christophe Deschamps
3e22ea3a80 Fix Toast not dismissing 2022-07-21 12:22:21 +02:00
Christophe Deschamps
49bee7c6a0 ICS Reply 2022-07-11 23:44:22 +02:00
Christophe Deschamps
907cc94fc6 Conference side menu icon 2022-07-11 23:44:13 +02:00
Christophe Deschamps
b04a306443 Fix locally paused state in view model 2022-07-11 23:44:06 +02:00
Christophe Deschamps
ffe795bf02 Merge branch 'release/4.7' of gitlab.linphone.org:BC/public/linphone-iphone into release/4.7 2022-07-11 20:52:24 +02:00
Christophe Deschamps
5ee6695cdc Adapt to latest sdk change related to conference + implemented joining spinner + refactored conference miniatures update 2022-07-11 20:52:15 +02:00
QuentinArguillere
d14a0d3c10 In group chatrooms, added the “add to contact” contextual action when interacting with a message coming from someone that is not registered in your phone contacts 2022-07-08 17:21:31 +02:00
QuentinArguillere
9612e21162 Fix “Add to contact” action for encrypted chatrooms 2022-07-08 17:11:12 +02:00
QuentinArguillere
81688b416b Do not display “Infos” action for messages in 1-1 chatrooms 2022-07-05 13:51:40 +02:00
QuentinArguillere
da08af7e3f “Back” button in chatrooms should now behave more in line with what is expected : return to the chatlist view in most cases 2022-07-05 13:50:15 +02:00
QuentinArguillere
9ab70c60fe In chat conversation, hide keyboard when the action pop-up bubble (reply, transfer, etc) appears, and show keyboard when “reply’ is selected. This matches the usual behaviours of other messaging apps 2022-07-04 17:24:33 +02:00
Christophe Deschamps
e3ed160c54 Dropdown picker more user-friendly 2022-07-03 19:00:52 +02:00
Christophe Deschamps
7d71bd500e Merge branch 'release/4.7' of gitlab.linphone.org:BC/public/linphone-iphone into release/4.7 2022-07-03 19:00:47 +02:00
QuentinArguillere
6ca276b718 Update iOS version on Podfile from 9.0 to 10.0 2022-06-30 15:57:52 +02:00
Christophe Deschamps
0d0c0225f1 Fix calendar event pre-set fields 2022-06-30 15:21:13 +02:00
Christophe Deschamps
6adeb43fdc Added calendar sharing of ICS from bubble chat 2022-06-30 12:27:41 +02:00
Christophe Deschamps
761a47ad87 Prevent keyboard from hiding description field in conference scheduling view 2022-06-29 13:12:50 +02:00
Christophe Deschamps
343a30d93b Admin set/unset notification in conference 2022-06-29 08:53:00 +02:00
QuentinArguillere
54071f9d15 Avoid crash in settings menu for iOS < 13.0 2022-06-28 17:21:01 +02:00
QuentinArguillere
924b499496 Disable voip & remote push notification by default when using the assistant to login with an external sip account 2022-06-28 17:20:17 +02:00
QuentinArguillere
10b28cd6cf Fix canAdminEphemeral function in ChatConversationViews so that only encrypted chatrooms can possibly return “true”. Also fix bug causing the wrong row to be called in chatroom popup action menu 2022-06-27 16:50:38 +02:00
QuentinArguillere
33b07703ca Always display LDAP contacts in priority. If a local contact matches, partially or totally, the LDAP contact, still display both. 2022-06-27 11:43:33 +02:00
QuentinArguillere
74c69b3779 Always Hide edit/delete buttons for LDAP contact details view (could still appear if accessed through a “previous” button) 2022-06-27 11:43:27 +02:00
QuentinArguillere
ef8e1baa92 Fix typo in LDAP.plist file 2022-06-24 16:54:55 +02:00
QuentinArguillere
6e93601508 Fix typos in LDAP settings menu that would cause a partial loss of the configuration when exiting the menu 2022-06-24 16:18:15 +02:00
QuentinArguillere
0e31b555c1 Implement notification mute for group & encrypted chatrooms 2022-06-23 14:48:51 +02:00
QuentinArguillere
930dd74c89 Fix bugs when rotating from portrait to landscape mode : edit/delete action shown as available for LDAP contacts, or Contact Name appearing despite being currently in edit mode 2022-06-23 13:33:16 +02:00
QuentinArguillere
f847d8cfe3 Fix bug that could cause a clipping/hiding of a contact name depending on the phone orientation 2022-06-23 13:33:06 +02:00
QuentinArguillere
263b460372 When hitting the “back” button on a contact details view, redirect to the ContactListView by default. Only return to the history details view if we specifically came from there. 2022-06-23 13:33:00 +02:00
QuentinArguillere
4c690f9274 Now allow duplicate contacts to be displayed (useful if you have a local contact AND the contact exists with more informations in a LDAP server) 2022-06-23 13:32:54 +02:00
QuentinArguillere
ff14c18f1c Fix GUI when remote provisioning fails due to the user already having accounts 2022-06-23 13:32:49 +02:00
Christophe Deschamps
97708e9096 Fallback to AS if MaxPart > 6 only if Grid is active 2022-06-23 09:49:02 +02:00
256 changed files with 14207 additions and 3148 deletions

View file

@ -7,11 +7,12 @@ variables:
job-ios:
stage: build
tags: [ "macmini-m1-xcode13" ]
tags: [ "macos-xcode13" ]
script:
- pod install --repo-update
- pwd
- sed 's/fileprivate let tableView =/public let tableView =/g' ./Pods/DropDown/DropDown/src/DropDown.swift > tmp.swift && mv -f tmp.swift ./Pods/DropDown/DropDown/src/DropDown.swift
- xcodebuild archive -scheme $archive_scheme -archivePath ./$archive_path -configuration Release -workspace ./linphone.xcworkspace -UseModernBuildSystem=YES -destination 'generic/platform=iOS'
- xcodebuild -exportArchive -archivePath ./$archive_path -exportPath ./$export_path -exportOptionsPlist ./$export_options_plist -allowProvisioningUpdates -UseModernBuildSystem=YES -destination 'generic/platform=iOS'

View file

@ -10,15 +10,89 @@ Group changes to describe their impact on the project, as follows:
Fixed for any bug fixes.
Security to invite users to upgrade in case of vulnerabilities.
## [5.1.1] - 2023-04-09
### Changed
- Update linphone SDK to 5.2.99
### Fixed
- Fix bug that could prevent the creation or logging in of a linphone account using a phone number
- Fix UI bug on dark mode when using multiple accounts simultaneously
## [5.1.0] - 2023-21-08
### Added
- In contacts and chat conversations view, show short term presence for contacts whom publish it + added setting to disable it (enabled by default for sip.linphone.org accounts)
- Advanced settings - option to prevent the taking of screenshot
- Emoji picker in chat conversations
- Add Organization label to contacts, and the possibility to filter through it
- Possibility to make an attended transfer from one call to another
- Contact names, phone numbers and sip addresses are now copyable through with long press action
### Changed
- Switched Account Creator backend from XMLRPC to FlexiAPI, it now requires to be able to receive a push notification
- Chat conversation view (one-to-one and group) completely remade with Swift, with various quality of life improvements.
- Minimum iOS version is now 11.2
- Update linphone SDK to 5.2.95
### Fixed
- Several crashes in the chat conversation view and background mode
- Url scheme handler : can now properly do a remote configuration when opening a linphone-config:URL from another app
- Bug that could cause push notification to stop working after killing the app manually
## [5.0.2] - 2023-16-03
### Changed
- Update linphone SDK to 5.2.32
### Fixed
- Performance issue causing a global slowing of the app, especially at launch
- Fix several memory leaks and crashes
## [5.0.1] - 2023-10-01
### Changed
- Update linphone SDK to 5.2.11
### Fixed
- Makes sure sip.linphone.org accounts have a LIME X3DH server URL for E2E chat messages encryption
- Fix potential crash when displaying images received in a chatroom
- Fix bug that would cause the previous call to be terminated when resuming another call that was paused
- Fix participant video display in conferences when a second participant joined with video enabled
## [5.0.0] - 2022-12-06
### Added
- Post Quantum encryption when using ZRTP
- Conference creation with scheduling, video, different layouts, showing who is speaking and who is muted, etc...
- Group calls directly from group chat rooms
- Chat rooms can be individually muted (no notification when receiving a chat message)
- Outgoing call video in early-media if requested by callee
- Call recordings can be exported
- Setting to prevent international prefix from account to be applied to call & chat
- Add a "Never ask again" option to the "Link my account" pop-up when starting the app
### Changed
- In-call views have been re-designed
- Improved how contact avatars are generated
- 3-dots menu even for basic chat rooms with more options
- Update linphone SDK to 5.2.0
### Fixed
- Chatroom appearing as empty when being logged on multiple accounts
- Chatroom appearing as empty after playing a video file inside it
- Fix potential crash when entering a chatroom
- Fix potential crash when accessing to the delivery infos of a message in a group chat.
- IMDN logo not properly displayed when transfering or replying to a message with media (voice message, photo...)
- Clarified view when sending an image from the galery
- Various audio route fixes for CallKit and IOS 16
## [4.6.4] - 2021-08-06
## [4.6.4] - 2022-08-06
### Changed
- Update linphone SDK to 5.1.42
### Fixed
- Prevent possible application freeze and crash when creating a new chatroom, depending on the phone's contacts.
## [4.6.3] - 2021-02-06
## [4.6.3] - 2022-02-06
### Added
- New "Contacts" menu in the settings, which allows the use of LDAP configurations
@ -33,7 +107,7 @@ Group changes to describe their impact on the project, as follows:
- Display bug when changing audio device
## [4.6.2] - 2021-07-03
## [4.6.2] - 2022-07-03
### Fixed
- Bug preventing the activation of the phone speaker during calls
@ -41,7 +115,7 @@ Group changes to describe their impact on the project, as follows:
- Bug causing IMDNs to be missing in some chatrooms
- Update linphone SDK to 5.1.7
## [4.6.1] - 2021-04-03
## [4.6.1] - 2022-04-03
### Fixed
- Crash in chatroom info view after entering background and re-entering foreground
@ -49,7 +123,7 @@ Group changes to describe their impact on the project, as follows:
- Hard to see text (written in black) on dark mode
- Removed duplicate push authorization request pop up on install
## [4.6.0] - 2021-31-02
## [4.6.0] - 2022-31-02
### Added
- Reply to chat message feature (with original message preview)

View file

@ -62,11 +62,13 @@
}
linphone_account_creator_set_user_data(account_creator, (__bridge void *)(self));
linphone_account_creator_cbs_set_link_account(linphone_account_creator_get_callbacks(account_creator),
assistant_link_phone_number_with_account);
linphone_account_creator_cbs_set_activate_alias(linphone_account_creator_get_callbacks(account_creator),
assistant_activate_phone_number_link);
LinphoneAccountCreatorCbs * cbs = linphone_factory_create_account_creator_cbs(linphone_factory_get());
linphone_account_creator_cbs_set_link_account(cbs, assistant_link_phone_number_with_account);
linphone_account_creator_cbs_set_activate_alias(cbs, assistant_activate_phone_number_link);
linphone_account_creator_add_callbacks(account_creator, cbs);
linphone_account_creator_cbs_unref(cbs);
LinphoneAccount *acc = linphone_core_get_default_account(LC);
LinphoneAccountParams const *accParams = (acc) ? linphone_account_get_params(acc) : NULL;
if (acc &&

View file

@ -22,6 +22,12 @@
#import "TPKeyboardAvoidingScrollView.h"
#import "PhoneMainView.h"
typedef enum _TokenRequestAction {
TokenRequestAction_None,
TokenRequestAction_CreateAccount,
TokenRequestAction_RecoverAccount
} TokenRequestAction;
@interface AssistantView : UIViewController <UITextFieldDelegate, UICompositeViewDelegate, UITextViewDelegate> {
@private
@ -33,6 +39,7 @@
size_t number_of_accounts_before;
BOOL mustRestoreView;
long phone_number_length;
TokenRequestAction tokenRequestAction;
}
@property(nonatomic) UICompositeViewDescription *outgoingView;

View file

@ -28,6 +28,13 @@
#import "UIAssistantTextField.h"
#import "UITextField+DoneButton.h"
#import "LinphoneAppDelegate.h"
#import "SVProgressHUD.h"
#ifdef DEBUG
#define PROVIDER_NAME "apns.dev"
#else
#define PROVIDER_NAME "apns"
#endif
typedef enum _ViewElement {
ViewElement_Username = 100,
@ -94,7 +101,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onContactTap {
NSString *url = @"https://www.linphone.org/contact";
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
LOGE(@"[Assistant] Failed to open %@, invalid URL", url);
}
}
@ -118,16 +125,16 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(configuringUpdate:)
name:kLinphoneConfiguringStateUpdate
object:nil];
if (!account_creator) {
account_creator = linphone_account_creator_new(
LC,
[LinphoneManager.instance lpConfigStringForKey:@"xmlrpc_url" inSection:@"assistant" withDefault:@""]
.UTF8String);
}
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onAccountAuthenticationTokenReceived:)
name:kLinphoneAccountCreationAuthenticationTokenReceived
object:nil];
if (!mustRestoreView) {
new_account = NULL;
number_of_accounts_before = bctbx_list_size(linphone_core_get_account_list(LC));
MSList *accounts = [LinphoneManager.instance createAccountsNotHiddenList];
number_of_accounts_before = bctbx_list_size(accounts);
bctbx_free(accounts);
[self resetTextFields];
[self changeView:_welcomeView back:FALSE animation:FALSE];
}
@ -183,6 +190,7 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Utils
- (void)resetLiblinphone:(BOOL)core {
if (account_creator) {
linphone_account_creator_unref(account_creator);
account_creator = NULL;
@ -194,21 +202,25 @@ static UICompositeViewDescription *compositeDescription = nil;
LC, [LinphoneManager.instance lpConfigStringForKey:@"xmlrpc_url" inSection:@"assistant" withDefault:@""]
.UTF8String);
linphone_account_creator_set_user_data(account_creator, (__bridge void *)(self));
linphone_account_creator_cbs_set_is_account_exist(linphone_account_creator_get_callbacks(account_creator),
assistant_is_account_used);
linphone_account_creator_cbs_set_create_account(linphone_account_creator_get_callbacks(account_creator),
assistant_create_account);
linphone_account_creator_cbs_set_activate_account(linphone_account_creator_get_callbacks(account_creator),
assistant_activate_account);
linphone_account_creator_cbs_set_is_account_activated(linphone_account_creator_get_callbacks(account_creator),
assistant_is_account_activated);
linphone_account_creator_cbs_set_recover_account(linphone_account_creator_get_callbacks(account_creator),
assistant_recover_phone_account);
linphone_account_creator_cbs_set_is_account_linked(linphone_account_creator_get_callbacks(account_creator),
assistant_is_account_linked);
linphone_account_creator_cbs_set_login_linphone_account(linphone_account_creator_get_callbacks(account_creator), assistant_login_linphone_account);
LinphoneAccountCreatorCbs * cbs = linphone_factory_create_account_creator_cbs(linphone_factory_get());
linphone_account_creator_cbs_set_is_account_exist(cbs, assistant_is_account_used);
linphone_account_creator_cbs_set_create_account(cbs, assistant_create_account);
linphone_account_creator_cbs_set_activate_account(cbs, assistant_activate_account);
linphone_account_creator_cbs_set_is_account_activated(cbs,
assistant_is_account_activated);
linphone_account_creator_cbs_set_recover_account(cbs,
assistant_recover_phone_account);
linphone_account_creator_cbs_set_is_account_linked(cbs,
assistant_is_account_linked);
linphone_account_creator_cbs_set_login_linphone_account(cbs, assistant_login_linphone_account);
linphone_account_creator_cbs_set_send_token(cbs, assistant_request_auth_token_cb);
linphone_account_creator_add_callbacks(account_creator, cbs);
linphone_account_creator_cbs_unref(cbs);
}
- (void)loadAssistantConfig:(NSString *)rcFilename {
linphone_core_load_config_from_xml(LC,
[LinphoneManager bundleFile:rcFilename].UTF8String);
@ -302,7 +314,12 @@ static UICompositeViewDescription *compositeDescription = nil;
return NSLocalizedString(@"There is no network connection available, enable "
@"WIFI or WWAN prior to configure an account.",
nil);
if IS(ERROR_PUSH_UNAVAILABLE)
return NSLocalizedString(@"Push parameters are not available, and are required in order to create an account through an iPhone.\n Please enable them or create your account on https://subscribe.linphone.org", nil);
if IS(ERROR_AUTH_TOKEN_NOT_RECEIVED)
return NSLocalizedString(@"Failed to get an auth token from account manager server", nil);
return NSLocalizedString(@"Unknown error, please try again later.", nil);
}
@ -512,13 +529,12 @@ static UICompositeViewDescription *compositeDescription = nil;
linphone_address_unref(identity);
LinphonePushNotificationConfig *pushConfig = linphone_account_params_get_push_notification_config(accountParams);
#ifdef DEBUG
#define PROVIDER_NAME "apns.dev"
#else
#define PROVIDER_NAME "apns"
#endif
linphone_push_notification_config_set_provider(pushConfig, PROVIDER_NAME);
if (strcmp(creatorDomain, "sip.linphone.org")==0) {
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionSRTP);
}
new_account = linphone_core_create_account(LC, accountParams);
linphone_account_params_unref(accountParams);
@ -705,7 +721,7 @@ static UICompositeViewDescription *compositeDescription = nil;
LinphoneAccount *default_account = linphone_core_create_account(LC, default_account_params);
const char *identity = linphone_account_params_get_identity(linphone_account_get_params(default_account));
if (identity) {
LinphoneAddress *default_addr = linphone_core_interpret_url(LC, identity);
LinphoneAddress *default_addr = linphone_core_interpret_url_2(LC, identity, false);
if (default_addr) {
const char *domain = linphone_address_get_domain(default_addr);
const char *username = linphone_address_get_username(default_addr);
@ -1011,10 +1027,13 @@ static UICompositeViewDescription *compositeDescription = nil;
[LinphoneManager.instance lpConfigSetInt:[NSDate new].timeIntervalSince1970
forKey:@"must_link_account_time"];
[LinphoneManager.instance configurePushProviderForAccounts];
if (number_of_accounts_before < bctbx_list_size(linphone_core_get_account_list(LC))) {
LOGI(@"A proxy config was set up with the remote provisioning, skip assistant");
MSList *accounts = [LinphoneManager.instance createAccountsNotHiddenList];
if (number_of_accounts_before < bctbx_list_size(accounts)) {
LOGI(@"[Assistant] A proxy config was set up with the remote provisioning, skip assistant");
[self onDialerClick:nil];
}
bctbx_free(accounts);
_waitView.hidden = true;
if (nextView == nil) {
@ -1047,7 +1066,19 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
- (void)onAccountAuthenticationTokenReceived:(NSNotification *)notif {
NSString *token = [LinphoneManager.instance lpConfigStringForKey:@"account_creation_token" inSection:@"app"];
linphone_account_creator_set_token(account_creator, [token UTF8String]);
if (tokenRequestAction == TokenRequestAction_CreateAccount)
linphone_account_creator_is_account_exist(account_creator);
else if (tokenRequestAction == TokenRequestAction_RecoverAccount)
linphone_account_creator_recover_account(account_creator);
tokenRequestAction = TokenRequestAction_None;
}
- (void)showErrorPopup:(const char *)error {
[SVProgressHUD dismiss];
const char *err = error ? error : "";
if (strcmp(err, "ERROR_BAD_CREDENTIALS") == 0) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Connection failure", nil)
@ -1125,6 +1156,28 @@ static UICompositeViewDescription *compositeDescription = nil;
defaultAction.accessibilityLabel = @"PopUpResp";
[errView addAction:defaultAction];
[self presentViewController:errView animated:YES completion:nil];
} else if (strcmp(err, "ERROR_PUSH_UNAVAILABLE") == 0) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Push unavailable", nil)
message:[AssistantView StringForXMLRPCError:err]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
defaultAction.accessibilityLabel = @"PopUpResp";
[self presentViewController:errView animated:YES completion:nil];
} else if (strcmp(err, "ERROR_AUTH_TOKEN_NOT_RECEIVED") == 0) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Authentication token error", nil)
message:[AssistantView StringForXMLRPCError:err]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
defaultAction.accessibilityLabel = @"PopUpResp";
[self presentViewController:errView animated:YES completion:nil];
} else {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Account configuration issue", nil)
message:[AssistantView StringForXMLRPCError:err]
@ -1149,7 +1202,11 @@ static UICompositeViewDescription *compositeDescription = nil;
_outgoingView = DialerView.compositeViewDescription;
[self configureAccount];
} else if (status == LinphoneAccountCreatorStatusAccountExist) {
_outgoingView = AssistantLinkView.compositeViewDescription;
if([LinphoneManager.instance lpConfigIntForKey:@"hide_link_phone_number"]){
_outgoingView = DialerView.compositeViewDescription;
}else{
_outgoingView = AssistantLinkView.compositeViewDescription;
}
[self configureAccount];
} else {
if (resp) {
@ -1212,6 +1269,7 @@ void assistant_create_account(LinphoneAccountCreator *creator, LinphoneAccountCr
AssistantView *thiz = (__bridge AssistantView *)(linphone_account_creator_get_user_data(creator));
thiz.waitView.hidden = YES;
if (status == LinphoneAccountCreatorStatusAccountCreated) {
[SVProgressHUD dismiss];
if (linphone_account_creator_get_phone_number(creator)) {
NSString* phoneNumber = [NSString stringWithUTF8String:linphone_account_creator_get_phone_number(creator)];
thiz.activationSMSText.text = [NSString stringWithFormat:NSLocalizedString(@"We have sent a SMS with a validation code to %@. To complete your phone number verification, please enter the 4 digit code below:", nil), phoneNumber];
@ -1231,6 +1289,7 @@ void assistant_recover_phone_account(LinphoneAccountCreator *creator, LinphoneAc
AssistantView *thiz = (__bridge AssistantView *)(linphone_account_creator_get_user_data(creator));
thiz.waitView.hidden = YES;
if (status == LinphoneAccountCreatorStatusRequestOk) {
[SVProgressHUD dismiss];
NSString* phoneNumber = [NSString stringWithUTF8String:linphone_account_creator_get_phone_number(creator)];
thiz.activationSMSText.text = [NSString stringWithFormat:NSLocalizedString(@"We have sent a SMS with a validation code to %@. To complete your phone number verification, please enter the 4 digit code below:", nil), phoneNumber];
[thiz changeView:thiz.createAccountActivateSMSView back:FALSE animation:TRUE];
@ -1258,6 +1317,24 @@ void assistant_activate_account(LinphoneAccountCreator *creator, LinphoneAccount
}
}
void assistant_request_auth_token_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status,
const char *resp) {
AssistantView *thiz = (__bridge AssistantView *)(linphone_account_creator_get_user_data(creator));
if (status == LinphoneAccountCreatorStatusMissingArguments) {
[thiz showErrorPopup:"ERROR_PUSH_UNAVAILABLE"];
} else if (status == LinphoneAccountCreatorStatusUnexpectedError) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Unknown error", nil)
message:NSLocalizedString(@"Failed to request an authentication token from account manager", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[thiz presentViewController:errView animated:YES completion:nil];
}
}
void assistant_login_linphone_account(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status,
const char *resp) {
AssistantView *thiz = (__bridge AssistantView *)(linphone_account_creator_get_user_data(creator));
@ -1285,7 +1362,12 @@ void assistant_is_account_activated(LinphoneAccountCreator *creator, LinphoneAcc
} else {
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
linphone_account_creator_set_language(creator, [[language substringToIndex:2] UTF8String]);
linphone_account_creator_recover_account(creator);
if (linphone_account_creator_get_token(creator)) {
linphone_account_creator_recover_account(creator);
} else {
[thiz requestAuthToken:TokenRequestAction_RecoverAccount];
}
}
} else {
// TODO : Re send email ?
@ -1424,39 +1506,108 @@ UIColor *previousColor = (UIColor*)[sender backgroundColor]; \
});
}
-(void)requestAuthToken:(TokenRequestAction)requestType {
const LinphonePushNotificationConfig * core_push_config = linphone_core_get_push_notification_config(LC);
linphone_account_creator_set_pn_provider(account_creator, PROVIDER_NAME);
//extract ".remote" from core pn_param which is of the form : VABCD1234.org.linphone.phone.voip&remote
NSString *formatedPnParam = [NSString stringWithUTF8String:linphone_push_notification_config_get_param(core_push_config)];
formatedPnParam = [formatedPnParam stringByReplacingOccurrencesOfString:@"voip&remote" withString:@"remote"];
linphone_account_creator_set_pn_param(account_creator, [formatedPnParam UTF8String]);
//extract REMOTETOKENID from core pn_prid which is of the form : VOIPTOKENID:voip&REMOTETOKENID:remote
const char* core_remote_token = linphone_push_notification_config_get_remote_token(core_push_config);
NSString *formatedRemoteToken=@"";
if (core_remote_token) {
formatedRemoteToken = [[NSString stringWithUTF8String:core_remote_token] substringToIndex:64];
linphone_account_creator_set_pn_prid(account_creator, [formatedRemoteToken UTF8String]);
} else {
LOGW(@"[Assistant] - No remote push token available in core for account creator configuration");
[self showErrorPopup:"ERROR_PUSH_UNAVAILABLE"];
return;
}
LOGI(@"[Assistant] Found push notification info: provider [%s], param [%@] and prid [%@]", PROVIDER_NAME, formatedPnParam, formatedRemoteToken);
LinphoneAccountCreatorStatus requestStatus = linphone_account_creator_request_auth_token(account_creator);
if (requestStatus == LinphoneAccountCreatorStatusRequestOk) {
[SVProgressHUD show];
tokenRequestAction = requestType;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (tokenRequestAction == requestType) {
tokenRequestAction = TokenRequestAction_None;
[self showErrorPopup:"ERROR_AUTH_TOKEN_NOT_RECEIVED"];
[SVProgressHUD dismiss];
}
});
} else {
[self showErrorPopup:"ERROR_PUSH_UNAVAILABLE"];
}
}
- (IBAction)onCreateAccountClick:(id)sender {
if ([self checkFields]) {
ONCLICKBUTTON(sender, 100, {
_activationTitle.text = @"CREATE ACCOUNT";
_waitView.hidden = NO;
linphone_account_creator_is_account_exist(account_creator);
UIAssistantTextField *createUsername = [self findTextField:ViewElement_Username];
if ([createUsername.text length] == 0) {
linphone_account_creator_set_username(account_creator, linphone_account_creator_get_phone_number(account_creator));
}
if (linphone_account_creator_get_token(account_creator)) {
linphone_account_creator_is_account_exist(account_creator);
} else {
[self requestAuthToken:TokenRequestAction_CreateAccount];
}
});
}
}
- (IBAction)onCreateAccountActivationClick:(id)sender {
ONCLICKBUTTON(sender, 100, {
[self debugtest];
/*
_waitView.hidden = NO;
linphone_account_creator_set_activation_code(
account_creator,
((UITextField *)[self findView:ViewElement_SMSCode inView:_contentView ofType:UITextField.class])
.text.UTF8String);
if (linphone_account_creator_get_password(account_creator) == NULL &&
linphone_account_creator_get_ha1(account_creator) == NULL) {
if ([_activationTitle.text isEqualToString:@"USE LINPHONE ACCOUNT"]) {
linphone_account_creator_login_linphone_account(account_creator);
} else {
linphone_account_creator_activate_account(account_creator);
}
if ([_activationTitle.text isEqualToString:@"USE LINPHONE ACCOUNT"]) {
linphone_account_creator_login_linphone_account(account_creator);
} else {
linphone_account_creator_activate_account(account_creator);
} *//* else {
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
linphone_account_creator_set_language(account_creator, [[language substringToIndex:2] UTF8String]);
linphone_account_creator_link_account(account_creator);
linphone_account_creator_activate_alias(account_creator);
}
} */
});
}
-(void) debugtest{
_waitView.hidden = NO;
linphone_account_creator_set_activation_code(
account_creator,
((UITextField *)[self findView:ViewElement_SMSCode inView:_contentView ofType:UITextField.class])
.text.UTF8String);
if ([_activationTitle.text isEqualToString:@"USE LINPHONE ACCOUNT"]) {
linphone_account_creator_login_linphone_account(account_creator);
} else {
linphone_account_creator_activate_account(account_creator);
} /* else {
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
linphone_account_creator_set_language(account_creator, [[language substringToIndex:2] UTF8String]);
linphone_account_creator_link_account(account_creator);
linphone_account_creator_activate_alias(account_creator);
} */
}
- (IBAction)onCreateAccountCheckActivatedClick:(id)sender {
ONCLICKBUTTON(sender, 100, {
_waitView.hidden = NO;
@ -1488,7 +1639,13 @@ UIColor *previousColor = (UIColor*)[sender backgroundColor]; \
linphone_account_creator_get_ha1(account_creator) == NULL) {
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
linphone_account_creator_set_language(account_creator, [[language substringToIndex:2] UTF8String]);
linphone_account_creator_recover_account(account_creator);
linphone_account_creator_set_username(account_creator, linphone_account_creator_get_phone_number(account_creator));
if (linphone_account_creator_get_token(account_creator)) {
linphone_account_creator_recover_account(account_creator);
} else {
[self requestAuthToken:TokenRequestAction_RecoverAccount];
}
} else {
// check if account is already linked with a phone number.
// if not, propose it to the user
@ -1568,7 +1725,6 @@ UIColor *previousColor = (UIColor*)[sender backgroundColor]; \
- (IBAction)onRemoteProvisioningLoginClick:(id)sender {
ONCLICKBUTTON(sender, 100, {
_waitView.hidden = NO;
[LinphoneManager.instance lpConfigSetInt:1 forKey:@"transient_provisioning" inSection:@"misc"];
[self configureAccount];
});
}
@ -1584,10 +1740,11 @@ UIColor *previousColor = (UIColor*)[sender backgroundColor]; \
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[self presentViewController:errView animated:YES completion:nil];
_waitView.hidden = TRUE;
} else {
linphone_core_set_provisioning_uri(LC, [self addSchemeToProvisiionninUriIMissing:[self findTextField:ViewElement_URL].text].UTF8String);
[self resetLiblinphone:TRUE];
@ -1772,7 +1929,7 @@ UIColor *previousColor = (UIColor*)[sender backgroundColor]; \
- (IBAction)onLinkTap:(id)sender {
NSString *url = @"https://subscribe.linphone.org";
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
LOGE(@"[Assistant] Failed to open %@, invalid URL", url);
}
}

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -175,13 +175,13 @@
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KRQ-Fm-3cQ" userLabel="addedContacts" customClass="UICollectionView">
<rect key="frame" x="8" y="110" width="398" height="70"/>
<rect key="frame" x="8" y="110" width="398" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<accessibility key="accessibilityConfiguration" label="addedContacts"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="5" y="178" width="403" height="610"/>
<rect key="frame" x="5" y="158" width="403" height="610"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -97,7 +97,7 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XSI-9T-NtW" userLabel="addButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="382" y="4" width="24" height="21"/>
<rect key="frame" x="382" y="2" width="24" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>

View file

@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ChatConversationView">
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ChatConversationViewSwift">
<connections>
<outlet property="addressLabel" destination="40" id="43"/>
<outlet property="backButton" destination="9" id="Jcb-ET-bKd"/>
@ -50,19 +49,19 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="v2I-ka-LYa" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="0.0" y="42" width="414" height="788"/>
<rect key="frame" x="-1" y="41" width="393" height="744"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="77" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -77,7 +76,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="11" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bci-3K-AcG" userLabel="cancelButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="77" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -92,7 +91,7 @@
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="Contact1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="40" userLabel="addressLabel">
<rect key="frame" x="75" y="0.0" width="160" height="44"/>
<rect key="frame" x="75" y="0.0" width="149" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
@ -102,7 +101,7 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wzg-i0-spp" userLabel="callButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="248" y="0.0" width="83" height="66"/>
<rect key="frame" x="234" y="0.0" width="79" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<state key="normal" image="call_alt_start_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -114,7 +113,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="7" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hc0-GX-fC5" userLabel="backToCallButton" customClass="UIBackToCallButton">
<rect key="frame" x="248" y="0.0" width="83" height="66"/>
<rect key="frame" x="234" y="0.0" width="79" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<state key="normal" image="call_back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -127,7 +126,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="8" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wag-Nx-kd6" userLabel="deleteButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<rect key="frame" x="313" y="0.0" width="80" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -141,7 +140,7 @@
</connections>
</button>
<button opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FqM-Ud-i58" userLabel="editButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<rect key="frame" x="313" y="0.0" width="80" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -156,7 +155,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="4697" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CPn-Oc-9PX" userLabel="toggleMenuButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<rect key="frame" x="313" y="0.0" width="80" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -169,7 +168,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c9z-aq-2UP" userLabel="toggleSelectionButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="248" y="0.0" width="83" height="66"/>
<rect key="frame" x="234" y="0.0" width="79" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -185,7 +184,7 @@
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="addresses" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ncq-Zc-X6j" userLabel="participantsLabel">
<rect key="frame" x="75" y="36" width="160" height="25"/>
<rect key="frame" x="75" y="35" width="149" height="25"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
@ -198,11 +197,11 @@
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view tag="12" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="49" userLabel="contentView">
<rect key="frame" x="0.0" y="66" width="414" height="722"/>
<rect key="frame" x="0.0" y="65" width="393" height="679"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<tableView clipsSubviews="YES" tag="13" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="60" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="8" userLabel="messagesTableView">
<rect key="frame" x="0.0" y="0.0" width="414" height="574"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="529"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
@ -214,11 +213,11 @@
</connections>
</tableView>
<view hidden="YES" tag="14" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fx4-ao-53M" userLabel="composeIndicatorView">
<rect key="frame" x="0.0" y="574" width="414" height="22"/>
<rect key="frame" x="0.0" y="529" width="393" height="23"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="15" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="%@ is composing..." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="fpY-Fv-ht2" userLabel="composeLabel">
<rect key="frame" x="0.0" y="1" width="414" height="22"/>
<rect key="frame" x="10" y="-5" width="385" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label=""/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -229,7 +228,7 @@
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="16" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No conversation." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p7C-WH-uR1" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="0.0" width="414" height="574"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="539"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -237,11 +236,11 @@
<nil key="highlightedColor"/>
</label>
<view alpha="0.90000000000000002" tag="17" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="14" userLabel="messageView">
<rect key="frame" x="0.0" y="656" width="414" height="66"/>
<rect key="frame" x="0.0" y="612" width="393" height="67"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" tag="19" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="73" userLabel="pictureButton">
<rect key="frame" x="0.0" y="0.0" width="66" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="66" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send picture"/>
<state key="normal" image="chat_attachment_default.png">
@ -254,7 +253,7 @@
</connections>
</button>
<button opaque="NO" tag="9019" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aTi-pm-fAG" userLabel="audioRecordingButton">
<rect key="frame" x="66" y="0.0" width="56" height="66"/>
<rect key="frame" x="66" y="0.0" width="56" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send picture"/>
<inset key="imageEdgeInsets" minX="15" minY="20" maxX="15" maxY="20"/>
@ -267,7 +266,7 @@
</connections>
</button>
<button opaque="NO" tag="21" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="15" userLabel="sendButton">
<rect key="frame" x="349" y="0.0" width="66" height="66"/>
<rect key="frame" x="328" y="0.0" width="65" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send"/>
<inset key="titleEdgeInsets" minX="0.0" minY="30" maxX="0.0" maxY="0.0"/>
@ -281,24 +280,24 @@
</connections>
</button>
<view tag="20" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pqa-tg-5ml" userLabel="messageField" customClass="HPGrowingTextView">
<rect key="frame" x="130" y="13" width="208" height="40"/>
<rect key="frame" x="123" y="11" width="197" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<accessibility key="accessibilityConfiguration" label="Message field"/>
</view>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" tag="44536" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="ephemeral_messages_color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="LN7-ci-kNn" userLabel="ephemeralIndicator">
<rect key="frame" x="393" y="44" width="15" height="15"/>
<rect key="frame" x="372" y="44" width="14" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view hidden="YES" tag="28021" contentMode="scaleToFill" id="Tru-Zm-4EZ" userLabel="VoiceRecording">
<rect key="frame" x="0.0" y="596" width="414" height="60"/>
<rect key="frame" x="0.0" y="596" width="393" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<subviews>
<button opaque="NO" tag="28022" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wi9-en-JCZ">
<rect key="frame" x="12" y="13" width="24" height="34"/>
<rect key="frame" x="12" y="12" width="24" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="delete_default.png"/>
<connections>
@ -306,26 +305,26 @@
</connections>
</button>
<view tag="28023" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eXD-Gd-FXA">
<rect key="frame" x="50" y="8" width="302" height="44"/>
<rect key="frame" x="50" y="7" width="280" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="28024" contentMode="scaleToFill" id="OTf-Od-TDn" userLabel="vr_wave_mask_playback">
<rect key="frame" x="0.0" y="0.0" width="240" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="217" height="43"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.93333333330000001" green="0.93333333330000001" blue="0.93333333330000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="tintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="28025" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="vr_wave.png" translatesAutoresizingMaskIntoConstraints="NO" id="m9m-2e-T7E">
<rect key="frame" x="8" y="8" width="232" height="28"/>
<rect key="frame" x="7" y="8" width="210" height="27"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<view tag="28026" contentMode="scaleToFill" id="TzM-ND-yp4" userLabel="vr_wave_mask_record">
<rect key="frame" x="0.0" y="0.0" width="240" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="217" height="43"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" tag="28027" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dMW-Ix-4k0">
<rect key="frame" x="245" y="12" width="49" height="21"/>
<rect key="frame" x="222" y="12" width="48" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<nil key="textColor"/>
@ -335,7 +334,7 @@
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<button opaque="NO" tag="28028" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FNM-bb-AlC">
<rect key="frame" x="366" y="13" width="35" height="35"/>
<rect key="frame" x="343" y="12" width="37" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="vr_play.png"/>
<connections>
@ -346,11 +345,11 @@
<color key="backgroundColor" red="0.93333333330000001" green="0.93333333330000001" blue="0.93333333330000001" alpha="1" colorSpace="calibratedRGB"/>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3qd-ys-t2L" userLabel="imagesView">
<rect key="frame" x="0.0" y="625" width="414" height="0.0"/>
<rect key="frame" x="0.0" y="587" width="393" height="0.0"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" showsVerticalScrollIndicator="NO" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="JGQ-p2-HCX" userLabel="imagesCollectionView">
<rect key="frame" x="2" y="0.0" width="413" height="0.0"/>
<rect key="frame" x="2" y="0.0" width="391" height="0.0"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.98780487804878048" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="c7z-F2-r1y">
@ -364,7 +363,7 @@
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tjL-Vc-5gN" userLabel="encryptedButton">
<rect key="frame" x="359" y="10" width="34" height="40"/>
<rect key="frame" x="372" y="8" width="34" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_1_indicator.png"/>
<connections>
@ -372,7 +371,7 @@
</connections>
</button>
<view hidden="YES" tag="290392" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wve-MK-7ME" userLabel="ReplyView">
<rect key="frame" x="0.0" y="536" width="414" height="120"/>
<rect key="frame" x="0.0" y="536" width="393" height="120"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
@ -380,7 +379,7 @@
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<tableView hidden="YES" clipsSubviews="YES" tag="6992" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="gdT-1Q-vU2" userLabel="popupMenu">
<rect key="frame" x="142" y="66" width="273" height="132"/>
<rect key="frame" x="121" y="66" width="272" height="132"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</tableView>
@ -393,23 +392,23 @@
<point key="canvasLocation" x="365.21739130434787" y="-36.830357142857139"/>
</view>
<view contentMode="scaleToFill" id="680-UL-sil" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VoU-7Q-fgp">
<rect key="frame" x="90" y="42" width="324" height="854"/>
<rect key="frame" x="90" y="42" width="303" height="810"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Z3y-hY-5xp" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="324" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="303" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="Uvs-m3-GPj" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="324" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="303" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N2g-vL-3x8" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="37" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="34" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -424,7 +423,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="11" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Bqf-Gg-2Rw" userLabel="cancelButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="37" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="34" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -449,7 +448,7 @@
<nil key="highlightedColor"/>
</label>
<button hidden="YES" opaque="NO" tag="8" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RDW-7W-25T" userLabel="deleteButton" customClass="UIIconButton">
<rect key="frame" x="285" y="0.0" width="39" height="66"/>
<rect key="frame" x="264" y="0.0" width="39" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -463,7 +462,7 @@
</connections>
</button>
<button opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KeL-Ej-92j" userLabel="editButton" customClass="UIIconButton">
<rect key="frame" x="285" y="0.0" width="39" height="66"/>
<rect key="frame" x="264" y="0.0" width="39" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -478,7 +477,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="4697" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pQX-Ll-9wL" userLabel="toggleMenuButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="285" y="0.0" width="39" height="66"/>
<rect key="frame" x="264" y="0.0" width="39" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -491,7 +490,7 @@
</connections>
</button>
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wag-QV-oUD" userLabel="callButton" customClass="UIIconButton">
<rect key="frame" x="248" y="0.0" width="37" height="66"/>
<rect key="frame" x="230" y="0.0" width="34" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<state key="normal" image="call_alt_start_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -503,7 +502,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="7" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="t25-en-4LP" userLabel="backToCallButton" customClass="UIBackToCallButton">
<rect key="frame" x="248" y="0.0" width="37" height="66"/>
<rect key="frame" x="230" y="0.0" width="34" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<state key="normal" image="call_back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -515,7 +514,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4RV-US-Kr1" userLabel="toggleSelectionButton" customClass="UIIconButton">
<rect key="frame" x="248" y="0.0" width="37" height="66"/>
<rect key="frame" x="230" y="0.0" width="34" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -531,7 +530,7 @@
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="addresses" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="tyU-Wy-rLs" userLabel="participantsLabel">
<rect key="frame" x="67" y="37" width="366" height="25"/>
<rect key="frame" x="67" y="36" width="366" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
@ -543,11 +542,11 @@
</subviews>
</view>
<view tag="12" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OTt-fc-941" userLabel="contentView">
<rect key="frame" x="0.0" y="66" width="324" height="788"/>
<rect key="frame" x="0.0" y="66" width="303" height="744"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<tableView clipsSubviews="YES" tag="13" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="60" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="CU7-Za-RwN" userLabel="messagesTableView">
<rect key="frame" x="0.0" y="0.0" width="324" height="700"/>
<rect key="frame" x="0.0" y="0.0" width="303" height="657"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
@ -557,7 +556,7 @@
</connections>
</tableView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="16" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No conversation." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pzm-tk-LH0" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="0.0" width="324" height="617"/>
<rect key="frame" x="0.0" y="0.0" width="303" height="582"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -565,11 +564,11 @@
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="14" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nTf-7h-Z4z" userLabel="composeIndicatorView">
<rect key="frame" x="0.0" y="700" width="324" height="22"/>
<rect key="frame" x="0.0" y="657" width="303" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="15" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="%@ is composing..." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="I34-aL-yuS" userLabel="composeLabel">
<rect key="frame" x="0.0" y="0.0" width="324" height="22"/>
<rect key="frame" x="0.0" y="0.0" width="303" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label=""/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -579,11 +578,11 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view tag="17" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LA5-wD-ftj" userLabel="messageView">
<rect key="frame" x="0.0" y="722" width="324" height="66"/>
<rect key="frame" x="0.0" y="678" width="303" height="67"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="18" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="kKc-DG-gwg" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="324" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="303" height="67"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" tag="19" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gSL-jE-GYO" userLabel="pictureButton">
@ -608,18 +607,17 @@
</state>
<state key="selected" image="vr_on.png"/>
<connections>
<action selector="onPictureClick:" destination="-1" eventType="touchUpInside" id="qhP-B0-dkG"/>
<action selector="onVrStart:" destination="-1" eventType="touchUpInside" id="yWJ-st-yz2"/>
</connections>
</button>
<view tag="20" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C02-2r-vXK" userLabel="messageField" customClass="HPGrowingTextView">
<rect key="frame" x="59" y="13" width="230" height="40"/>
<rect key="frame" x="53" y="12" width="215" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Message field"/>
</view>
<button opaque="NO" tag="21" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nV9-xZ-oSM" userLabel="sendButton">
<rect key="frame" x="258" y="0.0" width="66" height="66"/>
<rect key="frame" x="236" y="0.0" width="67" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send"/>
<inset key="titleEdgeInsets" minX="0.0" minY="30" maxX="0.0" maxY="0.0"/>
@ -633,7 +631,7 @@
</connections>
</button>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" tag="44536" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="ephemeral_messages_color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="Gsu-3J-HRp" userLabel="ephemeralIndicator">
<rect key="frame" x="305" y="40" width="15" height="15"/>
<rect key="frame" x="284" y="41" width="13" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
</subviews>
@ -641,7 +639,7 @@
</subviews>
</view>
<tableView hidden="YES" clipsSubviews="YES" tag="6992" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="iwm-pi-mku" userLabel="popupMenu">
<rect key="frame" x="13" y="66" width="311" height="132"/>
<rect key="frame" x="-10" y="66" width="313" height="132"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</tableView>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -210,6 +210,7 @@
<outlet property="toggleSelectionButton" destination="uqG-2T-VOa" id="ytx-bj-7Qr"/>
<outlet property="view" destination="6" id="13"/>
</connections>
<point key="canvasLocation" x="460" y="-11"/>
</tableViewController>
</objects>
<resources>
@ -217,7 +218,7 @@
<image name="call_back_disabled.png" width="61.599998474121094" height="44"/>
<image name="cancel_edit_default.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="cancel_edit_disabled.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="cancel_forward.png" width="80" height="80"/>
<image name="cancel_forward.png" width="29" height="29"/>
<image name="chat_add_default.png" width="50.400001525878906" height="44.799999237060547"/>
<image name="chat_add_group.png" width="64" height="42.400001525878906"/>
<image name="color_E.png" width="2" height="2"/>

View file

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -16,6 +19,7 @@
<outlet property="emptyLabel" destination="Mdj-Pz-nu4" id="ijc-2c-waE"/>
<outlet property="landscapeView" destination="lgD-Mw-h57" id="DTS-80-rMM"/>
<outlet property="nameLabel" destination="moZ-Bg-zcv" id="Lt9-h0-2o1"/>
<outlet property="organizationLabel" destination="pAA-jk-E4s" id="J0M-Ms-5dp"/>
<outlet property="portraitView" destination="1" id="k69-5P-ieM"/>
<outlet property="tableController" destination="20" id="27"/>
<outlet property="view" destination="1" id="3"/>
@ -24,19 +28,19 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="XnN-PU-Vk7" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<rect key="frame" x="0.0" y="42" width="393" height="744"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button hidden="YES" opaque="NO" tag="3" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bPQ-aJ-Lk6" userLabel="cancelButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="79" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -50,7 +54,7 @@
</connections>
</button>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="79" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -66,7 +70,7 @@
</connections>
</button>
<button opaque="NO" tag="5" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MuB-yy-R9o" userLabel="deleteButton" customClass="UIInterfaceStyleToggleButton">
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
<rect key="frame" x="236" y="0.0" width="78" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -82,7 +86,7 @@
</connections>
</button>
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8" userLabel="editButton" customClass="UIInterfaceStyleToggleButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<rect key="frame" x="314" y="0.0" width="79" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -99,30 +103,37 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="7" contentMode="scaleToFill" fixedFrame="YES" directionalLockEnabled="YES" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8D6-vy-obt" userLabel="contentView">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<rect key="frame" x="0.0" y="66" width="393" height="678"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="B6X-C9-2vm" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="142" y="10" width="90" height="90"/>
<imageView tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="B6X-C9-2vm" userLabel="avatarImage">
<rect key="frame" x="150" y="10" width="90" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<connections>
<outletCollection property="gestureRecognizers" destination="8bV-f4-pLL" appends="YES" id="4V5-Px-aHT"/>
</connections>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="9" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="John Doe" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="moZ-Bg-zcv" userLabel="nameLabel">
<rect key="frame" x="0.0" y="108" width="375" height="40"/>
<label opaque="NO" userInteractionEnabled="NO" tag="9" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="John Doe" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="moZ-Bg-zcv" userLabel="nameLabel" customClass="CopyableLabel" customModule="linphoneapp" customModuleProvider="target">
<rect key="frame" x="0.0" y="108" width="393" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="27"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Organization" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pAA-jk-E4s" userLabel="organizationLabel">
<rect key="frame" x="0.0" y="148" width="393" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<tableView clipsSubviews="YES" tag="10" contentMode="scaleToFill" fixedFrame="YES" directionalLockEnabled="YES" alwaysBounceVertical="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" style="plain" allowsSelection="NO" allowsSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="1" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="19" userLabel="tableView">
<rect key="frame" x="0.0" y="156" width="375" height="337"/>
<rect key="frame" x="0.0" y="176" width="393" height="502"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<connections>
<outlet property="dataSource" destination="20" id="28"/>
@ -130,26 +141,26 @@
</connections>
</tableView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</scrollView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="40" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No contact selected" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mdj-Pz-nu4" userLabel="emptyLabel">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<rect key="frame" x="0.0" y="66" width="393" height="678"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JK8-Td-I1i" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="375" height="559"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="744"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="J67-KE-kHm" userLabel="activityIndicatorView">
<rect key="frame" x="179" y="267" width="20" height="20"/>
<rect key="frame" x="188" y="358" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
</view>
</subviews>
@ -244,7 +255,7 @@
<rect key="frame" x="0.0" y="66" width="667" height="267"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<subviews>
<imageView tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="IJJ-eZ-rC2" userLabel="avatarImage" customClass="UIRoundedImageView">
<imageView tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="IJJ-eZ-rC2" userLabel="avatarImage">
<rect key="frame" x="46" y="8" width="62" height="62"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
@ -321,5 +332,11 @@
<image name="edit_default.png" width="46.400001525878906" height="46.400001525878906"/>
<image name="edit_disabled.png" width="46.400001525878906" height="46.400001525878906"/>
<image name="valid_default.png" width="44.799999237060547" height="30.399999618530273"/>
<systemColor name="secondarySystemBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -12,11 +12,14 @@
<connections>
<outlet property="addButton" destination="6" id="91"/>
<outlet property="allButton" destination="4" id="27"/>
<outlet property="deleteButton" destination="DZc-zR-1Q7" id="M6N-vO-UIb"/>
<outlet property="ldapMoreResultsLabel" destination="cDH-mL-cHP" id="3d9-gp-Hog"/>
<outlet property="linphoneButton" destination="5" id="31"/>
<outlet property="loadingLabel" destination="qSa-Ba-dq9" id="CPa-pO-OQD"/>
<outlet property="loadingView" destination="CM2-Aq-Q3g" id="uie-SJ-TKf"/>
<outlet property="searchBar" destination="5jE-oF-d45" id="xfS-xo-2Bm"/>
<outlet property="selectedButtonImage" destination="A9k-KU-Dlm" id="4dX-pd-Y2D"/>
<outlet property="switchView" destination="93" id="4iM-Fl-F9B"/>
<outlet property="tableController" destination="TJG-JZ-YRR" id="0lt-gC-EOm"/>
<outlet property="toggleSelectionButton" destination="5lZ-u7-Yex" id="ULR-WM-Yuo"/>
<outlet property="topBar" destination="3" id="w1O-2o-b18"/>
@ -179,6 +182,14 @@
<outlet property="delegate" destination="TJG-JZ-YRR" id="V1N-gI-U4J"/>
</connections>
</tableView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="More results are available, refine search to see them" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cDH-mL-cHP" userLabel="ldapMoreResultsLabel">
<rect key="frame" x="8" y="110" width="359" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No contact found in your address book" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JR3-k7-gVP" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="110" width="375" height="449"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
@ -187,7 +198,7 @@
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" contentMode="scaleToFill" id="CM2-Aq-Q3g">
<view hidden="YES" alpha="0.80000000000000004" contentMode="scaleToFill" id="CM2-Aq-Q3g">
<rect key="frame" x="0.0" y="110" width="375" height="449"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
@ -209,7 +220,7 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="6.5217391304347831" y="142.29910714285714"/>
<point key="canvasLocation" x="5.7971014492753632" y="141.96428571428569"/>
</view>
<tableViewController id="TJG-JZ-YRR" userLabel="tableController" customClass="ContactsListTableView">
<connections>

View file

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_0" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -11,6 +14,7 @@
<outlet property="addressLabel" destination="EoB-ux-sD7" id="Ajw-2s-M6X"/>
<outlet property="avatarImage" destination="23" id="43"/>
<outlet property="backButton" destination="9" id="Pqj-y9-hqc"/>
<outlet property="chatButton" destination="obZ-W7-q8P" id="96n-Oe-Gm0"/>
<outlet property="contactLabel" destination="25" id="rTL-Ut-42o"/>
<outlet property="emptyLabel" destination="hvz-CS-NME" id="Qws-r1-XMh"/>
<outlet property="encryptedChatView" destination="JU4-bf-tVI" id="j6f-qz-VKd"/>
@ -26,19 +30,19 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="HKr-sq-hGv" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
<rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
<rect key="frame" x="0.0" y="42" width="667" height="267"/>
<rect key="frame" x="-1" y="41" width="389" height="735"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="389" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="128" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="74" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -50,7 +54,7 @@
</connections>
</button>
<button opaque="NO" tag="5" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="50" userLabel="addButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="539" y="0.0" width="128" height="66"/>
<rect key="frame" x="314" y="0.0" width="75" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -62,22 +66,22 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view tag="7" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="33" userLabel="headerView">
<rect key="frame" x="0.0" y="66" width="667" height="250"/>
<rect key="frame" x="0.0" y="66" width="389" height="250"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="23" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="244" y="8" width="178" height="100"/>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="23" userLabel="avatarImage">
<rect key="frame" x="141" y="8" width="104" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="9" contentMode="left" fixedFrame="YES" text="John Doe" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="25" userLabel="contactLabel">
<rect key="frame" x="0.0" y="110" width="667" height="40"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="9" contentMode="left" fixedFrame="YES" text="John Doe" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="25" userLabel="contactLabel" customClass="CopyableLabel" customModule="linphoneapp" customModuleProvider="target">
<rect key="frame" x="0.0" y="110" width="389" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
@ -85,15 +89,15 @@
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" tag="10" contentMode="scaleAspectFit" fixedFrame="YES" image="linphone_user.png" translatesAutoresizingMaskIntoConstraints="NO" id="mfN-Ai-9RX" userLabel="linphoneImage" customClass="UIRoundedImageView">
<rect key="frame" x="642" y="124" width="15" height="15"/>
<rect key="frame" x="363" y="124" width="16" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="11" contentMode="left" fixedFrame="YES" text="johndoe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="EoB-ux-sD7" userLabel="addressLabel">
<rect key="frame" x="0.0" y="158" width="667" height="23"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="11" contentMode="left" fixedFrame="YES" text="johndoe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="EoB-ux-sD7" userLabel="addressLabel" customClass="CopyableLabel" customModule="linphoneapp" customModuleProvider="target">
<rect key="frame" x="0.0" y="158" width="389" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
@ -101,11 +105,11 @@
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="k0D-99-OKO" userLabel="optionsView">
<rect key="frame" x="0.0" y="189" width="667" height="44"/>
<rect key="frame" x="0.0" y="189" width="389" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="13" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5eX-W0-T4B" userLabel="callButton">
<rect key="frame" x="179" y="0.0" width="51" height="51"/>
<rect key="frame" x="98" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -117,7 +121,7 @@
</connections>
</button>
<button opaque="NO" tag="12" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="obZ-W7-q8P" userLabel="chatButton">
<rect key="frame" x="317" y="0.0" width="50" height="51"/>
<rect key="frame" x="174" y="0.0" width="50" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -129,11 +133,11 @@
</connections>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JU4-bf-tVI" userLabel="encryptedChatView">
<rect key="frame" x="456" y="-1" width="50" height="51"/>
<rect key="frame" x="251" y="-2" width="49" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="E2n-mF-saI" userLabel="encryptedChatButton" customClass="UIIconButton">
<rect key="frame" x="-1" y="0.0" width="51" height="51"/>
<rect key="frame" x="0.0" y="-2" width="51" height="53"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
@ -154,35 +158,35 @@
</subviews>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<tableView clipsSubviews="YES" tag="6" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="30" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="k6N-Av-eOu">
<rect key="frame" x="0.0" y="316" width="667" height="0.0"/>
<rect key="frame" x="0.0" y="316" width="389" height="419"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<connections>
<outlet property="dataSource" destination="baU-d4-eu3" id="p7o-Mx-Kmc"/>
<outlet property="delegate" destination="baU-d4-eu3" id="iS5-xg-0C2"/>
</connections>
</tableView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="40" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No log selected" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hvz-CS-NME" userLabel="emptyLabel">
<rect key="frame" x="0.0" y="66" width="667" height="201"/>
<rect key="frame" x="0.0" y="65" width="389" height="670"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dEJ-xc-518" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="667" height="267"/>
<rect key="frame" x="0.0" y="0.0" width="389" height="735"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="NK3-ME-9jd" userLabel="activityIndicatorView">
<rect key="frame" x="326" y="122" width="20" height="20"/>
<rect key="frame" x="186" y="352" width="20" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
</view>
</subviews>
@ -193,23 +197,23 @@
<point key="canvasLocation" x="-3.2000000000000002" y="22.488755622188908"/>
</view>
<view contentMode="scaleToFill" id="LBc-mh-ozk" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
<rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NHC-7w-48z">
<rect key="frame" x="0.0" y="42" width="667" height="333"/>
<rect key="frame" x="-2" y="42" width="391" height="800"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Rtv-hu-bCz" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="391" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="imageView:JOe-5t-C7f:image" translatesAutoresizingMaskIntoConstraints="NO" id="JOe-5t-C7f" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="391" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NJl-Lb-CU6" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="71" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="41" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -221,7 +225,7 @@
</connections>
</button>
<button opaque="NO" tag="5" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="O7r-6t-b7w" userLabel="addButton" customClass="UIIconButton">
<rect key="frame" x="594" y="0.0" width="73" height="66"/>
<rect key="frame" x="346" y="0.0" width="45" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -235,7 +239,7 @@
</subviews>
</view>
<tableView clipsSubviews="YES" tag="6" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="30" sectionHeaderHeight="44" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="2jK-gw-ULv">
<rect key="frame" x="0.0" y="168" width="667" height="165"/>
<rect key="frame" x="0.0" y="167" width="391" height="633"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
@ -244,11 +248,11 @@
</connections>
</tableView>
<view tag="7" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Mwp-y3-g1b" userLabel="headerView">
<rect key="frame" x="0.0" y="66" width="667" height="102"/>
<rect key="frame" x="0.0" y="66" width="391" height="102"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="d9m-G0-1u3" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="28" y="8" width="88" height="86"/>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="d9m-G0-1u3" userLabel="avatarImage">
<rect key="frame" x="16" y="8" width="51" height="86"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
@ -256,7 +260,7 @@
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="9" contentMode="left" fixedFrame="YES" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Qbg-hm-bd7" userLabel="contactLabel">
<rect key="frame" x="160" y="8" width="356" height="50"/>
<rect key="frame" x="94" y="8" width="207" height="48"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
@ -264,7 +268,7 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="11" contentMode="left" fixedFrame="YES" text="johndoe@sip.linphone.org" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="XJa-f6-K0y" userLabel="addressLabel">
<rect key="frame" x="160" y="56" width="356" height="38"/>
<rect key="frame" x="94" y="54" width="207" height="39"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
@ -272,11 +276,11 @@
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="teU-AB-8hO" userLabel="optionsView">
<rect key="frame" x="0.0" y="29" width="667" height="44"/>
<rect key="frame" x="0.0" y="29" width="391" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="13" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pBo-Oo-bAW" userLabel="callButton">
<rect key="frame" x="491" y="0.0" width="51" height="51"/>
<rect key="frame" x="271" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -288,7 +292,7 @@
</connections>
</button>
<button opaque="NO" tag="12" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iDG-Mn-jm2" userLabel="chatButton">
<rect key="frame" x="551" y="0.0" width="51" height="51"/>
<rect key="frame" x="303" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -300,11 +304,11 @@
</connections>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="m90-u6-x3J" userLabel="encryptedChatView">
<rect key="frame" x="611" y="0.0" width="51" height="51"/>
<rect key="frame" x="336" y="-1" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8fY-hz-ECC" userLabel="encryptedChatButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="51" height="51"/>
<rect key="frame" x="0.0" y="-2" width="51" height="53"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
@ -325,7 +329,7 @@
</subviews>
</view>
<imageView hidden="YES" userInteractionEnabled="NO" tag="10" contentMode="scaleAspectFit" fixedFrame="YES" image="linphone_user.png" translatesAutoresizingMaskIntoConstraints="NO" id="G2O-Yh-fZA" userLabel="linphoneImage">
<rect key="frame" x="123" y="8" width="30" height="25"/>
<rect key="frame" x="71" y="8" width="19" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
@ -336,7 +340,7 @@
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="40" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No log selected" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IHY-Yg-pkN" userLabel="emptyLabel">
<rect key="frame" x="0.0" y="66" width="667" height="267"/>
<rect key="frame" x="0.0" y="65" width="391" height="735"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -344,11 +348,11 @@
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X29-vB-VIz" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="667" height="333"/>
<rect key="frame" x="0.0" y="0.0" width="391" height="800"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="7l5-ZU-CbW" userLabel="activityIndicatorView">
<rect key="frame" x="326" y="155" width="20" height="20"/>
<rect key="frame" x="185" y="385" width="21" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
@ -384,106 +388,113 @@
<image name="contact_add_disabled.png" width="55.200000762939453" height="47.200000762939453"/>
<image name="imageView:JOe-5t-C7f:image" width="2" height="2">
<mutableData key="keyedArchiveRepresentation">
YnBsaXN0MDDUAQIDBAUGUlNYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK8QEQcI
ERYbHCAhKCsuOEBESExPVSRudWxs1AkKCwwNDg8QViRjbGFzc1xOU0ltYWdlRmxhZ3NWTlNSZXBzV05T
Q29sb3KAEBIAwAAAgAKACtISCRMVWk5TLm9iamVjdHOhFIADgAnSEgkXGqIYGYAEgAWACBAA0h0JHh9f
EBROU1RJRkZSZXByZXNlbnRhdGlvboAGgAdPEQI+TU0AKgAAAAzh4eHhAA8BAAADAAAAAQACAAABAQAD
AAAAAQACAAABAgADAAAAAQAIAAABAwADAAAAAQABAAABBgADAAAAAQABAAABCgADAAAAAQABAAABEQAE
AAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQABAAABFgADAAAAAQACAAABFwAEAAAAAQAAAAQBHAAD
AAAAAQABAAABKAADAAAAAQACAAABUwADAAAAAQABAACHcwAHAAABeAAAAMYAAAAAAAABeGFwcGwCEAAA
bW50ckdSQVlYWVogB9UABwABAAAAAAAAYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbW
AAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE
ZGVzYwAAALQAAAB1Y3BydAAAASwAAAAnd3RwdAAAAVQAAAAUa1RSQwAAAWgAAAAOZGVzYwAAAAAAAAAb
Q2FsaWJyYXRlZCBHcmF5IENvbG9yc3BhY2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdGV4dAAAAABDb3B5
cmlnaHQgQXBwbGUgQ29tcHV0ZXIsIEluYy4AAFhZWiAAAAAAAADzUQABAAAAARbMY3VydgAAAAAAAAAB
AjMAANIiIyQlWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBOU0JpdG1hcEltYWdlUmVwoyQmJ1pOU0ltYWdl
UmVwWE5TT2JqZWN00iIjKSpXTlNBcnJheaIpJ9IiIywtXk5TTXV0YWJsZUFycmF5oywpJ9UvMDEyCTM0
NTY3V05TV2hpdGVcTlNDb21wb25lbnRzXE5TQ29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29sb3JTcGFjZUQw
IDAAQzAgMBADgAuAD9Q5OjsJPD0+P1ROU0lEVU5TSUNDV05TTW9kZWwQCYAMEACADtJBCUJDV05TLmRh
dGFPERFoAAARaGFwcGwCAAAAbW50ckdSQVlYWVogB9wACAAXAA8ALgAPYWNzcEFQUEwAAAAAbm9uZQAA
AAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAFZGVzYwAAAMAAAAB5ZHNjbQAAATwAAAfoY3BydAAACSQAAAAjd3RwdAAA
CUgAAAAUa1RSQwAACVwAAAgMZGVzYwAAAAAAAAAfR2VuZXJpYyBHcmF5IEdhbW1hIDIuMiBQcm9maWxl
YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05T
S2V5ZWRBcmNoaXZlctEICVRyb290gAGvEBALDBccEyEmJy4xND5GR0tOVSRudWxs1Q0ODxAREhMUFRZW
JGNsYXNzXk5TUmVzaXppbmdNb2RlXE5TSW1hZ2VGbGFnc1ZOU1JlcHNXTlNDb2xvcoAPEAASAMAAAIAC
gArSGA0ZG1pOUy5vYmplY3RzoRqAA4AJ0hgNHSCiHh+ABIAFgAjTDSIjJCUTXxAUTlNUSUZGUmVwcmVz
ZW50YXRpb25fEBlOU0ludGVybmFsTGF5b3V0RGlyZWN0aW9ugAeABk8RAj5NTQAqAAAADOHh4eEADwEA
AAMAAAABAAIAAAEBAAMAAAABAAIAAAECAAMAAAABAAgAAAEDAAMAAAABAAEAAAEGAAMAAAABAAEAAAEK
AAMAAAABAAEAAAERAAQAAAABAAAACAESAAMAAAABAAEAAAEVAAMAAAABAAEAAAEWAAMAAAABAAIAAAEX
AAQAAAABAAAABAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFTAAMAAAABAAEAAIdzAAcAAAF4AAAAxgAA
AAAAAAF4YXBwbAIQAABtbnRyR1JBWVhZWiAH1QAHAAEAAAAAAABhY3NwQVBQTAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAARkZXNjAAAAtAAAAHVjcHJ0AAABLAAAACd3dHB0AAABVAAAABRrVFJDAAABaAAA
AA5kZXNjAAAAAAAAABtDYWxpYnJhdGVkIEdyYXkgQ29sb3JzcGFjZQAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAAHwAAAAxza1NLAAAALgAAAYRkYURLAAAAOAAA
AbJjYUVTAAAAOAAAAep2aVZOAAAAQAAAAiJwdEJSAAAASgAAAmJ1a1VBAAAALAAAAqxmckZVAAAAPgAA
AthodUhVAAAANAAAAxZ6aFRXAAAAHgAAA0puYk5PAAAAOgAAA2hjc0NaAAAAKAAAA6JoZUlMAAAAJAAA
A8ppdElUAAAATgAAA+5yb1JPAAAAKgAABDxkZURFAAAATgAABGZrb0tSAAAAIgAABLRzdlNFAAAAOAAA
AbJ6aENOAAAAHgAABNZqYUpQAAAAJgAABPRlbEdSAAAAKgAABRpwdFBPAAAAUgAABURubE5MAAAAQAAA
BZZlc0VTAAAATAAABdZ0aFRIAAAAMgAABiJ0clRSAAAAJAAABlRmaUZJAAAARgAABnhockhSAAAAPgAA
Br5wbFBMAAAASgAABvxydVJVAAAAOgAAB0ZlblVTAAAAPAAAB4BhckVHAAAALAAAB7wAVgFhAGUAbwBi
AGUAYwBuAOEAIABzAGkAdgDhACAAZwBhAG0AYQAgADIALAAyAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDl
ACAAMgAsADIAIABnAGEAbQBtAGEAcAByAG8AZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBv
AHMAIABnAGUAbgDoAHIAaQBjAGEAIAAyAC4AMgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBt
ACAAQwBoAHUAbgBnACAARwBhAG0AbQBhACAAMgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBj
AG8AIABkAGEAIABHAGEAbQBhACAAZABlACAAQwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9
BDAAIABHAHIAYQB5AC0EMwQwBDwEMAAgADIALgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1
AGUAIABnAHIAaQBzACAAZwBhAG0AbQBhACAAMgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/ABy
AGsAZQAgAGcAYQBtAG0AYQAgADIALgAykBp1KHBwlo5RSV6mACAAMgAuADIAIIJyX2ljz4/wAEcAZQBu
AGUAcgBpAHMAawAgAGcAcgDlACAAZwBhAG0AbQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBj
AG4A4QAgAWEAZQBkAOEAIABnAGEAbQBhACAAMgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZ
ACAAMgAuADIAUAByAG8AZgBpAGwAbwAgAGcAcgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABl
AGwAbABhACAAZwBhAG0AbQBhACAAMgAsADIARwBhAG0AYQAgAGcAcgBpACAAZwBlAG4AZQByAGkAYwED
ACAAMgAsADIAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBv
AGYAaQBsACAARwBhAG0AbQBhACAAMgAsADLHfLwYACDWjMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8
Zm6QGnBwXqZ8+2VwACAAMgAuADIAIGPPj/Blh072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDt
MNUwoTCkMOsDkwO1A70DuQO6A8wAIAOTA7oDwQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBp
AGwAIABnAGUAbgDpAHIAaQBjAG8AIABkAGUAIABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBt
AG0AYQAgADIALAAyAEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAy
AC0AcAByAG8AZgBpAGUAbABQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBt
AG0AYQAgAGQAZQAgAGcAcgBpAHMAZQBzACAAMgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4i
DkwOFw4xDkgOJw5EDhsAIAAyAC4AMgBHAGUAbgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZ
AGwAZQBpAG4AZQBuACAAaABhAHIAbQBhAGEAbgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBm
AGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABw
AHIAbwBmAGkAbABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFb
AGMAaQAgAGcAYQBtAG0AYQAgADIALAAyBB4EMQRJBDAETwAgBEEENQRABDAETwAgBDMEMAQ8BDwEMAAg
ADIALAAyAC0EPwRABD4ERAQ4BDsETABHAGUAbgBlAHIAaQBjACAARwByAGEAeQAgAEcAYQBtAG0AYQAg
ADIALgAyACAAUAByAG8AZgBpAGwAZQY6BicGRQYnACAAMgAuADIAIAZEBkgGRgAgBjEGRQYnBi8GSgAg
BjkGJwZFdGV4dAAAAABDb3B5cmlnaHQgQXBwbGUgSW5jLiwgMjAxMgAAWFlaIAAAAAAAAPNRAAEAAAAB
FsxjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABt
AHIAdwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4AsgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEH
AQ0BEwEZAR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZ
AeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1
AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRj
BHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYn
BjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghG
CFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrF
CtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2p
DcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1
ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixSt
FM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjV
GPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1w
HZkdwx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKC
Iq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgN
KD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4W
Lkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSe
NNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuq
O+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6
Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtT
S5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2
VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0n
XXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmbo
Zz1nk2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6
cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwh
fIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4ef
iASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2
lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBp
oNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24
ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7Lrun
vCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4
yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls
2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG
6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH
+lf65/t3/Af8mP0p/br+S/7c/23//4AN0iIjRUZdTlNNdXRhYmxlRGF0YaNFRydWTlNEYXRh0iIjSUpc
TlNDb2xvclNwYWNloksnXE5TQ29sb3JTcGFjZdIiI01OV05TQ29sb3KiTSfSIiNQUVdOU0ltYWdlolAn
XxAPTlNLZXllZEFyY2hpdmVy0VRVVHJvb3SAAQAIABEAGgAjAC0AMgA3AEsAUQBaAGEAbgB1AH0AfwCE
AIYAiACNAJgAmgCcAJ4AowCmAKgAqgCsAK4AswDKAMwAzgMQAxUDIAMpAzwDQANLA1QDWQNhA2QDaQN4
A3wDhwOPA5wDqQO+A8MDxwPJA8sDzQPWA9sD4QPpA+sD7QPvA/ED9gP+FWoVbBVxFX8VgxWKFY8VnBWf
FawVsRW5FbwVwRXJFcwV3hXhFeYAAAAAAAACAQAAAAAAAABWAAAAAAAAAAAAAAAAAAAV6A
AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLgAAWFlaIAAAAAAAAPNRAAEAAAAB
FsxjdXJ2AAAAAAAAAAECMwAA0igpKitaJGNsYXNzbmFtZVgkY2xhc3Nlc18QEE5TQml0bWFwSW1hZ2VS
ZXCjKiwtWk5TSW1hZ2VSZXBYTlNPYmplY3TSKCkvMFdOU0FycmF5oi8t0igpMjNeTlNNdXRhYmxlQXJy
YXmjMi8t1TU2NzgNOTo7PD1XTlNXaGl0ZVxOU0NvbXBvbmVudHNcTlNDb2xvclNwYWNlXxASTlNDdXN0
b21Db2xvclNwYWNlRDAgMABDMCAwEAOAC4AO1D9AQQ1CQ0RFVE5TSURVTlNJQ0NXTlNNb2RlbBAJgAwQ
AIANTxERnAAAEZxhcHBsAgAAAG1udHJHUkFZWFlaIAfcAAgAFwAPAC4AD2Fjc3BBUFBMAAAAAG5vbmUA
AAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAABWRlc2MAAADAAAAAeWRzY20AAAE8AAAIGmNwcnQAAAlYAAAAI3d0cHQA
AAl8AAAAFGtUUkMAAAmQAAAIDGRlc2MAAAAAAAAAH0dlbmVyaWMgR3JheSBHYW1tYSAyLjIgUHJvZmls
ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAB8AAAAMc2tTSwAAAC4AAAGEZGFESwAAADoA
AAGyY2FFUwAAADgAAAHsdmlWTgAAAEAAAAIkcHRCUgAAAEoAAAJkdWtVQQAAACwAAAKuZnJGVQAAAD4A
AALaaHVIVQAAADQAAAMYemhUVwAAABoAAANMa29LUgAAACIAAANmbmJOTwAAADoAAAOIY3NDWgAAACgA
AAPCaGVJTAAAACQAAAPqcm9STwAAACoAAAQOZGVERQAAAE4AAAQ4aXRJVAAAAE4AAASGc3ZTRQAAADgA
AATUemhDTgAAABoAAAUMamFKUAAAACYAAAUmZWxHUgAAACoAAAVMcHRQTwAAAFIAAAV2bmxOTAAAAEAA
AAXIZXNFUwAAAEwAAAYIdGhUSAAAADIAAAZUdHJUUgAAACQAAAaGZmlGSQAAAEYAAAaqaHJIUgAAAD4A
AAbwcGxQTAAAAEoAAAcuYXJFRwAAACwAAAd4cnVSVQAAADoAAAekZW5VUwAAADwAAAfeAFYBYQBlAG8A
YgBlAGMAbgDhACAAcwBpAHYA4QAgAGcAYQBtAGEAIAAyACwAMgBHAGUAbgBlAHIAaQBzAGsAIABnAHIA
5QAgADIALAAyACAAZwBhAG0AbQBhAC0AcAByAG8AZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkA
cwBvAHMAIABnAGUAbgDoAHIAaQBjAGEAIAAyAC4AMgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA
4QBtACAAQwBoAHUAbgBnACAARwBhAG0AbQBhACAAMgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIA
aQBjAG8AIABkAGEAIABHAGEAbQBhACAAZABlACAAQwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsE
TAQ9BDAAIABHAHIAYQB5AC0EMwQwBDwEMAAgADIALgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkA
cQB1AGUAIABnAHIAaQBzACAAZwBhAG0AbQBhACAAMgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA
/AByAGsAZQAgAGcAYQBtAG0AYQAgADIALgAykBp1KHBwlo5RSV6mADIALgAygnJfaWPPj/DHfLwYACDW
jMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8AEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAZwBhAG0A
bQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A4QAgAWEAZQBkAOEAIABnAGEAbQBhACAA
MgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZACAAMgAuADIARwBhAG0AYQAgAGcAcgBpACAA
ZwBlAG4AZQByAGkAYwEDACAAMgAsADIAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQA
dQBmAGUAbgAtAFAAcgBvAGYAaQBsACAARwBhAG0AbQBhACAAMgAsADIAUAByAG8AZgBpAGwAbwAgAGcA
cgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABlAGwAbABhACAAZwBhAG0AbQBhACAAMgAsADIA
RwBlAG4AZQByAGkAcwBrACAAZwByAOUAIAAyACwAMgAgAGcAYQBtAG0AYQBwAHIAbwBmAGkAbGZukBpw
cF6mfPtlcAAyAC4AMmPPj/Blh072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUwoTCkMOsD
kwO1A70DuQO6A8wAIAOTA7oDwQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwAIABnAGUA
bgDpAHIAaQBjAG8AIABkAGUAIABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0AYQAgADIA
LAAyAEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0AcAByAG8A
ZgBpAGUAbABQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0AYQAgAGQA
ZQAgAGcAcgBpAHMAZQBzACAAMgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwOFw4xDkgO
Jw5EDhsAIAAyAC4AMgBHAGUAbgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwAZQBpAG4A
ZQBuACAAaABhAHIAbQBhAGEAbgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkAaQBsAGkA
RwBlAG4AZQByAGkBDQBrAGkAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIAbwBmAGkA
bABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMAaQAgAGcA
YQBtAG0AYQAgADIALAAyBjoGJwZFBicAIAAyAC4AMgAgBkQGSAZGACAGMQZFBicGLwZKACAGOQYnBkUE
HgQxBEkEMARPACAEQQQ1BEAEMARPACAEMwQwBDwEPAQwACAAMgAsADIALQQ/BEAEPgREBDgEOwRMAEcA
ZQBuAGUAcgBpAGMAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABQAHIAbwBmAGkAbABlAAB0
ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDEyAABYWVogAAAAAAAA81EAAQAAAAEWzGN1cnYA
AAAAAAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3AHwA
gQCGAIsAkACVAJoAnwCkAKkArgCyALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkB
HwElASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB
+gIDAgwCFAIdAiYCLwI4AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAMLAxYD
IQMtAzgDQwNPA1oDZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+BIwE
mgSoBLYExATTBOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZIBlkG
agZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghuCIII
lgiqCL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsL
Igs5C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3eDfgO
Ew4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExExEU8R
bRGMEaoRyRHoEgcSJhJFEmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIV
NBVWFXgVmxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkgGUUZ
axmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUdHh1HHXAdmR3DHewe
Fh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFIIXUhoSHOIfsiJyJVIoIiryLdIwoj
OCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhxKKIo
1CkGKTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6CLrcu
7i8kL1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01
hzXCNf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76DwnPGU8
pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/iQCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPARANE
R0SKRM5FEkVVRZpF3kYiRmdGq0bwRzVHe0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpM
cky6TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSPVNtV
KFV1VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3JXhpe
bF69Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+lo
P2iWaOxpQ2maafFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHwckty
pnMBc11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6RnqlewR7Y3vCfCF8gXzhfUF9
oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6J
M4mZif6KZIrKizCLlov8jGOMyo0xjZiN/45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSV
X5XJljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFHobai
JqKWowajdqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6hrxav
i7AAsHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8IbybvRW9
j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjKt8s2y7bM
Ncy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp22vvb
gNwF3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp0Opb6uXr
cOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe9m32+/eK+Bn4qPk4+cf6V/rn+3f8
B/yY/Sn9uv5L/tz/bf//0igpSElcTlNDb2xvclNwYWNlokotXE5TQ29sb3JTcGFjZdIoKUxNV05TQ29s
b3KiTC3SKClPUFdOU0ltYWdlok8tAAgAEQAaACQAKQAyADcASQBMAFEAUwBmAGwAdwB+AI0AmgChAKkA
qwCtALIAtAC2ALsAxgDIAMoAzADRANQA1gDYANoA4QD4ARQBFgEYA1oDXwNqA3MDhgOKA5UDngOjA6sD
rgOzA8IDxgPRA9kD5gPzBAgEDQQRBBMEFQQXBCAEJQQrBDMENQQ3BDkEOxXbFeAV7RXwFf0WAhYKFg0W
EhYaAAAAAAAAAgEAAAAAAAAAUQAAAAAAAAAAAAAAAAAAFh0
</mutableData>
</image>
<image name="linphone_user.png" width="41.599998474121094" height="42.400001525878906"/>
<image name="security_toogle_icon_green.png" width="33.599998474121094" height="38.400001525878906"/>
<systemColor name="secondarySystemBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -29,15 +29,15 @@
@property(nonatomic, strong) NSMutableArray *addresses;
@property(nonatomic, strong) NSMutableArray *phoneOrAddr;
@property(nonatomic, strong) NSMutableArray *addressesCached;
@property(readonly, nonatomic) NSMutableDictionary *ldapContactAddressBookMap;
@property(readonly, nonatomic) NSMutableDictionary *ldapAndProvisioningContactAddressBookMap;
@end
@implementation ChatConversationCreateTableView
- (void)viewWillAppear:(BOOL)animated {
if (!_ldapContactAddressBookMap) {
_ldapContactAddressBookMap = [NSMutableDictionary dictionary];
if (!_ldapAndProvisioningContactAddressBookMap) {
_ldapAndProvisioningContactAddressBookMap = [NSMutableDictionary dictionary];
}
[super viewWillAppear:animated];
@ -57,7 +57,7 @@
_addresses = [[NSMutableArray alloc] initWithCapacity:LinphoneManager.instance.fastAddressBook.addressBookMap.allKeys.count];
_phoneOrAddr = [[NSMutableArray alloc] initWithCapacity:LinphoneManager.instance.fastAddressBook.addressBookMap.allKeys.count];
_addressesCached = [[NSMutableArray alloc] initWithCapacity:LinphoneManager.instance.fastAddressBook.addressBookMap.allKeys.count];
_addressesCached = [[NSMutableArray alloc] initWithCapacity:LinphoneManager.instance.fastAddressBook.addressBookMap.allKeys.count];
[[NSNotificationCenter defaultCenter]
addObserver:self
@ -82,10 +82,47 @@
[self searchBar:_searchBar textDidChange:_searchBar.text];
self.tableView.accessibilityIdentifier = @"Suggested addresses";
NSDictionary* userInfo;
[NSNotificationCenter.defaultCenter addObserver:self
selector: @selector(receivePresenceNotification:)
name: @"LinphoneFriendPresenceUpdate"
object: userInfo];
}
-(void) receivePresenceNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"LinphoneFriendPresenceUpdate"])
{
NSDictionary* userInfo = notification.userInfo;
NSString* friend = (NSString*)userInfo[@"friend"];
for (int i = 0; i < _addresses.count; i++)
{
NSString *key = [_addresses objectAtIndex:i];
Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:key use_prefix:[CallManager.instance applyInternationalPrefix]]];
if (!contact) {
contact = [_ldapAndProvisioningContactAddressBookMap objectForKey:key];
}
if (contact.friend != nil && linphone_friend_get_address(contact.friend) != nil) {
char *curi = linphone_address_as_string_uri_only(linphone_friend_get_address(contact.friend));
NSString *uri = [NSString stringWithUTF8String:curi];
if([uri isEqual:friend]){
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:0];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
}
}
}
}
}
- (void) viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneFriendPresenceUpdate" object:nil];
[AvatarBridge removeAllObserver];
_notFirstTime = FALSE;
}
@ -97,64 +134,76 @@
_loadingView.hidden = TRUE;
}
-(BOOL) isSecureChatable:(const LinphoneFriend*)friend {
if (!friend)
return false;
const LinphonePresenceModel *model = linphone_friend_get_presence_model(friend);
return model && linphone_presence_model_has_capability(model, LinphoneFriendCapabilityLimeX3dh);
}
- (void) buildChatContactTable {
bctbx_list_t *results = [MagicSearchSingleton.instance getLastSearchResults];
while (results) {
LinphoneSearchResult *result = results->data;
bctbx_list_t *result_list = [MagicSearchSingleton.instance getLastSearchResults];
bctbx_list_t *it;
LinphoneAccount *account = linphone_core_get_default_account(LC);
for (it = result_list; it != NULL; it = it->next) {
LinphoneSearchResult *result = it->data;
const LinphoneAddress *addr = linphone_search_result_get_address(result);
const LinphoneFriend* friend = linphone_search_result_get_friend(result);
const char *phoneNumber = linphone_search_result_get_phone_number(result);
if (([LinphoneManager.instance lpConfigBoolForKey:@"force_lime_chat_rooms"] && ![self isSecureChatable:friend]) || [LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"]) {
continue;
}
const char *phoneNumber = NULL;
Contact *contact = nil;
char *uri = nil;
NSString *address = nil;
if (addr) {
uri = linphone_address_as_string_uri_only(addr);
address = [NSString stringWithUTF8String:uri];
contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:address]];
}
const LinphoneFriend* friend = linphone_search_result_get_friend(result);
if (!addr || (!contact && friend)) {
phoneNumber = linphone_search_result_get_phone_number(result);
contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:address use_prefix:[CallManager.instance applyInternationalPrefix]]];
if (!contact && friend) {
contact = [[Contact alloc] initWithFriend:friend];
[contact setCreatedFromLdapOrProvisioning:TRUE];
[_ldapAndProvisioningContactAddressBookMap setObject:contact forKey:address];
}
} else if (friend){
if (!phoneNumber) {
results = results->next;
continue;
}
LinphoneAccount *account = linphone_core_get_default_account(LC);
if (account) {
const char *normalizedPhoneNumber = linphone_account_normalize_phone_number(account, phoneNumber);
char *normalizedPhoneNumber = linphone_account_normalize_phone_number(account, phoneNumber);
if (!normalizedPhoneNumber) {
// get invalid phone number, continue
results = results->next;
continue;
}
addr = linphone_account_normalize_sip_uri(account, normalizedPhoneNumber);
bctbx_free(normalizedPhoneNumber);
uri = linphone_address_as_string_uri_only(addr);
address = [NSString stringWithUTF8String:uri];
contact = [[Contact alloc] initWithFriend:friend];
[contact setCreatedFromLdap:TRUE];
[_ldapContactAddressBookMap setObject:contact forKey:address];
[contact setCreatedFromLdapOrProvisioning:TRUE];
[_ldapAndProvisioningContactAddressBookMap setObject:contact forKey:address];
linphone_address_unref(addr);
}
}
if (uri) ms_free(uri);
if (!addr) {
results = results->next;
continue;
}
ms_free(uri);
[_addresses addObject:address];
[_phoneOrAddr addObject:phoneNumber ? [NSString stringWithUTF8String:phoneNumber] : address];
[_addressesCached addObject:[NSString stringWithFormat:@"%d",linphone_search_result_get_capabilities(result)]];
results = results->next;
}
bctbx_list_free(result_list);
[self.tableView reloadData];
_reloadMagicSearch = FALSE;
}
@ -168,7 +217,7 @@
[_addresses removeAllObjects];
[_phoneOrAddr removeAllObjects];
[_addressesCached removeAllObjects];
[_ldapContactAddressBookMap removeAllObjects];
[_ldapAndProvisioningContactAddressBookMap removeAllObjects];
[self.tableView reloadData];
_reloadMagicSearch = _reloadMagicSearch || [filter length]==0 || ![[MagicSearchSingleton.instance currentFilter] isEqualToString:filter];
@ -192,7 +241,7 @@
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
return 60.0;
return 60.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@ -203,12 +252,12 @@
NSString *key = [_addresses objectAtIndex:indexPath.row];
NSString *phoneOrAddr = [_phoneOrAddr objectAtIndex:indexPath.row];
Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:key]];
Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:key use_prefix:[CallManager.instance applyInternationalPrefix]]];
if (!contact) {
contact = [_ldapContactAddressBookMap objectForKey:key];
contact = [_ldapAndProvisioningContactAddressBookMap objectForKey:key];
}
const LinphonePresenceModel *model = contact.friend ? linphone_friend_get_presence_model(contact.friend) : NULL;
const LinphonePresenceModel *model = contact.friend ? linphone_friend_get_presence_model(contact.friend) : NULL;
Boolean linphoneContact = [FastAddressBook contactHasValidSipDomain:contact]
|| (model && linphone_presence_model_get_basic_status(model) == LinphonePresenceBasicStatusOpen);
LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:key];
@ -216,30 +265,32 @@
return cell;
cell.linphoneImage.hidden = [LinphoneManager.instance lpConfigBoolForKey:@"hide_linphone_contacts" inSection:@"app"] || !linphoneContact;
cell.securityImage.hidden = !(model && linphone_presence_model_has_capability(model, LinphoneFriendCapabilityLimeX3dh));
int capabilities = [[_addressesCached objectAtIndex:indexPath.row] intValue];
BOOL greyCellForEncryptedChat = _isEncrypted ? capabilities > 1 : TRUE;
BOOL greyCellForGroupChat = _isGroupChat ? capabilities > 0 : TRUE;
cell.userInteractionEnabled = cell.greyView.hidden = greyCellForEncryptedChat && greyCellForGroupChat;
cell.displayNameLabel.text = [contact createdFromLdap] ? [contact displayName] : [FastAddressBook displayNameForAddress:addr];
cell.securityImage.hidden = !(model && linphone_presence_model_has_capability(model, LinphoneFriendCapabilityLimeX3dh));
int capabilities = [[_addressesCached objectAtIndex:indexPath.row] intValue];
BOOL greyCellForEncryptedChat = _isEncrypted ? capabilities > 1 : TRUE;
BOOL greyCellForGroupChat = _isGroupChat ? capabilities > 0 : TRUE;
cell.userInteractionEnabled = cell.greyView.hidden = greyCellForEncryptedChat && greyCellForGroupChat;
cell.displayNameLabel.text = [contact createdFromLdapOrProvisioning] ? [contact displayName] : [FastAddressBook displayNameForAddress:addr];
char *str = linphone_address_as_string(addr);
cell.addressLabel.text = linphoneContact ? [NSString stringWithUTF8String:str] : phoneOrAddr;
ms_free(str);
cell.selectedImage.hidden = ![_contactsGroup containsObject:cell.addressLabel.text];
[cell.avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
[cell.avatarImage setImage:[FastAddressBook imageForAddress:addr]];
cell.contentView.userInteractionEnabled = false;
cell.contentView.backgroundColor = UIColor.clearColor;
cell.backgroundColor = UIColor.clearColor;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIChatCreateCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!cell.userInteractionEnabled)
return;
if (!cell.userInteractionEnabled)
return;
LinphoneAccount *defaultAccount = linphone_core_get_default_account(LC);
if (!(defaultAccount && linphone_account_params_get_conference_factory_uri(linphone_account_get_params(defaultAccount))) || !_isGroupChat) {
LinphoneAddress *addr = linphone_address_new(cell.addressLabel.text.UTF8String);
[PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:_isEncrypted];
[PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:_isEncrypted];
if (!addr) {
LOGE(@"Chat room could not be created on server, because null address.");
[ChatConversationInfoView displayCreationError];
@ -251,8 +302,6 @@
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSInteger index = 0;
_searchBar.text = @"";
[self searchBar:_searchBar textDidChange:@""];
if(cell.selectedImage.hidden) {
if(![_contactsGroup containsObject:cell.addressLabel.text]) {
[_contactsGroup addObject:cell.addressLabel.text];

View file

@ -55,6 +55,9 @@
- (IBAction)onNextClick:(id)sender;
- (IBAction)onChiffreClick:(id)sender;
-(void) unfragmentCompositeDescription;
-(void) fragmentCompositeDescription;
@end
#endif /* ChatConversationCreateView_h */

View file

@ -45,6 +45,21 @@ static UICompositeViewDescription *compositeDescription = nil;
return self.class.compositeViewDescription;
}
-(void) unfragmentCompositeDescription {
if (!IPAD)
return;
compositeDescription.isLeftFragment = true;
compositeDescription.otherFragment = nil;
}
-(void) fragmentCompositeDescription {
if (!IPAD)
return;
compositeDescription.otherFragment = IPAD ? NSStringFromClass(ChatsListView.class) : nil;
compositeDescription.isLeftFragment = false;
}
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
@ -54,7 +69,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[self.view addGestureRecognizer:tap];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.itemSize = CGSizeMake(100.0 , 50.0);
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize;
_collectionController.collectionView = _collectionView;
_collectionController = (ChatConversationCreateCollectionViewController *)[[UICollectionViewController alloc] initWithCollectionViewLayout:layout];
_collectionView.dataSource = self;
@ -63,6 +78,7 @@ static UICompositeViewDescription *compositeDescription = nil;
_tableController.controllerNextButton = _nextButton;
_isForEditing = FALSE;
_voipTitle.text = VoipTexts.call_action_participants_list;
_topBar.backgroundColor = [VoipTheme.voipToolbarBackgroundColor get];
}
@ -75,6 +91,10 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(viewUpdateEvent:)
name:kLinphoneChatCreateViewChange
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(displayModeChanged)
name:kDisplayModeChanged
object:nil];
LinphoneAccount *defaultAccount = linphone_core_get_default_account(LC);
_chiffreOptionView.hidden = !(defaultAccount && linphone_account_params_get_conference_factory_uri(linphone_account_get_params(defaultAccount)));
if ([LinphoneManager.instance lpConfigBoolForKey:@"hide_linphone_contacts" inSection:@"app"]) {
@ -83,8 +103,17 @@ static UICompositeViewDescription *compositeDescription = nil;
CGRect frame = _allButton.frame;
frame.origin.x = _linphoneButton.frame.origin.x;
_allButton.frame = frame;
}
if ([LinphoneManager.instance lpConfigBoolForKey:@"force_lime_chat_rooms"] || [LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"]) {
_chiffreOptionView.hidden = true;
_isEncrypted = true;
_tableController.isEncrypted = true;
_allButton.hidden = true;
_linphoneButton.hidden = true;
_selectedButtonImage.hidden = true;
}
if (_isForVoipConference) {
_switchView.hidden = true;
@ -95,13 +124,26 @@ static UICompositeViewDescription *compositeDescription = nil;
} else {
[_nextButton setImage:[UIImage imageNamed:@"next_default"] forState:UIControlStateNormal];
}
_topBar.backgroundColor = VoipTheme.toolbar_color;
} else {
_voipTitle.hidden = true;
[_nextButton setImage:[UIImage imageNamed:@"next_default"] forState:UIControlStateNormal];
_topBar.backgroundColor = UIColor.secondarySystemBackgroundColor;
}
[self displayModeChanged];
}
- (void)displayModeChanged{
[self.tableController.tableView reloadData];
if (_isForVoipConference) {
self.view.backgroundColor = [VoipTheme.voipBackgroundBWColor get];
_tableController.tableView.backgroundColor = [VoipTheme.voipBackgroundBWColor get];
_tableController.searchBar.backgroundColor = [VoipTheme.voipBackgroundBWColor get];
_tableController.collectionView.backgroundColor = [VoipTheme.voipBackgroundBWColor get];
} else {
self.view.backgroundColor = [VoipTheme.backgroundWhiteBlack get];
_tableController.tableView.backgroundColor = [VoipTheme.backgroundWhiteBlack get];
_tableController.searchBar.backgroundColor = [VoipTheme.backgroundWhiteBlack get];
_tableController.collectionView.backgroundColor = [VoipTheme.backgroundWhiteBlack get];
}
}
- (void)viewUpdateEvent:(NSNotification *)notif {
@ -116,17 +158,17 @@ static UICompositeViewDescription *compositeDescription = nil;
frame.origin.x = self.view.frame.size.width * 0.192;
}
_chiffreOptionView.frame = frame;
_isEncrypted = FALSE;
_isEncrypted = [LinphoneManager.instance lpConfigBoolForKey:@"force_lime_chat_rooms"] || [LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"]; // false by default
CGRect buttonFrame = _chiffreButton.frame;
_tableController.isEncrypted = _isEncrypted;
// no encrypted by default
buttonFrame.origin.x = 2;
[_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_grey.png"]];
_chiffreButton.frame = buttonFrame;
if (!_isEncrypted) {
buttonFrame.origin.x = 2;
[_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_grey.png"]];
_chiffreButton.frame = buttonFrame;
}
_waitView.hidden = YES;
_backButton.hidden = IPAD;
_backButton.hidden = IPAD && !(_isForVoipConference||_isForOngoingVoipConference);
if(_tableController.contactsGroup.count == 0) {
if (!_isForEditing)
_nextButton.enabled = FALSE;
@ -149,9 +191,8 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (IPAD)
[NSNotificationCenter.defaultCenter removeObserver:self];
[super viewWillDisappear:animated];
[NSNotificationCenter.defaultCenter removeObserver:self];
}
#pragma mark - Chat room functions
@ -168,7 +209,12 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onBackClick:(id)sender {
[_tableController.contactsGroup removeAllObjects];
if (_isForVoipConference) {
[PhoneMainView.instance popToView:ConferenceSchedulingView.compositeViewDescription];
if (_isForOngoingVoipConference) {
[PhoneMainView.instance popToView:VIEW(ConferenceCallView).compositeViewDescription];
[ControlsViewModelBridge showParticipants];
} else {
[PhoneMainView.instance popToView:ConferenceSchedulingView.compositeViewDescription];
}
} else {
if (_tableController.isForEditing)
[PhoneMainView.instance popToView:ChatConversationInfoView.compositeViewDescription];
@ -180,7 +226,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onNextClick:(id)sender {
if (_isForVoipConference) {
if (_isForOngoingVoipConference) {
[PhoneMainView.instance changeCurrentView:VIEW(ActiveCallOrConferenceView).compositeViewDescription];
[PhoneMainView.instance popToView:VIEW(ConferenceCallView).compositeViewDescription];
[ConferenceViewModelBridge updateParticipantsListWithAddresses:_tableController.contactsGroup];
} else {
[PhoneMainView.instance changeCurrentView:VIEW(ConferenceSchedulingSummaryView).compositeViewDescription];
@ -260,7 +306,7 @@ typedef enum { ContactsAll, ContactsLinphone, ContactsMAX } ContactsCategory;
return NO;
}
#pragma mark - UICollectionViewDataSource
#pragma mark - UICollectionViewDataSource & Delegate
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _tableController.contactsGroup.count;
}
@ -282,9 +328,10 @@ typedef enum { ContactsAll, ContactsLinphone, ContactsMAX } ContactsCategory;
ms_free(phone);
} else
addr = linphone_address_new(uri.UTF8String);
cell = [cell initWithName:[FastAddressBook displayNameForAddress:addr]];
[cell.nameLabel setText:[FastAddressBook displayNameForAddress:addr]];
linphone_address_unref(addr);
return cell;
}
@end

View file

@ -32,7 +32,7 @@
NSString *messageText;
}
@property(nonatomic) LinphoneChatMessage *msg;
@property(nonatomic) LinphoneEventLog *event;
@property(nonatomic) bctbx_list_t *displayedList;
@property(nonatomic) bctbx_list_t *receivedList;
@property(nonatomic) bctbx_list_t *notReceivedList;

View file

@ -48,17 +48,12 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewDidLoad {
[super viewDidLoad];
_msg = NULL;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
int index = [VIEW(ChatConversationView).tableController indexOfMesssage:_msg];
if (index < 0)
[PhoneMainView.instance popToView:ChatConversationView.compositeViewDescription];
_cell = (UIChatBubbleTextCell *)[VIEW(ChatConversationView).tableController tableView:VIEW(ChatConversationView).tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
_cell = [VIEW(ChatConversationView).tableController buildMessageCell:_event];
_cell.frame = CGRectMake(-10,0,_msgView.frame.size.width,_msgView.frame.size.height);
_cell.isFirst = true;
_cell.isLast = true;
@ -90,23 +85,33 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)updateImdnList {
if (_msg && linphone_chat_message_get_chat_room(_msg)) {
_displayedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDisplayed);
_receivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDeliveredToUser);
_notReceivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDelivered);
_errorList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateNotDelivered);
[_tableView reloadData];
if (_event) {
LinphoneChatMessage *_msg = linphone_event_log_get_chat_message(_event);
if (_msg) {
_displayedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDisplayed);
_receivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDeliveredToUser);
_notReceivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDelivered);
_errorList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateNotDelivered);
[_tableView reloadData];
}
}
}
- (void)fitContent {
LinphoneChatMessage *_msg = linphone_event_log_get_chat_message(_event);
CGSize messageSize = [UIChatBubbleTextCell ViewHeightForMessage:_msg withWidth:self.view.frame.size.width];
[_msgView setFrame:CGRectMake(_msgView.frame.origin.x,
_msgView.frame.origin.y,
self.view.frame.size.width,
messageSize.height+5)];
if (messageSize.height > self.view.bounds.size.height/2) {
[_msgView setFrame:CGRectMake(_msgView.frame.origin.x,
_msgView.frame.origin.y,
self.view.frame.size.width,
self.view.bounds.size.height/2 +5)];
} else {
[_msgView setFrame:CGRectMake(_msgView.frame.origin.x,
_msgView.frame.origin.y,
self.view.frame.size.width,
messageSize.height+5)];
}
[_tableView setFrame:CGRectMake(_tableView.frame.origin.x,
_msgView.frame.origin.y + _msgView.frame.size.height + 10,
@ -299,7 +304,8 @@ static UICompositeViewDescription *compositeDescription = nil;
f.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
f.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
if (linphone_chat_message_is_ephemeral(_msg)) {
LinphoneChatMessage *_msg = _event ? linphone_event_log_get_chat_message(_event) : nil;
if (_msg && linphone_chat_message_is_ephemeral(_msg)) {
long duration = linphone_chat_message_get_ephemeral_expire_time(_msg) == 0 ?
linphone_chat_room_get_ephemeral_lifetime(linphone_chat_message_get_chat_room(_msg)) :
linphone_chat_message_get_ephemeral_expire_time(_msg)-[NSDate date].timeIntervalSince1970;

View file

@ -35,6 +35,7 @@
@property(nonatomic) LinphoneChatRoom *room;
@property(nonatomic) LinphoneChatRoomCbs *chatRoomCbs;
@property(nonatomic) const char *peerAddress;
@property(nonatomic) const char *localAddress;
@property (weak, nonatomic) IBOutlet UIIconButton *nextButton;
@property (weak, nonatomic) IBOutlet UIRoundBorderedButton *quitButton;

View file

@ -22,6 +22,7 @@
#import "ChatConversationInfoView.h"
#import "PhoneMainView.h"
#import "UIChatConversationInfoTableViewCell.h"
#import "linphoneapp-Swift.h"
#import "linphone/core.h"
@ -84,6 +85,7 @@ static UICompositeViewDescription *compositeDescription = nil;
_room = NULL;
_chatRoomCbs = NULL;
_peerAddress = NULL;
_localAddress = NULL;
}
- (void)viewWillAppear:(BOOL)animated {
@ -95,10 +97,45 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(onLinphoneCoreReady:)
name:kLinphoneGlobalStateUpdate
object:nil];
NSDictionary* userInfo;
[NSNotificationCenter.defaultCenter addObserver:self
selector: @selector(receivePresenceNotification:)
name: @"LinphoneFriendPresenceUpdate"
object: userInfo];
}
-(void) receivePresenceNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"LinphoneFriendPresenceUpdate"])
{
NSDictionary* userInfo = notification.userInfo;
NSString* friend = (NSString*)userInfo[@"friend"];
for (int i = 0; i < _contacts.count; i++)
{
NSString *uri = _contacts[i];
LinphoneAddress *addr = linphone_address_new(uri.UTF8String);
if (addr != nil) {
char *curi = linphone_address_as_string_uri_only(addr);
NSString *uri = [NSString stringWithUTF8String:curi];
if([uri isEqual:friend]){
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:0];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
}
}
}
}
}
- (void)viewWillDisappear:(BOOL)animated {
[NSNotificationCenter.defaultCenter removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneFriendPresenceUpdate" object:nil];
[AvatarBridge removeAllObserver];
if (!_room || !_chatRoomCbs)
return;
@ -153,10 +190,11 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)onLinphoneCoreReady:(NSNotification *)notif {
if ((LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn) {
if (!_create && _peerAddress) {
if (!_create && _peerAddress && _localAddress) {
LinphoneAddress *peerAddr = linphone_core_create_address([LinphoneManager getLc], _peerAddress);
if (peerAddr) {
_room = linphone_core_get_chat_room([LinphoneManager getLc], peerAddr);
LinphoneAddress *localAddr = linphone_core_create_address([LinphoneManager getLc], _localAddress);
if (peerAddr && localAddr) {
_room = linphone_core_search_chat_room([LinphoneManager getLc], NULL, localAddr, peerAddr, NULL);
}
[self configure];
}
@ -181,7 +219,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)onValidate {
ChatConversationView *view = VIEW(ChatConversationView);
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
// Change subject if necessary
if (![_oldSubject isEqualToString:_nameLabel.text])
linphone_chat_room_set_subject(_room, _nameLabel.text.UTF8String);
@ -270,13 +308,14 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onBackClick:(id)sender {
if(_create) {
ChatConversationCreateView *view = VIEW(ChatConversationCreateView);
[view fragmentCompositeDescription];
view.tableController.contactsGroup = [_contacts mutableCopy];
view.tableController.notFirstTime = TRUE;
view.isForEditing = FALSE;
view.isForVoipConference = FALSE;
[PhoneMainView.instance popToView:view.compositeViewDescription];
} else {
ChatConversationView *view = VIEW(ChatConversationView);
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
}
@ -296,6 +335,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onAddClick:(id)sender {
if (_create || _imAdmin) {
ChatConversationCreateView *view = VIEW(ChatConversationCreateView);
[view fragmentCompositeDescription];
view.tableController.notFirstTime = TRUE;
view.isForEditing = !_create;
view.isGroupChat = TRUE;
@ -324,7 +364,7 @@ static UICompositeViewDescription *compositeDescription = nil;
cell.uri = _contacts[indexPath.row];
LinphoneAddress *addr = linphone_address_new(cell.uri.UTF8String);
cell.nameLabel.text = (addr == nil? cell.uri : [FastAddressBook displayNameForAddress:addr]);
[cell.avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:YES withRoundedRadius:YES];
[cell.avatarImage setImage:[FastAddressBook imageForAddress:addr]];
cell.controllerView = self;
if(![_admins containsObject:cell.uri]) {
cell.adminLabel.enabled = FALSE;

View file

@ -25,6 +25,7 @@
#import "UICheckBoxTableView.h"
@interface FileContext : NSObject
@property NSMutableArray <NSString *> *typesArray;
@property NSMutableArray <NSData *> *datasArray;
@ -60,6 +61,7 @@
@property(nonatomic) NSTimer *ephemeralDisplayTimer;
@property (nullable, nonatomic) UIButton *floatingScrollButton;
@property (nullable, nonatomic) UILabel *scrollBadge;
@property (nullable, nonatomic) UIButton *floatingScrollBackground;
- (void)addEventEntry:(LinphoneEventLog *)event;
- (void)scrollToBottom:(BOOL)animated;
@ -70,5 +72,6 @@
- (void) dismissMessagesPopups;
- (void) scrollToMessage:(LinphoneChatMessage *)message;
- (int) indexOfMesssage:(LinphoneChatMessage *)message;
- (void *)buildMessageCell:(LinphoneEventLog *) event;
@end

View file

@ -20,7 +20,6 @@
#import "LinphoneManager.h"
#import "ChatConversationTableView.h"
#import "ChatConversationImdnView.h"
#import "UIChatBubbleTextCell.h"
#import "UIChatBubblePhotoCell.h"
#import "UIChatNotifiedEventCell.h"
#import "PhoneMainView.h"
@ -84,7 +83,6 @@
LinphoneChatRoomCapabilitiesMask capabilities = linphone_chat_room_get_capabilities(_chatRoom);
bool oneToOne = capabilities & LinphoneChatRoomCapabilitiesOneToOne;
bctbx_list_t *chatRoomEvents = linphone_chat_room_get_history_events(_chatRoom, 0);
int unread_count = 0;
bctbx_list_t *head = chatRoomEvents;
@ -142,12 +140,11 @@
- (void)addEventEntry:(LinphoneEventLog *)event {
[eventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]];
[totalEventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]];
[totalEventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]];
int pos = (int)eventList.count - 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:pos inSection:0];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView reloadData];
[self.tableView endUpdates];
}
@ -171,9 +168,9 @@
//[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
animated:animated];
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
[ChatConversationView markAsRead:_chatRoom];
[ChatConversationViewSwift markAsRead:_chatRoom];
}
- (void)scrollToLastUnread:(BOOL)animated {
@ -203,7 +200,7 @@
index = (int)count - 1;
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
[ChatConversationView markAsRead:_chatRoom];
[ChatConversationViewSwift markAsRead:_chatRoom];
// Scroll to unread
if (index < 0)
@ -331,28 +328,32 @@ static const int BASIC_EVENT_LIST=15;
}
}
-(UIChatBubbleTextCell *)buildMessageCell:(LinphoneEventLog *) event {
NSString *kCellId = nil;
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
BOOL isConferenceIcs = [ICSBubbleView isConferenceInvitationMessageWithCmessage:chat];
if (!isConferenceIcs && (linphone_chat_message_get_file_transfer_information(chat) || linphone_chat_message_get_external_body_url(chat)))
kCellId = NSStringFromClass(UIChatBubblePhotoCell.class);
else
kCellId = NSStringFromClass(UIChatBubbleTextCell.class);
// To use less memory and to avoid overlapping. To be improved.
UIChatBubbleTextCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCellId];
cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId];
[cell setEvent:event];
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *kCellId = nil;
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage) {
UIChatBubbleTextCell *cell = [self buildMessageCell:event];
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
BOOL isConferenceIcs = [ICSBubbleView isConferenceInvitationMessageWithCmessage:chat];
if (!isConferenceIcs && (linphone_chat_message_get_file_transfer_information(chat) || linphone_chat_message_get_external_body_url(chat)))
kCellId = NSStringFromClass(UIChatBubblePhotoCell.class);
else
kCellId = NSStringFromClass(UIChatBubbleTextCell.class);
// To use less memory and to avoid overlapping. To be improved.
UIChatBubbleTextCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId];
[cell setEvent:event];
if (chat) {
cell.isFirst = [self isFirstIndexInTableView:indexPath chat:chat];
cell.isLast = [self isLastIndexInTableView:indexPath chat:chat];
[cell update];
}
if (chat) {
cell.isFirst = [self isFirstIndexInTableView:indexPath chat:chat];
cell.isLast = [self isLastIndexInTableView:indexPath chat:chat];
[cell update];
}
[cell setChatRoomDelegate:_chatRoomDelegate];
[super accessoryForCell:cell atPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
@ -378,6 +379,13 @@ static const int BASIC_EVENT_LIST=15;
[_chatRoomDelegate tableViewIsScrolling];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
[ChatConversationViewSwift markAsRead:_chatRoom];
}
}
static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
@ -423,7 +431,7 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f;
title:NSLocalizedString(@"Reply", nil)
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
LinphoneChatMessage *msg = linphone_event_log_get_chat_message(event);
[VIEW(ChatConversationView) initiateReplyViewForMessage:msg];
[VIEW(ChatConversationViewSwift) initiateReplyViewForMessage:msg];
[self scrollToBottom:TRUE];
}];
@ -443,12 +451,11 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f;
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
UIContextualAction *imdnAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:NSLocalizedString(@"Info", nil)
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
LinphoneChatMessage *msg = linphone_event_log_get_chat_message(event);
ChatConversationImdnView *view = VIEW(ChatConversationImdnView);
view.msg = msg;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
title:NSLocalizedString(@"Info", nil)
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
ChatConversationImdnView *view = VIEW(ChatConversationImdnView);
view.event = event;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}];
UISwipeActionsConfiguration *swipeActionConfig;

View file

@ -63,6 +63,7 @@
@property(nonatomic) LinphoneChatRoomCbs *chatRoomCbs;
@property(nonatomic) Boolean markAsRead;
@property(nonatomic) const char *peerAddress;
@property(nonatomic) const char *localAddress;
@property (strong, nonatomic) FileDataSource *FileDataSource;
@ -112,6 +113,7 @@
@property LinphonePlayer *sharedVoicePlayer;
@property BOOL showVoiceRecorderView;
@property BOOL preservePendingActions;
@property BOOL *sharingMedia;
// Reply
@property (weak, nonatomic) IBOutlet UIView *replyView;

View file

@ -139,7 +139,7 @@ static UICompositeViewDescription *compositeDescription = nil;
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:nil
tabBar:IPAD ? TabBarView.class :nil
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:NO
@ -196,7 +196,8 @@ static UICompositeViewDescription *compositeDescription = nil;
_vrInnerView.layer.masksToBounds = YES;
_vrWaveMaskPlayer.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_L"]]; // rgba(1,88,7,0.2);
_showVoiceRecorderView = false;
_toggleMenuButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
_toggleRecord.imageView.contentMode = UIViewContentModeScaleAspectFit;
}
- (void)refreshData {
@ -212,10 +213,17 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!_chatRoom)
[self onLinphoneCoreReady:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(applicationWillEnterBackground)
selector:@selector(applicationDidEnterBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(applicationWillEnterForeground)
name:UIApplicationWillEnterForegroundNotification
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
@ -232,10 +240,10 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onLinphoneCoreReady:)
name:kLinphoneGlobalStateUpdate
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onLinphoneCoreReady:)
name:kLinphoneGlobalStateUpdate
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(endVoicePlayingIfDoingSO:)
@ -246,24 +254,23 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(endVoicePlayingIfDoingSO:)
name:kLinphoneVoiceMessagePlayerEOF
object:nil];
if ([_fileContext count] > 0) {
[UIView animateWithDuration:0
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
// resizing imagesView
CGRect imagesFrame = [_imagesView frame];
imagesFrame.origin.y = [_messageView frame].origin.y - 120;
imagesFrame.size.height = 120;
[_imagesView setFrame:imagesFrame];
// resizing chatTable
CGRect tableViewFrame = [_tableController.tableView frame];
tableViewFrame.size.height -= 120;
[_tableController.tableView setFrame:tableViewFrame];
[self updateFramesInclRecordingAndReplyView];
}
completion:nil];
}
if ([_fileContext count] > 0) {
[UIView animateWithDuration:0
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
// resizing imagesView
CGRect imagesFrame = [_imagesView frame];
imagesFrame.origin.y = [_messageView frame].origin.y - 120;
imagesFrame.size.height = 120;
[_imagesView setFrame:imagesFrame];
// resizing chatTable
CGRect tableViewFrame = [_tableController.tableView frame];
tableViewFrame.size.height -= 120;
[_tableController.tableView setFrame:tableViewFrame];
[self updateFramesInclRecordingAndReplyView];
} completion:nil];
}
[self configureForRoom:self.editing];
// Resize the popup table depending on wether ephemeral messages are enabled or not.
@ -273,12 +280,13 @@ static UICompositeViewDescription *compositeDescription = nil;
// Voice recording & Replies
_vrView.hidden = true;
_toggleRecord.enabled = linphone_core_get_calls_nb(LC) == 0;
_toggleRecord.enabled = linphone_core_get_calls_nb(LC) == 0;
_replyView.hidden = true;
_preservePendingActions = false;
_toggleRecord.enabled = linphone_core_get_calls_nb(LC) == 0;
[PhoneMainView.instance hideTabBar:!IPAD];
}
- (void)viewWillDisappear:(BOOL)animated {
@ -307,6 +315,8 @@ static UICompositeViewDescription *compositeDescription = nil;
[NSNotificationCenter.defaultCenter removeObserver:self];
PhoneMainView.instance.currentRoom = NULL;
[[UIApplication sharedApplication] setIdleTimerDisabled:false];
_chatRoom = NULL;
_tableController.chatRoom = nil;
}
- (void)removeCallBacks {
@ -323,27 +333,33 @@ static UICompositeViewDescription *compositeDescription = nil;
return;
}
composingVisible = !composingVisible;
[self setComposingVisible:!composingVisible withDelay:0];
// force offset recomputing
[_messageField refreshHeight];
LinphoneAddress *peerAddr = linphone_core_create_address([LinphoneManager getLc], _peerAddress);
if (peerAddr) {
_chatRoom = linphone_core_get_chat_room([LinphoneManager getLc], peerAddr);
isOneToOne = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesOneToOne;
isEncrypted = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesEncrypted;
LinphoneAddress *localAddr = linphone_core_create_address([LinphoneManager getLc], _localAddress);
if (peerAddr && localAddr) {
_chatRoom = linphone_core_search_chat_room([LinphoneManager getLc], NULL, localAddr, peerAddr, NULL);
if (_chatRoom) {
isOneToOne = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesOneToOne;
isEncrypted = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesEncrypted;
[self setComposingVisible:!composingVisible withDelay:0];
[self configureForRoom:true];
[_tableController scrollToBottom:true];
}
}
[self configureForRoom:true];
_backButton.hidden = _tableController.isEditing;
[_tableController scrollToBottom:true];
[self refreshImageDrawer];
[self stopAllPlays];
if (peerAddr) linphone_address_unref(peerAddr);
if (localAddr) linphone_address_unref(localAddr);
_backButton.hidden = _tableController.isEditing;
[self refreshImageDrawer];
[self stopAllPlays];
[self keyboardWillHide:nil];
}
#pragma mark -
- (void)applicationWillEnterBackground{
- (void)applicationDidEnterBackground{
if (!_preservePendingActions)
[self cancelVoiceRecording];
else if (_isVoiceRecording)
@ -351,9 +367,18 @@ static UICompositeViewDescription *compositeDescription = nil;
if (!_preservePendingActions)
[self closePendingReply];
[self stopAllPlays];
_chatRoom = nil;
[_messageField resignFirstResponder];
}
- (void)applicationWillEnterForeground{
if (_chatRoom == nil) {
if (linphone_core_get_calls_nb(LC) == 0)
[SVProgressHUD show];
else
[self onLinphoneCoreReady:nil];
}
}
- (void)configureForRoom:(BOOL)editing {
if (!_chatRoom) {
@ -373,7 +398,7 @@ static UICompositeViewDescription *compositeDescription = nil;
linphone_chat_room_cbs_set_is_composing_received(_chatRoomCbs, on_chat_room_is_composing_received);
linphone_chat_room_cbs_set_conference_joined(_chatRoomCbs, on_chat_room_conference_joined);
linphone_chat_room_cbs_set_conference_left(_chatRoomCbs, on_chat_room_conference_left);
linphone_chat_room_cbs_set_security_event(_chatRoomCbs, on_chat_room_conference_alert);
linphone_chat_room_cbs_set_security_event(_chatRoomCbs, on_chat_room_conference_alert);
linphone_chat_room_cbs_set_user_data(_chatRoomCbs, (__bridge void*)self);
linphone_chat_room_add_callbacks(_chatRoom, _chatRoomCbs);
}
@ -395,6 +420,7 @@ static UICompositeViewDescription *compositeDescription = nil;
LinphoneParticipant *firstParticipant = participants ? (LinphoneParticipant *)participants->data : NULL;
const LinphoneAddress *addr = firstParticipant ? linphone_participant_get_address(firstParticipant) : linphone_chat_room_get_peer_address(_chatRoom);
[ContactDisplay setDisplayNameLabel:_addressLabel forAddress:addr];
bctbx_list_free(participants);
} else
_addressLabel.text = [NSString stringWithUTF8String:linphone_chat_room_get_subject(_chatRoom) ?: LINPHONE_DUMMY_SUBJECT];
@ -426,7 +452,7 @@ static UICompositeViewDescription *compositeDescription = nil;
if (!room)
return true;
LinphoneChatRoomCapabilitiesMask capabilities = linphone_chat_room_get_capabilities(room);
return capabilities & LinphoneChatRoomCapabilitiesBasic;
return capabilities & LinphoneChatRoomCapabilitiesEncrypted;
}
@ -466,7 +492,7 @@ static UICompositeViewDescription *compositeDescription = nil;
//file shared from photo lib
NSString *fileName = dict[@"url"];
[_messageField setText:dict[@"message"]];
[self confirmShare:[self nsDataRead] url:nil fileName:fileName];
[self confirmShare:[self nsDataRead] url:nil fileName:fileName];
[defaults removeObjectForKey:@"photoData"];
} else if (dictFile) {
NSString *fileName = dictFile[@"url"];
@ -483,23 +509,26 @@ static UICompositeViewDescription *compositeDescription = nil;
// reload the chatroom after the core starts
- (void)onLinphoneCoreReady:(NSNotification *)notif {
if ((LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn) {
LinphoneAddress *peerAddr = linphone_core_create_address([LinphoneManager getLc], _peerAddress);
if (peerAddr) {
_chatRoom = linphone_core_get_chat_room([LinphoneManager getLc], peerAddr);
isOneToOne = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesOneToOne;
isEncrypted = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesEncrypted;
}
[self configureForRoom:self.editing];
if (_chatRoom && _markAsRead) {
if (IPAD) {
[VIEW(ChatsListView).tableController loadData];
if (linphone_core_get_global_state(LC) == LinphoneGlobalOn) {
LinphoneAddress *peerAddr = linphone_core_create_address([LinphoneManager getLc], _peerAddress);
LinphoneAddress *localAddr = linphone_core_create_address([LinphoneManager getLc], _localAddress);
if (peerAddr && localAddr) {
_chatRoom = linphone_core_search_chat_room([LinphoneManager getLc], NULL, localAddr, peerAddr, NULL);
if (_chatRoom) {
isOneToOne = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesOneToOne;
isEncrypted = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesEncrypted;
[self configureForRoom:self.editing];
if (_chatRoom && _markAsRead) {
if (IPAD) {
[VIEW(ChatsListView).tableController loadData];
}
[ChatConversationView markAsRead:_chatRoom];
}
_markAsRead = TRUE;
}
[ChatConversationView markAsRead:_chatRoom];
}
_markAsRead = TRUE;
}
}
[SVProgressHUD dismiss];
}
}
- (void)callUpdateEvent:(NSNotification *)notif {
@ -598,9 +627,9 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)confirmShare:(NSData *)data url:(NSString *)url fileName:(NSString *)fileName {
DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:@""];
DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Select or create a conversation to share the file(s)", nil)];
dispatch_async(dispatch_get_main_queue(), ^{
[sheet addButtonWithTitle:NSLocalizedString(@"send to this conversation", nil)
[sheet addButtonWithTitle:NSLocalizedString(@"Send to this conversation", nil)
block:^() {
if (![[self.messageField text] isEqualToString:@""]) {
[self sendMessageInMessageField:linphone_chat_room_create_empty_message(_chatRoom)];
@ -657,6 +686,11 @@ static UICompositeViewDescription *compositeDescription = nil;
completion:^(BOOL finished) {
_composeIndicatorView.hidden = !visible;
}];
if (visible) {
if (_tableController.tableView.contentOffset.y + newComposingFrame.size.height >= (_tableController.tableView.contentSize.height - _tableController.tableView.frame.size.height - 1)) {
[_tableController scrollToBottom:TRUE];
}
}
}
- (BOOL) groupCallAvailable {
@ -771,9 +805,9 @@ static UICompositeViewDescription *compositeDescription = nil;
// if we're showing the compose message, update it position
if (![_composeLabel isHidden]) {
CGRect frame = [_composeLabel frame];
CGRect frame = [_composeIndicatorView frame];
frame.origin.y -= diff;
[_composeLabel setFrame:frame];
[_composeIndicatorView setFrame:frame];
}
}
}
@ -781,7 +815,15 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)event {
[PhoneMainView.instance popCurrentView];
NSString *previousViewName = [PhoneMainView.instance getPreviousViewName];
_sharingMedia = nil;
if ([previousViewName isEqualToString:@"ContactDetailsView"]) {
ContactDetailsView *view = VIEW(ContactDetailsView);
[PhoneMainView.instance popToView:view.compositeViewDescription];
} else {
ChatsListView *view = VIEW(ChatsListView);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
}
- (IBAction)onEditClick:(id)event {
@ -937,6 +979,7 @@ static UICompositeViewDescription *compositeDescription = nil;
view.oldSubject = [NSString stringWithUTF8String:linphone_chat_room_get_subject(_chatRoom) ?: LINPHONE_DUMMY_SUBJECT];
view.room = _chatRoom;
view.peerAddress = _peerAddress;
view.localAddress = _localAddress;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
@ -1049,84 +1092,86 @@ static UICompositeViewDescription *compositeDescription = nil;
}
+ (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType {
NSString *filePath = [LinphoneManager validFilePath:name];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePath]) {
NSData* data = [NSData dataWithContentsOfFile:filePath];
if (![LinphoneManager.instance lpConfigBoolForKey:@"vfs_enabled_mode"]) {
NSString *filePath = [LinphoneManager validFilePath:name];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePath]) {
NSData* data = [NSData dataWithContentsOfFile:filePath];
// define a block , not called immediately. To avoid crash when saving photo before PHAuthorizationStatusNotDetermined.
void (^block)(void)= ^ {
if ([fileType isEqualToString:@"image"] ) {
// we're finished, save the image and update the message
UIImage *image = [UIImage imageWithData:data];
if (!image) {
ChatConversationView *view = VIEW(ChatConversationView);
[view showFileDownloadError];
return;
// define a block , not called immediately. To avoid crash when saving photo before PHAuthorizationStatusNotDetermined.
void (^block)(void)= ^ {
if ([fileType isEqualToString:@"image"] ) {
// we're finished, save the image and update the message
UIImage *image = [UIImage imageWithData:data];
if (!image) {
ChatConversationView *view = VIEW(ChatConversationView);
[view showFileDownloadError];
return;
}
__block PHObjectPlaceholder *placeHolder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image];
placeHolder = [request placeholderForCreatedAsset];
} completionHandler:^(BOOL success, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]);
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write image to photo library",nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
} else {
LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]);
}
});
}];
} else if([fileType isEqualToString:@"video"]) {
__block PHObjectPlaceholder *placeHolder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]];
placeHolder = [request placeholderForCreatedAsset];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]);
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write video to photo library", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
} else {
LOGI(@"video saved to [%@]", [placeHolder localIdentifier]);
}
});
}];
}
__block PHObjectPlaceholder *placeHolder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image];
placeHolder = [request placeholderForCreatedAsset];
} completionHandler:^(BOOL success, NSError *error) {
};
// When you save an image or video to a photo library, make sure that it is allowed. Otherwise, there will be a backup error.
if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) {
block();
} else {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]);
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write image to photo library",nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) {
block();
} else {
LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]);
}
});
}];
} else if([fileType isEqualToString:@"video"]) {
__block PHObjectPlaceholder *placeHolder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]];
placeHolder = [request placeholderForCreatedAsset];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]);
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil)
message:NSLocalizedString(@"Cannot write video to photo library", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
} else {
LOGI(@"video saved to [%@]", [placeHolder localIdentifier]);
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Photo's permission", nil) message:NSLocalizedString(@"Photo not authorized", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil] show];
}
});
}];
}
};
// When you save an image or video to a photo library, make sure that it is allowed. Otherwise, there will be a backup error.
if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) {
block();
} else {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) {
block();
} else {
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Photo's permission", nil) message:NSLocalizedString(@"Photo not authorized", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil] show];
}
});
}];
}
}
}
@ -1415,12 +1460,11 @@ void on_chat_room_chat_message_received(LinphoneChatRoom *cr, const LinphoneEven
bool isDisplayingBottomOfTable = [view.tableController.tableView indexPathsForVisibleRows].lastObject.row == [view.tableController totalNumberOfItems] - 1;
[view.tableController addEventEntry:(LinphoneEventLog *)event_log];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:view];
if (isDisplayingBottomOfTable) {
[view.tableController scrollToBottom:TRUE];
} else {
[[view.tableController scrollBadge] setHidden:FALSE];
int unread_msg = linphone_chat_room_get_unread_messages_count(cr);
[[view.tableController scrollBadge] setText:[NSString stringWithFormat:@"%d", unread_msg]];
}
@ -1721,13 +1765,6 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
}
}
-(BOOL) isConversationMuted {
return FALSE; // TODO
}
-(void) toggleMuteConversation {
// TODO
}
-(void) showAddressAndIdentityPopup {
char *localAddress = linphone_address_as_string(linphone_chat_room_get_local_address(_chatRoom));
@ -1754,8 +1791,7 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
}
-(BOOL) canAdminEphemeral:(const LinphoneChatRoom *)cr {
if (!cr) return FALSE;
if ([ChatConversationView isBasicChatRoom:_chatRoom]) return FALSE;
if (!cr || !isEncrypted) return FALSE;
// If ephemeral mode is DeviceManaged, then we don't need to check anything else
return (linphone_chat_room_params_get_ephemeral_mode(linphone_chat_room_get_current_params(cr)) == LinphoneChatRoomEphemeralModeDeviceManaged)
@ -1773,42 +1809,57 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
_popupMenu.layer.masksToBounds = false;
_toggleMenuButton.hidden = false;
_popupMenu.tableFooterView = [UIView new];
_popupMenu.separatorStyle = UITableViewCellSeparatorStyleNone;
[_popupMenu reloadData];
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self onToggleMenu:nil];
BOOL isEncrypted = ![ChatConversationView isBasicChatRoom:_chatRoom];
if (indexPath.row == 0) {
int firstIndex = isOneToOne ? 0 : 1;
if (!isOneToOne && indexPath.row == 0) { //Schedule meeting
[ConferenceViewModelBridge scheduleFromGroupChatWithCChatRoom:_chatRoom];
[PhoneMainView.instance popToView:ConferenceSchedulingView.compositeViewDescription];
}
if (indexPath.row == firstIndex) {
if (isOneToOne) {
[self addOrGoToContact:linphone_chat_room_get_peer_address(_chatRoom)];
if (isEncrypted) {
LinphoneAddress* contactAddress = linphone_address_clone(linphone_participant_get_address(bctbx_list_nth_data(linphone_chat_room_get_participants(_chatRoom), 0)));
linphone_address_clean(contactAddress);
[self addOrGoToContact:contactAddress];
linphone_address_unref(contactAddress);
} else {
[self addOrGoToContact:linphone_chat_room_get_peer_address(_chatRoom)];
}
} else {
[self displayGroupInfo];
}
}
if (isEncrypted && indexPath.row == 1) {
if (isEncrypted && indexPath.row == 1+firstIndex) {
[self goToDeviceListView];
}
BOOL canEphemeral = [self canAdminEphemeral:_chatRoom];
if (canEphemeral && indexPath.row == 2) {
if (canEphemeral && indexPath.row == 2+firstIndex) {
EphemeralSettingsView *view = VIEW(EphemeralSettingsView);
view.room = _chatRoom;
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
if ((!isEncrypted && indexPath.row == 1) || (isEncrypted && indexPath.row == 3)) {
[self toggleMuteConversation];
if ((!isEncrypted && indexPath.row == 1+firstIndex) || (isEncrypted && indexPath.row == 3+firstIndex)) {
[LinphoneManager setChatroomPushEnabled:_chatRoom withPushEnabled:![LinphoneManager getChatroomPushEnabled:_chatRoom]];
[_popupMenu reloadData];
}
if ((!isEncrypted && indexPath.row == 2) || (isEncrypted && indexPath.row == 4)) {
if ((!isEncrypted && indexPath.row == 2+firstIndex) || (isEncrypted && indexPath.row == 4+firstIndex)) {
[_tableController onEditClick:nil];
[self onEditionChangeClick:nil];
}
if ((isEncrypted && ((!canEphemeral && indexPath.row == 4)||(canEphemeral && indexPath.row == 5)))
|| (!isEncrypted && indexPath.row == 3)) {
if ((isEncrypted && ((!canEphemeral && indexPath.row == 4+firstIndex)||(canEphemeral && indexPath.row == 5+firstIndex)))
|| (!isEncrypted && indexPath.row == 3+firstIndex)) {
[self showAddressAndIdentityPopup];
}
}
@ -1831,61 +1882,89 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
if ([self canAdminEphemeral:_chatRoom])
++nbRows;
if (!isOneToOne) // schedule meeting
++nbRows;
return nbRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] init];
if (indexPath.row == 0) {
if (!_chatRoom) {
// Workaround to avoid crash in background for release 4.7. This shouldn't happen though, so there may be a deeper issue not found yet
return cell;
}
int firstIndex = isOneToOne ? 0 : 1;
if (!isOneToOne && indexPath.row == 0) {
cell.imageView.image = [UIImage imageNamed:@"menu_voip_meeting_schedule"];
cell.textLabel.text = NSLocalizedString(@"Schedule a meeting",nil);
}
if (indexPath.row == firstIndex) {
if (isOneToOne) {
Contact *contact = [FastAddressBook getContactWithAddress:linphone_chat_room_get_peer_address(_chatRoom)];
Contact *contact;
if (isEncrypted) {
LinphoneAddress * contactAddress = linphone_address_clone(linphone_participant_get_address(bctbx_list_nth_data(linphone_chat_room_get_participants(_chatRoom), 0)));
linphone_address_clean(contactAddress);
contact = [FastAddressBook getContactWithAddress:contactAddress];
linphone_address_unref(contactAddress);
} else {
contact = [FastAddressBook getContactWithAddress:linphone_chat_room_get_peer_address(_chatRoom)];
}
if (contact == nil) {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"contact_add_default.png"] newSize:CGSizeMake(20, 25)];
cell.imageView.image = [UIImage imageNamed:@"contact_add_default.png"];
cell.textLabel.text = NSLocalizedString(@"Add to contacts",nil);
} else {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"contacts_all_default.png"] newSize:CGSizeMake(20, 25)];
cell.imageView.image = [UIImage imageNamed:@"contacts_all_default.png"];
cell.textLabel.text = NSLocalizedString(@"Go to contact",nil);
}
} else {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"chat_group_informations.png"] newSize:CGSizeMake(25, 25)];
cell.imageView.image = [UIImage imageNamed:@"chat_group_informations.png"];
cell.textLabel.text = NSLocalizedString(@"Group infos",nil);
}
}
if (isEncrypted && indexPath.row == 1) {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"menu_security_default.png"] newSize:CGSizeMake(20, 25)];
if (isEncrypted && indexPath.row == 1+firstIndex) {
cell.imageView.image = [UIImage imageNamed:@"menu_security_default.png"];
cell.textLabel.text = NSLocalizedString(@"Conversation's devices",nil);
}
bool canEphemeral = [self canAdminEphemeral:_chatRoom];
if (canEphemeral && indexPath.row == 2) {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"ephemeral_messages_default.png"] newSize:CGSizeMake(20, 25)];
if (canEphemeral && indexPath.row == 2+firstIndex) {
cell.imageView.image = [UIImage imageNamed:@"ephemeral_messages_default.png"];
cell.textLabel.text = NSLocalizedString(@"Ephemeral messages",nil);
}
if ((isEncrypted && indexPath.row == 3) || (!isEncrypted && indexPath.row == 1)) {
if ([self isConversationMuted]) {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"menu_notifications_off.png"] newSize:CGSizeMake(20, 25)];
cell.textLabel.text = NSLocalizedString(@"NOT IMPLEMENTED",nil);
if ((isEncrypted && indexPath.row == 3+firstIndex) || (!isEncrypted && indexPath.row == 1+firstIndex)) {
if ([LinphoneManager getChatroomPushEnabled:_chatRoom]) {
cell.imageView.image = [UIImage imageNamed:@"menu_notifications_off.png"];
cell.textLabel.text = NSLocalizedString(@"Mute notifications",nil);
} else {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"menu_notifications_on.png"] newSize:CGSizeMake(20, 25)];
cell.textLabel.text = NSLocalizedString(@"NOT IMPLEMENTED",nil);
cell.imageView.image = [UIImage imageNamed:@"menu_notifications_on.png"];
cell.textLabel.text = NSLocalizedString(@"Un-mute notifications",nil);
}
}
if ((isEncrypted && indexPath.row == 4) || (!isEncrypted && indexPath.row == 2)) {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"delete_default.png"] newSize:CGSizeMake(20, 25)];
if ((isEncrypted && indexPath.row == 4+firstIndex) || (!isEncrypted && indexPath.row == 2+firstIndex)) {
cell.imageView.image = [UIImage imageNamed:@"delete_default.png"];
cell.textLabel.text = NSLocalizedString(@"Delete messages",nil);
}
if ((isEncrypted && ((!canEphemeral && indexPath.row == 4)||(canEphemeral && indexPath.row == 5)))
|| (!isEncrypted && indexPath.row == 3)) {
cell.imageView.image = [LinphoneUtils resizeImage:[UIImage imageNamed:@"chat_group_informations.png"] newSize:CGSizeMake(25, 25)];
cell.textLabel.text = NSLocalizedString(@"Show address and identity",nil);
if ((isEncrypted && ((!canEphemeral && indexPath.row == 4+firstIndex)||(canEphemeral && indexPath.row == 5+firstIndex)))
|| (!isEncrypted && indexPath.row == 3+firstIndex)) {
cell.imageView.image = [UIImage imageNamed:@"chat_group_informations.png"];
cell.textLabel.text = NSLocalizedString(@"Debug infos",nil);
}
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
UIImageView * icon = [[UIImageView alloc] initWithFrame:CGRectMake(tableView.frame.size.width-37, 7, 30, 30)];
icon.contentMode = UIViewContentModeScaleAspectFit;
icon.image = cell.imageView.image;
[cell.contentView addSubview:icon];
cell.imageView.image = nil;
return cell;
}
- (IBAction)onToggleMenu:(id)sender {
@ -2194,6 +2273,7 @@ void on_shared_player_eof_reached(LinphonePlayer *p) {
_showReplyView = true;
[self updateFramesInclRecordingAndReplyView];
[self.tableController scrollToMessage:message];
[self.messageField becomeFirstResponder];
}
-(void) handlePendingTransferIfAny {

View file

@ -31,4 +31,5 @@
- (void)loadData;
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom;
- (void)updateEventEntry:(LinphoneChatMessage *)msg;
@end

View file

@ -20,7 +20,7 @@
#import "ChatsListTableView.h"
#import "UIChatCell.h"
#import "FileTransferDelegate.h"
#import "linphoneapp-Swift.h"
#import "linphone/linphonecore.h"
#import "PhoneMainView.h"
#import "Utils.h"
@ -41,6 +41,11 @@
return self;
}
- (void)dealloc {
bctbx_list_free(_data);
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
@ -48,15 +53,53 @@
self.tableView.accessibilityIdentifier = @"Chat list";
[self loadData];
_chatRooms = NULL;
NSDictionary* userInfo;
[NSNotificationCenter.defaultCenter addObserver:self
selector: @selector(receivePresenceNotification:)
name: @"LinphoneFriendPresenceUpdate"
object: userInfo];
}
-(void) receivePresenceNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"LinphoneFriendPresenceUpdate"])
{
NSDictionary* userInfo = notification.userInfo;
NSString* friend = (NSString*)userInfo[@"friend"];
for (int i = 0; i < bctbx_list_size(_data); i++)
{
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)bctbx_list_nth_data(_data, i);
bctbx_list_t *participants = linphone_chat_room_get_participants(chatRoom);
if (linphone_chat_room_get_nb_participants(chatRoom) == 1) {
LinphoneParticipant *firstParticipant = participants ? (LinphoneParticipant *)participants->data : NULL;
char *curi = linphone_address_as_string_uri_only(linphone_participant_get_address(firstParticipant));
NSString *uri = [NSString stringWithUTF8String:curi];
LinphoneChatRoomCapabilitiesMask capabilities = linphone_chat_room_get_capabilities(chatRoom);
bool oneToOne = capabilities & LinphoneChatRoomCapabilitiesOneToOne;
if(oneToOne && [uri isEqual:friend]){
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:0];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
}
}
}
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// we cannot do that in viewWillAppear because we will change view while previous transition
// was not finished, leading to "[CALayer retain]: message sent to deallocated instance" error msg
/*
if (IPAD && [self totalNumberOfItems] > 0) {
[PhoneMainView.instance changeCurrentView:ChatConversationView.compositeViewDescription];
}
*/
}
- (void)viewWillDisappear:(BOOL)animated {
@ -72,6 +115,9 @@
}
_chatRooms = _chatRooms->next;
}
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneFriendPresenceUpdate" object:nil];
[AvatarBridge removeAllObserver];
}
- (void)layoutSubviews {
@ -114,6 +160,7 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
_data = [self sortChatRooms];
[super loadData];
/*
if (IPAD) {
int idx = bctbx_list_index(_data, VIEW(ChatConversationView).chatRoom);
// if conversation view is using a chatroom that does not exist anymore, update it
@ -125,20 +172,34 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
[LinphoneManager.instance lpConfigSetBool:FALSE forKey:@"create_chat"];
} else if (![self selectFirstRow]) {
ChatConversationCreateView *view = VIEW(ChatConversationCreateView);
[view fragmentCompositeDescription];
view.tableController.notFirstTime = FALSE;
view.isForVoipConference = FALSE;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
}
*/
}
- (void)updateEventEntry:(LinphoneChatMessage *)msg {
int idx = bctbx_list_index(_data, linphone_chat_message_get_chat_room(msg));
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
if (idx < 0) {
LOGW(@"event entry doesn't exist");
return;
}
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:FALSE];
}
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom {
int idx = bctbx_list_index(_data, VIEW(ChatConversationView).chatRoom);
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
/*
if (IPAD) {
UIChatCell *cell = (UIChatCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell updateUnreadBadge];
}
*/
}
#pragma mark - UITableViewDataSource Functions
@ -163,7 +224,7 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
[cell setChatRoom:(LinphoneChatRoom *)bctbx_list_nth_data(_data, (int)[indexPath row])];
[super accessoryForCell:cell atPath:indexPath];
BOOL forwardMode = VIEW(ChatConversationView).pendingForwardMessage != nil;
BOOL forwardMode = VIEW(ChatConversationViewSwift).pendingForwardMessage != nil;
cell.forwardIcon.hidden = !forwardMode;
if (forwardMode) {
cell.ephemeral.hidden = true;
@ -185,12 +246,12 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
return;
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)bctbx_list_nth_data(_data, (int)[indexPath row]);
[PhoneMainView.instance goToChatRoom:chatRoom];
[PhoneMainView.instance goToChatRoomSwift:chatRoom];
}
void deletion_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_current_callbacks(cr);
ChatsListTableView *view = (__bridge ChatsListTableView *)linphone_chat_room_cbs_get_user_data(cbs) ?: NULL;
ChatsListTableView *view =cbs ? ((__bridge ChatsListTableView *)linphone_chat_room_cbs_get_user_data(cbs) ?: NULL) : NULL;
if (!view)
return;
@ -231,7 +292,9 @@ void deletion_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomStat
}
}
[ftdToDelete cancel];
// Re-enable push notification after deleting the chatroom, in order to get the notification if we are re-invited, or for secure 1-to-1 chatrooms.
[LinphoneManager setChatroomPushEnabled:chatRoom withPushEnabled:TRUE];
linphone_core_delete_chat_room(LC, chatRoom);
chatRooms = chatRooms->next;
}

View file

@ -40,7 +40,10 @@
- (IBAction)onAddGroupChatClick:(id)event;
- (IBAction)onAddClick:(id)event;
- (IBAction)onChatRoomSwiftClick:(id)event;
- (IBAction)onEditionChangeClick:(id)sender;
- (IBAction)onDeleteClick:(id)sender;
-(void) mediaSharing;
@end

View file

@ -21,6 +21,7 @@
#import "PhoneMainView.h"
#import "ChatConversationCreateView.h"
#import "linphoneapp-Swift.h"
@implementation ChatsListView
#pragma mark - ViewController Functions
@ -39,6 +40,10 @@
selector:@selector(ephemeralDeleted:)
name:kLinphoneEphemeralMessageDeletedInRoom
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(displayModeChanged)
name:kDisplayModeChanged
object:nil];
[_backToCallButton update];
self.tableController.waitView = _waitView;
[self setEditing:NO];
@ -54,20 +59,43 @@
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];*/
BOOL forwardMode = VIEW(ChatConversationView).pendingForwardMessage != nil;
[self mediaSharing];
}
- (void)mediaSharing{
BOOL forwardMode;
NSString* groupName = [NSString stringWithFormat:@"group.%@.linphoneExtension",[[NSBundle mainBundle] bundleIdentifier]];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName];
NSDictionary *dict = [defaults valueForKey:@"photoData"];
NSDictionary *dictFile = [defaults valueForKey:@"icloudData"];
NSDictionary *dictUrl = [defaults valueForKey:@"url"];
if(dict||dictFile||dictUrl) VIEW(ChatConversationViewSwift).sharingMedia = TRUE;
if(VIEW(ChatConversationViewSwift).sharingMedia == false){
forwardMode = VIEW(ChatConversationViewSwift).pendingForwardMessage != nil;
}else{
forwardMode = VIEW(ChatConversationViewSwift).sharingMedia != false;
}
_tableController.editButton.hidden = forwardMode;
_forwardTitle.text = NSLocalizedString(@"Select a discussion or create a new one",nil);
if(VIEW(ChatConversationViewSwift).sharingMedia == false){
_forwardTitle.text = NSLocalizedString(@"Select a discussion or create a new one",nil);
}
else{
_forwardTitle.text = NSLocalizedString(@"Select or create a conversation to share the file(s)",nil);
}
_forwardTitle.hidden = !forwardMode;
_cancelForwardButton.hidden = !forwardMode;
_tableController.tableView.frame = CGRectMake(0, 66 + (forwardMode ? _forwardTitle.frame.size.height : 0), _tableController.tableView.frame.size.width, self.view.frame.size.height - 66 - ( forwardMode ? _forwardTitle.frame.size.height : 0 ));
_addButton.frame = CGRectMake(forwardMode ? 82 : 0 , _addButton.frame.origin.y, _addButton.frame.size.width, _addButton.frame.size.height);
_addGroupChatButton.frame = CGRectMake(forwardMode ? 164 : 82 , _addGroupChatButton.frame.origin.y, _addGroupChatButton.frame.size.width, _addGroupChatButton.frame.size.height);
}
- (void)displayModeChanged{
[self.tableController.tableView reloadData];
}
- (void)ephemeralDeleted:(NSNotification *)notif {
//LinphoneChatRoom *r =[[notif.userInfo objectForKey:@"room"] intValue];
@ -117,6 +145,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)newChatCreate:(BOOL)isGroup {
ChatConversationCreateView *view = VIEW(ChatConversationCreateView);
[view fragmentCompositeDescription];
view.isForEditing = false;
view.isGroupChat = isGroup;
view.tableController.notFirstTime = FALSE;
@ -127,14 +156,18 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onAddGroupChatClick:(id)event {
[self newChatCreate:TRUE];
if (IPAD)
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil];
//if (IPAD)
//[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil];
}
- (IBAction)onChatRoomSwiftClick:(id)event {
[PhoneMainView.instance changeCurrentView:ChatConversationViewSwift.compositeViewDescription];
}
- (IBAction)onAddClick:(id)event {
[self newChatCreate:FALSE];
if (IPAD)
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil];
//if (IPAD)
//[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil];
}
- (IBAction)onEditionChangeClick:(id)sender {
@ -172,8 +205,16 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (IBAction)onCancelForwardClicked:(id)sender {
VIEW(ChatConversationView).pendingForwardMessage = nil;
VIEW(ChatConversationViewSwift).sharingMedia = false;
VIEW(ChatConversationViewSwift).pendingForwardMessage = nil;
NSString* groupName = [NSString stringWithFormat:@"group.%@.linphoneExtension",[[NSBundle mainBundle] bundleIdentifier]];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName];
[defaults removeObjectForKey:@"photoData"];
[defaults removeObjectForKey:@"icloudData"];
[defaults removeObjectForKey:@"url"];
[PhoneMainView.instance popCurrentView];
}
@end

View file

@ -31,11 +31,12 @@
@property(nonatomic, retain) NSString *identifier;
@property(nonatomic, retain) NSString *firstName;
@property(nonatomic, retain) NSString *lastName;
@property(nonatomic, retain) NSString *organizationName;
@property(nonatomic, retain) NSString *displayName;
@property(nonatomic, strong) NSMutableArray *sipAddresses;
@property(nonatomic, strong) NSMutableArray *emails;
@property(nonatomic, strong) NSMutableArray *phones;
@property BOOL createdFromLdap;
@property BOOL createdFromLdapOrProvisioning;
@property BOOL added;
- (void)setAvatar:(UIImage *)avatar;
@ -58,4 +59,6 @@
- (BOOL)removeSipAddressAtIndex:(NSInteger)index;
- (BOOL)removePhoneNumberAtIndex:(NSInteger)index;
- (BOOL)removeEmailAtIndex:(NSInteger)index;
- (NSMutableArray*)getSipAddressesWithoutDuplicatePhoneNumbers;
@end

View file

@ -36,7 +36,7 @@
_person = acncontact;
_friend = afriend ? linphone_friend_ref(afriend) : NULL;
_added = FALSE;
_createdFromLdap = FALSE;
_createdFromLdapOrProvisioning = FALSE;
_phones = [[NSMutableArray alloc] init];
_sipAddresses = [[NSMutableArray alloc] init];
_emails = [[NSMutableArray alloc] init];
@ -44,6 +44,7 @@
_identifier = _person.identifier;
_firstName = _person.givenName;
_lastName = _person.familyName;
_organizationName = _person.organizationName;
_displayName = [NSString stringWithFormat:@"%@ %@", _firstName, _lastName];
for (CNLabeledValue<CNPhoneNumber *> *phoneNumber in _person.phoneNumbers) {
[_phones addObject:phoneNumber.value.stringValue];
@ -64,13 +65,17 @@
}
const char *key = [NSString stringWithFormat:@"ab%@", acncontact.identifier].UTF8String;
// try to find friend associated with that person
if (_friend){
linphone_friend_unref(_friend);
_friend = nil;
}
_friend = linphone_friend_list_find_friend_by_ref_key(linphone_core_get_default_friend_list(LC), key);
if (!_friend) {
_friend = linphone_friend_ref(linphone_core_create_friend(LC));
_friend = linphone_core_create_friend(LC);
linphone_friend_set_ref_key(_friend, key);
linphone_friend_set_name(_friend, [NSString stringWithFormat:@"%@%@", _firstName ? _firstName : @"", _lastName ? [_firstName ? @" " : @"" stringByAppendingString:_lastName] : @""] .UTF8String);
for (NSString *sipAddr in _sipAddresses) {
LinphoneAddress *addr = linphone_core_interpret_url(LC, sipAddr.UTF8String);
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, sipAddr.UTF8String, true);
if (addr) {
linphone_address_set_display_name(addr, [self displayName].UTF8String);
linphone_friend_add_address(_friend, addr);
@ -80,14 +85,15 @@
for (NSString *phone in _phones) {
linphone_friend_add_phone_number(_friend, phone.UTF8String);
}
if (_organizationName) {
linphone_friend_set_organization(_friend, [_organizationName UTF8String]);
}
if (_friend) {
linphone_friend_enable_subscribes(_friend, FALSE);
linphone_friend_set_inc_subscribe_policy(_friend, LinphoneSPDeny);
linphone_core_add_friend(LC, _friend);
}
}
linphone_friend_ref(_friend);
}else linphone_friend_ref(_friend);
} else if (_friend) {
[self loadFriend];
} else {
@ -287,7 +293,7 @@
[_person setValue:tmpSipAddresses forKey:CNContactInstantMessageAddressesKey];
ret = TRUE;
} else {
LinphoneAddress *addr = linphone_core_interpret_url(LC, sip.UTF8String) ?: linphone_address_new(sip.UTF8String);
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, sip.UTF8String, true) ?: linphone_address_new(sip.UTF8String);
if (!addr)
return FALSE;
@ -370,7 +376,7 @@
}
ret = TRUE;
} else {
LinphoneAddress *addr = linphone_core_interpret_url(LC, ((NSString *)_sipAddresses[index]).UTF8String);
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, ((NSString *)_sipAddresses[index]).UTF8String, true);
if (!addr)
return FALSE;
@ -461,11 +467,11 @@
// try to find friend associated with that person
_friend = linphone_friend_list_find_friend_by_ref_key(linphone_core_get_default_friend_list(LC), key);
if (!_friend) {
_friend = linphone_friend_ref(linphone_core_create_friend(LC));
_friend = linphone_core_create_friend(LC);
linphone_friend_set_ref_key(_friend, key);
linphone_friend_set_name(_friend, [NSString stringWithFormat:@"%@%@", _firstName ? _firstName : @"", _lastName ? [_firstName ? @" " : @"" stringByAppendingString:_lastName] : @""] .UTF8String);
for (NSString *sipAddr in _sipAddresses) {
LinphoneAddress *addr = linphone_core_interpret_url(LC, sipAddr.UTF8String);
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, sipAddr.UTF8String, true);
if (addr) {
linphone_address_set_display_name(addr, [self displayName].UTF8String);
linphone_friend_add_address(_friend, addr);
@ -480,12 +486,31 @@
linphone_friend_set_inc_subscribe_policy(_friend, LinphoneSPDeny);
linphone_core_add_friend(LC, _friend);
}
}
linphone_friend_ref(_friend);
} else linphone_friend_ref(_friend);
}
- (void)clearFriend {
if (_friend) linphone_friend_unref(_friend);
_friend = NULL;
}
- (NSMutableArray*)getSipAddressesWithoutDuplicatePhoneNumbers {
NSMutableArray* resAdresses = [[NSMutableArray alloc] init];
for (NSString *address in _sipAddresses) {
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, [address UTF8String], YES);
bool isFoundInPhones = false;
if (addr && linphone_address_get_username(addr)) {
for (NSString *phoneNb in _phones) {
if ([phoneNb isEqualToString:[NSString stringWithUTF8String:linphone_address_get_username(addr)]]) {
isFoundInPhones = true;
break;
}
}
}
if (!isFoundInPhones) [resAdresses addObject:address];
}
return resAdresses;
}
@end

View file

@ -27,6 +27,7 @@ typedef enum _ContactSections {
ContactSections_None = 0, // first section is empty because we cannot set header for first section
ContactSections_FirstName,
ContactSections_LastName,
ContactSections_Organization,
ContactSections_Sip,
ContactSections_Number,
ContactSections_Email,

View file

@ -139,7 +139,7 @@
}
- (BOOL)isValid {
BOOL hasName = (_contact.firstName.length + _contact.lastName.length > 0);
BOOL hasName = (_contact.firstName.length + _contact.lastName.length + _contact.organizationName.length > 0);
BOOL hasAddr =
(_contact.phones.count + _contact.sipAddresses.count) > 0;
return hasName && hasAddr;
@ -156,19 +156,19 @@
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == ContactSections_FirstName || section == ContactSections_LastName) {
if (section == ContactSections_FirstName || section == ContactSections_LastName || section == ContactSections_Organization) {
/*first and last name only when editting */
return (self.tableView.isEditing) ? 1 : 0;
} else if (section == ContactSections_Sip) {
return _contact.createdFromLdap ? 0 : _contact.sipAddresses.count;
return [_contact getSipAddressesWithoutDuplicatePhoneNumbers].count;
} else if (section == ContactSections_Number) {
return _contact.phones.count;
} else if (section == ContactSections_Email) {
BOOL showEmails = [LinphoneManager.instance
lpConfigBoolForKey:@"show_contacts_emails_preference"];
return showEmails ? _contact.emails.count : 0;
}
return 0;
return _contact.phones.count;
} else if (section == ContactSections_Email) {
BOOL showEmails = [LinphoneManager.instance
lpConfigBoolForKey:@"show_contacts_emails_preference"];
return showEmails ? _contact.emails.count : 0;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@ -192,6 +192,9 @@
} else if (indexPath.section == ContactSections_LastName) {
value = _contact.lastName;
[cell hideDeleteButton:YES];
} else if (indexPath.section == ContactSections_Organization) {
value = _contact.organizationName;
[cell hideDeleteButton:YES];
} else if ([indexPath section] == ContactSections_Number) {
value = _contact.phones[indexPath.row];
[cell.editTextfield setKeyboardType:UIKeyboardTypePhonePad];
@ -200,7 +203,7 @@
LinphoneAddress *addr = NULL;
if ([LinphoneManager.instance
lpConfigBoolForKey:@"contact_display_username_only"] &&
(addr = linphone_core_interpret_url(LC, [value UTF8String]))) {
(addr = linphone_core_interpret_url_2(LC, [value UTF8String], YES))) {
value =
[NSString stringWithCString:linphone_address_get_username(addr)
encoding:[NSString defaultCStringEncoding]];
@ -279,11 +282,14 @@
} else if (section == ContactSections_LastName && self.tableView.isEditing) {
text = NSLocalizedString(@"Last name", nil);
canAddEntry = NO;
} else if (section == ContactSections_Organization && self.tableView.isEditing) {
text = NSLocalizedString(@"Organization", nil);
canAddEntry = NO;
} else if ([self getSectionData:section].count > 0 || self.tableView.isEditing) {
if (section == ContactSections_Number) {
text = NSLocalizedString(@"Phone numbers", nil);
addEntryName = NSLocalizedString(@"Add new phone number", nil);
} else if (section == ContactSections_Sip && !_contact.createdFromLdap) {
} else if (section == ContactSections_Sip && !_contact.createdFromLdapOrProvisioning) {
text = NSLocalizedString(@"SIP addresses", nil);
addEntryName = NSLocalizedString(@"Add new SIP address", nil);
} else if (section == ContactSections_Email &&
@ -358,7 +364,7 @@
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == 0 ||
(!self.tableView.isEditing && (section == ContactSections_FirstName || section == ContactSections_LastName))) {
(!self.tableView.isEditing && (section == ContactSections_FirstName || section == ContactSections_LastName || section == ContactSections_LastName))) {
return 1e-5;
}
return [self tableView:tableView viewForHeaderInSection:section].frame.size.height;
@ -390,6 +396,9 @@
case ContactSections_LastName:
_contact.lastName = value;
break;
case ContactSections_Organization:
_contact.organizationName = value;
break;
case ContactSections_Sip:
[_contact setSipAddress:value atIndex:path.row];
value = _contact.sipAddresses[path.row]; // in case of reformatting

View file

@ -35,8 +35,9 @@
@property(nonatomic, strong) IBOutlet UIToggleButton *editButton;
@property(nonatomic, strong) IBOutlet UIButton *backButton;
@property(nonatomic, strong) IBOutlet UIButton *cancelButton;
@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage;
@property(weak, nonatomic) IBOutlet UIImageView *avatarImage;
@property(weak, nonatomic) IBOutlet UILabel *nameLabel;
@property(weak, nonatomic) IBOutlet UILabel *organizationLabel;
@property(weak, nonatomic) IBOutlet UIToggleButton *deleteButton;
@property(weak, nonatomic) IBOutlet UIScrollView *contentView;
@property(weak, nonatomic) IBOutlet UILabel *emptyLabel;

View file

@ -20,6 +20,7 @@
#import "ContactDetailsView.h"
#import "PhoneMainView.h"
#import "UIContactDetailsCell.h"
#import "linphoneapp-Swift.h"
@implementation ContactDetailsView
@ -63,7 +64,7 @@
}
LOGI(@"Reset data to contact %p", _contact);
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact]];
[_tableController setContact:_contact];
_emptyLabel.hidden = YES;
_avatarImage.hidden = !_emptyLabel.hidden;
@ -91,24 +92,25 @@
[PhoneMainView.instance popCurrentView];
return;
}
PhoneMainView.instance.currentName = _contact.displayName;
_nameLabel.text = PhoneMainView.instance.currentName;
// fix no sipaddresses in contact.friend
const MSList *sips = linphone_friend_get_addresses(_contact.friend);
while (sips) {
linphone_friend_remove_address(_contact.friend, sips->data);
sips = sips->next;
}
for (NSString *sipAddr in _contact.sipAddresses) {
LinphoneAddress *addr = linphone_core_interpret_url(LC, sipAddr.UTF8String);
if (addr) {
linphone_friend_add_address(_contact.friend, addr);
linphone_address_destroy(addr);
}
}
[LinphoneManager.instance.fastAddressBook saveContact:_contact];
PhoneMainView.instance.currentName = _contact.displayName;
_nameLabel.text = PhoneMainView.instance.currentName;
_organizationLabel.text = _contact.organizationName;
// fix no sipaddresses in contact.friend
const MSList *sips = linphone_friend_get_addresses(_contact.friend);
while (sips) {
linphone_friend_remove_address(_contact.friend, sips->data);
sips = sips->next;
}
for (NSString *sipAddr in _contact.sipAddresses) {
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, sipAddr.UTF8String, true);
if (addr) {
linphone_friend_add_address(_contact.friend, addr);
linphone_address_destroy(addr);
}
}
[LinphoneManager.instance.fastAddressBook saveContact:_contact];
}
- (void)selectContact:(Contact *)acontact andReload:(BOOL)reload {
@ -119,11 +121,12 @@
_contact = acontact;
_emptyLabel.hidden = (_contact != NULL);
_avatarImage.hidden = !_emptyLabel.hidden;
_deleteButton.hidden = !_emptyLabel.hidden || [_contact createdFromLdap];
_editButton.hidden = !_emptyLabel.hidden || [_contact createdFromLdap];
_deleteButton.hidden = !_emptyLabel.hidden || [_contact createdFromLdapOrProvisioning];
_editButton.hidden = !_emptyLabel.hidden || [_contact createdFromLdapOrProvisioning];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact]];
[ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact];
_organizationLabel.text = _contact.organizationName;
[_tableController setContact:_contact];
if (reload) {
@ -146,7 +149,7 @@
}
- (void)addCurrentContactContactField:(NSString *)address {
LinphoneAddress *linphoneAddress = linphone_core_interpret_url(LC, address.UTF8String);
LinphoneAddress *linphoneAddress = linphone_core_interpret_url_2(LC, address.UTF8String, true);
NSString *username =
linphoneAddress ? [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)] : address;
@ -284,6 +287,9 @@
if (IPAD && self.contact == NULL) {
_editButton.hidden = TRUE;
_deleteButton.hidden = TRUE;
} else if (self.contact != NULL && self.contact.createdFromLdapOrProvisioning) {
_editButton.hidden = TRUE;
_deleteButton.hidden = TRUE;
}
PhoneMainView.instance.currentName = _nameLabel.text;
// Update presence for contact
@ -296,6 +302,21 @@
[_editButton setImage:[UIImage imageNamed:@"valid_default.png"] forState:UIControlStateSelected];
[self updateBackOrCancelButton];
[self recomputeTableViewSize:FALSE];
NSDictionary* userInfo;
[NSNotificationCenter.defaultCenter addObserver:self
selector: @selector(receivePresenceNotification:)
name: @"LinphoneFriendPresenceUpdate"
object: userInfo];
}
-(void) receivePresenceNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"LinphoneFriendPresenceUpdate"])
{
[self resetData];
}
}
- (void)deviceOrientationDidChange:(NSNotification*)notif {
@ -310,9 +331,14 @@
}
}
if (self.contact != NULL && self.contact.createdFromLdapOrProvisioning) {
_editButton.hidden = TRUE;
_deleteButton.hidden = TRUE;
}
_nameLabel.hidden = self.tableController.isEditing;
_organizationLabel.hidden = self.tableController.isEditing;
[self updateBackOrCancelButton];
[self recomputeTableViewSize:_editButton.hidden];
[self recomputeTableViewSize:self.tableController.isEditing];
}
- (void)viewWillDisappear:(BOOL)animated {
@ -343,6 +369,9 @@
if (rm) {
[LinphoneManager.instance.fastAddressBook deleteContact:_contact];
}
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneFriendPresenceUpdate" object:nil];
[AvatarBridge removeAllObserver];
}
#pragma mark - UICompositeViewDelegate Functions
@ -397,7 +426,9 @@ static UICompositeViewDescription *compositeDescription = nil;
_cancelButton.hidden = !editing;
_backButton.hidden = editing;
_nameLabel.hidden = editing;
_organizationLabel.hidden = editing;
[ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact];
_organizationLabel.text = _contact.organizationName;
[self recomputeTableViewSize:editing];
@ -408,10 +439,11 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)recomputeTableViewSize:(BOOL)editing {
CGRect frame = _tableController.tableView.frame;
frame.origin.y = _avatarImage.frame.size.height + _avatarImage.frame.origin.y;
if ([self viewIsCurrentlyPortrait] && !editing) {
frame.origin.y += _nameLabel.frame.size.height;
}
frame.origin.y = _organizationLabel.frame.origin.y + _organizationLabel.frame.size.height;
} else {
frame.origin.y = _avatarImage.frame.size.height + _avatarImage.frame.origin.y;
}
frame.size.height = _tableController.tableView.contentSize.height;
_tableController.tableView.frame = frame;
@ -442,7 +474,7 @@ static UICompositeViewDescription *compositeDescription = nil;
_contact.firstName = _tmpContact.firstName.copy;
_contact.lastName = _tmpContact.lastName.copy;
_contact.avatar = _tmpContact.avatar.copy;
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact]];
while (_contact.sipAddresses.count > 0) {
[_contact removeSipAddressAtIndex:0];
@ -514,11 +546,11 @@ static UICompositeViewDescription *compositeDescription = nil;
}
NSString* previous = [PhoneMainView.instance getPreviousViewName];
if ([previous isEqualToString:@"ContactsListView"] || [previous isEqualToString:@"ImagePickerView"]) {
ContactsListView *view = VIEW(ContactsListView);
if ([previous isEqualToString:@"HistoryDetailsView"]) {
HistoryDetailsView *view = VIEW(HistoryDetailsView);
[PhoneMainView.instance popToView:view.compositeViewDescription];
} else {
HistoryDetailsView *view = VIEW(HistoryDetailsView);
ContactsListView *view = VIEW(ContactsListView);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
}
@ -588,7 +620,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[[store unifiedContactWithIdentifier:contactToCheck.identifier keysToFetch:keysToFetch error:nil] mutableCopy];
if(mCNContact == NULL){
for(NSString *address in contactToCheck.sipAddresses){
NSString *name = [FastAddressBook normalizeSipURI:address];
NSString *name = [FastAddressBook normalizeSipURI:address use_prefix:TRUE];
if([LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:name]){
return TRUE;
}
@ -619,7 +651,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[_contact setAvatar:image];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact]];
}
- (void)imagePickerDelegateVideo:(NSURL*)url info:(NSDictionary *)info {

View file

@ -60,6 +60,60 @@
[view setContact:nil];
}
}
NSDictionary* userInfo;
[NSNotificationCenter.defaultCenter addObserver:self
selector: @selector(receivePresenceNotification:)
name: @"LinphoneFriendPresenceUpdate"
object: userInfo];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneFriendPresenceUpdate" object:nil];
[AvatarBridge removeAllObserver];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
-(void) receivePresenceNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"LinphoneFriendPresenceUpdate"])
{
NSDictionary* userInfo = notification.userInfo;
NSString* friend = (NSString*)userInfo[@"friend"];
NSArray<NSIndexPath *> *indexPathsVisible = self.tableView.indexPathsForVisibleRows;
for (int i = 0; i < indexPathsVisible.count; i++)
{
NSMutableArray *subAr = [addressBookMap objectForKey:[addressBookMap keyAtIndex:indexPathsVisible[i].section]];
Contact *contact = subAr[indexPathsVisible[i].row];
if (contact.sipAddresses.count > 0){
for (NSString *sip in contact.sipAddresses) {
NSString *uri = [@"sip:" stringByAppendingString:sip];
if([uri isEqual:friend]){
NSIndexPath* indexPath = indexPathsVisible[i];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
}
}
}else if (contact.phones.count > 0){
for (NSString *phone in contact.phones) {
NSString *uri = phone;
if([uri isEqual:friend]){
NSIndexPath* indexPath = indexPathsVisible[i];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
}
}
}
}
}
}
- (id)init {
@ -231,7 +285,7 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
// Cached avatar
UIImage *image = [FastAddressBook imageForContact:contact];
[cell.avatarImage setImage:image bordered:NO withRoundedRadius:YES];
[cell.avatarImage setImage:image];
[cell setContact:contact];
[super accessoryForCell:cell atPath:indexPath];
cell.contentView.userInteractionEnabled = false;

View file

@ -50,14 +50,17 @@ typedef enum _ContactSelectionMode { ContactSelectionModeNone, ContactSelectionM
@property(strong, nonatomic) IBOutlet ContactsListTableView *tableController;
@property(strong, nonatomic) IBOutlet UIView *topBar;
@property(strong, nonatomic) IBOutlet UIView *switchView;
@property(nonatomic, strong) IBOutlet UIButton *allButton;
@property(nonatomic, strong) IBOutlet UIButton *linphoneButton;
@property(nonatomic, strong) IBOutlet UIButton *addButton;
@property(nonatomic, strong) IBOutlet UIButton *deleteButton;
@property(strong, nonatomic) IBOutlet UISearchBar *searchBar;
@property(weak, nonatomic) IBOutlet UIImageView *selectedButtonImage;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *toggleSelectionButton;
@property (weak, nonatomic) IBOutlet UILabel *loadingLabel;
@property (weak, nonatomic) IBOutlet UIView *loadingView;
@property (weak, nonatomic) IBOutlet UILabel *ldapMoreResultsLabel;
- (IBAction)onAllClick:(id)event;
- (IBAction)onLinphoneClick:(id)event;

View file

@ -60,6 +60,7 @@ static BOOL addAddressFromOthers = FALSE;
@synthesize allButton;
@synthesize linphoneButton;
@synthesize addButton;
@synthesize deleteButton;
@synthesize topBar;
typedef enum { ContactsAll, ContactsLinphone, ContactsMAX } ContactsCategory;
@ -96,7 +97,16 @@ static UICompositeViewDescription *compositeDescription = nil;
if (![[PhoneMainView.instance getPreviousViewName] isEqualToString:@"ContactDetailsView"]) {
_searchBar.text = @"";
}
[self changeView:ContactsAll];
if ([LinphoneManager.instance lpConfigBoolForKey:@"only_show_sip_contacts_list"]) {
_switchView.hidden = true;
[self changeView:ContactsLinphone];
} else if ([LinphoneManager.instance lpConfigBoolForKey:@"hide_sip_contacts_list"]){
_switchView.hidden = true;
[self changeView:ContactsAll];
} else {
[self changeView:ContactsAll];
}
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
@ -142,6 +152,15 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(onMagicSearchFinished:)
name:kLinphoneMagicSearchFinished
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onMagicSearchMoreAvailable:)
name:kLinphoneMagicSearchMoreAvailable
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(displayModeChanged)
name:kDisplayModeChanged
object:nil];
}
- (void)onMagicSearchStarted:(NSNotification *)k {
@ -150,6 +169,9 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)onMagicSearchFinished:(NSNotification *)k {
_loadingView.hidden = TRUE;
}
- (void)onMagicSearchMoreAvailable:(NSNotification *)k {
_ldapMoreResultsLabel.hidden = FALSE;
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(@"Debuglog viewDidAppear");
@ -225,7 +247,11 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)refreshButtons {
[addButton setHidden:FALSE];
[addButton setHidden:![LinphoneManager.instance lpConfigBoolForKey:@"enable_native_address_book"] || [LinphoneManager.instance lpConfigBoolForKey:@"read_only_native_address_book"]];
if ([LinphoneManager.instance lpConfigBoolForKey:@"read_only_native_address_book"]) {
addButton.hidden = true;
deleteButton.hidden = true;
}
[self changeView:[ContactSelection getSipFilterEnabled] ? ContactsLinphone : ContactsAll];
}
@ -250,6 +276,10 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
- (void)displayModeChanged{
[self.tableController.tableView reloadData];
}
- (IBAction)onDeleteClick:(id)sender {
NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete selected contacts?\nThey will also be deleted from your phone's address book.", nil)];
[LinphoneManager.instance setContactsUpdated:TRUE];
@ -268,6 +298,13 @@ static UICompositeViewDescription *compositeDescription = nil;
- (IBAction)onEditionChangeClick:(id)sender {
allButton.hidden = linphoneButton.hidden = _selectedButtonImage.hidden = addButton.hidden = self.tableController.isEditing;
if ([LinphoneManager.instance lpConfigBoolForKey:@"enable_native_address_book"]) {
addButton.hidden = self.tableController.isEditing;
}
if ([LinphoneManager.instance lpConfigBoolForKey:@"read_only_native_address_book"]) {
addButton.hidden = true;
deleteButton.hidden = true;
}
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
@ -292,6 +329,7 @@ static UICompositeViewDescription *compositeDescription = nil;
if (searchText.length == 0) {
[LinphoneManager.instance setContactsUpdated:TRUE];
}
_ldapMoreResultsLabel.hidden = TRUE;
[tableController loadDataWithFilter:searchText];
}
}

View file

@ -103,7 +103,7 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)sender {
ChatConversationView *view = VIEW(ChatConversationView);
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}

View file

@ -145,9 +145,17 @@ static UICompositeViewDescription *compositeDescription = nil;
[_videoCameraSwitch setHidden:FALSE];
}
}
[_addContactButton setImage:[UIImage imageNamed:@"voip_conference_new"] forState:UIControlStateNormal];
_addContactButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
_addContactButton.enabled = true;
LinphoneAccount *defaultAccount = linphone_core_get_default_account(LC);
if (!(defaultAccount && linphone_account_params_get_conference_factory_uri(linphone_account_get_params(defaultAccount)))){
[_addContactButton setImage:[UIImage imageNamed:@"contact_add_default"] forState:UIControlStateNormal];
_addContactButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
_addContactButton.enabled = true;
}else{
[_addContactButton setImage:[UIImage imageNamed:@"voip_conference_new"] forState:UIControlStateNormal];
_addContactButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
_addContactButton.enabled = true;
}
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
@ -175,10 +183,11 @@ static UICompositeViewDescription *compositeDescription = nil;
_padView.hidden = !IPAD && UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
if (linphone_core_get_calls_nb(LC)) {
_backButton.hidden = FALSE;
_addContactButton.hidden = TRUE;
} else {
_backButton.hidden = TRUE;
_addContactButton.hidden = FALSE;
}
_addContactButton.hidden = FALSE;
}
- (void)viewDidAppear:(BOOL)animated {
@ -276,16 +285,10 @@ static UICompositeViewDescription *compositeDescription = nil;
- (BOOL)displayDebugPopup:(NSString *)address {
LinphoneManager *mgr = LinphoneManager.instance;
NSString *debugAddress = [mgr lpConfigStringForKey:@"debug_popup_magic" withDefault:@""];
if (![debugAddress isEqualToString:@""] && [address isEqualToString:debugAddress]) {
if ((![debugAddress isEqualToString:@""] && [address isEqualToString:debugAddress]) || [_addressField.text isEqual: @"#1234#"]) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Debug", nil)
message:NSLocalizedString(@"Choose an action", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
int debugLevel = [LinphoneManager.instance lpConfigIntForKey:@"debugenable_preference"];
BOOL debugEnabled = (debugLevel >= ORTP_DEBUG && debugLevel < ORTP_ERROR);
@ -313,31 +316,24 @@ static UICompositeViewDescription *compositeDescription = nil;
}];
[errView addAction:logAction];
UIAlertAction* remAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Remove account(s) and self destruct", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
linphone_core_clear_accounts([LinphoneManager getLc]);
linphone_core_clear_all_auth_info([LinphoneManager getLc]);
@try {
[LinphoneManager.instance destroyLinphoneCore];
} @catch (NSException *e) {
LOGW(@"Exception while destroying linphone core: %@", e);
} @finally {
if ([NSFileManager.defaultManager
isDeletableFileAtPath:[LinphoneManager preferenceFile:@"linphonerc"]] == YES) {
[NSFileManager.defaultManager
removeItemAtPath:[LinphoneManager preferenceFile:@"linphonerc"]
error:nil];
}
#ifdef DEBUG
[LinphoneManager instanceRelease];
#endif
}
[UIApplication sharedApplication].keyWindow.rootViewController = nil;
// make the application crash to be sure that user restart it properly
LOGF(@"Self-destructing in 3..2..1..0!");
}];
[errView addAction:remAction];
UIAlertAction* configAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"View config file", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
TextViewer *view = VIEW(TextViewer);
LpConfig *conf = LinphoneManager.instance.configDb;
char *config = linphone_config_dump(conf);
view.textViewer = [NSString stringWithUTF8String: config];
view.textNameViewer = @"";
[PhoneMainView.instance popToView:view.compositeViewDescription];
}];
[errView addAction:configAction];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[self presentViewController:errView animated:YES completion:nil];
return true;
@ -392,19 +388,39 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Action Functions
- (IBAction)onAddContactClick:(id)event {
ConferenceSchedulingView *view = VIEW(ConferenceSchedulingView);
[view resetViewModel];
[PhoneMainView.instance changeCurrentView:ConferenceSchedulingView.compositeViewDescription];
LinphoneAccount *defaultAccount = linphone_core_get_default_account(LC);
if (!(defaultAccount && linphone_account_params_get_conference_factory_uri(linphone_account_get_params(defaultAccount)))){
[ContactSelection setSelectionMode:ContactSelectionModeEdit];
[ContactSelection setAddAddress:[_addressField text]];
[ContactSelection enableSipFilter:FALSE];
[PhoneMainView.instance changeCurrentView:ContactsListView.compositeViewDescription];
}else{
ConferenceSchedulingView *view = VIEW(ConferenceSchedulingView);
[view resetViewModel];
[PhoneMainView.instance changeCurrentView:ConferenceSchedulingView.compositeViewDescription];
}
}
- (IBAction)onBackClick:(id)event {
[PhoneMainView.instance popToView:ActiveCallOrConferenceView.compositeViewDescription];
[PhoneMainView.instance popToView:[CallsViewModelBridge callViewToDisplay]];
}
- (IBAction)onAddressChange:(id)sender {
if ([self displayDebugPopup:_addressField.text]) {
if ([_addressField.text isEqual: @"#1234#"]) {
[self displayDebugPopup:_addressField.text];
_addressField.text = @"";
}
LinphoneAccount *defaultAccount = linphone_core_get_default_account(LC);
if (!(defaultAccount && linphone_account_params_get_audio_video_conference_factory_address(linphone_account_get_params(defaultAccount)))){
[_addContactButton setImage:[UIImage imageNamed:@"contact_add_default"] forState:UIControlStateNormal];
_addContactButton.enabled = ([[_addressField text] length] > 0);
if ([_addressField.text length] == 0) {
[self.view endEditing:YES];
}
}else{
[_addContactButton setImage:[UIImage imageNamed:@"voip_conference_new"] forState:UIControlStateNormal];
_addContactButton.enabled = true;
}
}
- (IBAction)onBackspaceClick:(id)sender {

View file

@ -20,6 +20,7 @@
#import "EphemeralSettingsView.h"
#import "PhoneMainView.h"
#import "UIDeviceCell.h"
#import "linphoneapp-Swift.h"
@ -74,14 +75,14 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)sender {
ChatConversationView *view = VIEW(ChatConversationView);
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
- (IBAction)onSaveClick:(id)sender {
[self setRoomSettingsBasedOnIndex];
ChatConversationView *view = VIEW(ChatConversationView);
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}

View file

@ -69,14 +69,15 @@ static UICompositeViewDescription *compositeDescription = nil;
object:nil];
// Update on show
const MSList *list = linphone_core_get_account_list([LinphoneManager getLc]);
MSList *list = [LinphoneManager.instance createAccountsNotHiddenList];
if (list != NULL) {
LinphoneAccount *account = (LinphoneAccount *)list->data;
if (account) {
[self registrationUpdate:linphone_account_get_state(account)];
}
}
bctbx_list_free(list);
if (account_creator) {
linphone_account_creator_unref(account_creator);
}

View file

@ -8,66 +8,90 @@
import Foundation
import UIKit
public extension ChatConversationTableView {
extension ChatConversationTableViewSwift {
private enum Constants {
static let trailingValue: CGFloat = 20.0
static let trailingValue: CGFloat = 30.0
static let leadingValue: CGFloat = 85.0
static let buttonHeight: CGFloat = 40.0
static let buttonWidth: CGFloat = 40.0
static let buttonHeight: CGFloat = 16.0
static let buttonWidth: CGFloat = 16.0
}
/*
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
createFloatingButton()
}
*/
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let lastCellRowIndex = tableView.indexPathsForVisibleRows?.last?.row {
if( lastCellRowIndex != self.totalNumberOfItems() - 1) {
self.floatingScrollButton?.isHidden = false
self.scrollBadge?.isHidden = (self.scrollBadge?.text == nil)
} else {
self.floatingScrollButton?.isHidden = true
self.scrollBadge?.text = nil
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidAppear(animated)
self.floatingScrollButton?.removeFromSuperview()
self.floatingScrollBackground?.removeFromSuperview()
}
private func createFloatingButton() {
func createFloatingButton() {
self.floatingScrollButton = UIButton(type: .custom)
self.floatingScrollBackground = UIButton(type: .custom)
self.floatingScrollButton?.translatesAutoresizingMaskIntoConstraints = false
self.floatingScrollBackground?.translatesAutoresizingMaskIntoConstraints = false
constrainFloatingButtonToWindow()
self.floatingScrollButton?.setImage(UIImage(named: "scroll_to_bottom_default"), for: .normal)
self.floatingScrollButton?.addTarget(self, action: #selector(scrollToBottomButtonAction(_:)), for: .touchUpInside)
var imageFloatingScrollButton = UIImage()
if #available(iOS 13.0, *) {
imageFloatingScrollButton = UIImage(named: "scroll_to_bottom_default")!.withTintColor(.darkGray)
} else {
imageFloatingScrollButton = UIImage(named: "scroll_to_bottom_default")!
}
self.floatingScrollButton?.setImage(imageFloatingScrollButton, for: .normal)
self.floatingScrollButton?.isHidden = true;
addBadgeToButon(badge: nil)
self.floatingScrollBackground?.backgroundColor = .lightGray
self.floatingScrollBackground?.layer.cornerRadius = 25
self.floatingScrollBackground?.isHidden = true;
self.floatingScrollButton?.onClick(action: {
self.scrollToBottomButtonAction()
})
self.floatingScrollBackground?.onClick(action: {
self.scrollToBottomButtonAction()
})
addBadgeToButton(badge: nil)
}
private func constrainFloatingButtonToWindow() {
DispatchQueue.main.async {
guard let keyWindow = UIApplication.shared.keyWindow,
guard let keyWindow = self.view,
let floatingButton = self.floatingScrollButton else { return }
keyWindow.addSubview(self.floatingScrollBackground!)
keyWindow.addSubview(floatingButton)
keyWindow.trailingAnchor.constraint(equalTo: floatingButton.trailingAnchor,
constant: Constants.trailingValue).isActive = true
keyWindow.bottomAnchor.constraint(equalTo: floatingButton.bottomAnchor,
constant: Constants.leadingValue).isActive = true
keyWindow.trailingAnchor.constraint(equalTo: floatingButton.trailingAnchor, constant: Constants.trailingValue).isActive = true
floatingButton.bottomAnchor.constraint(equalTo: keyWindow.bottomAnchor, constant: -25).isActive = true
floatingButton.widthAnchor.constraint(equalToConstant:
Constants.buttonWidth).isActive = true
floatingButton.heightAnchor.constraint(equalToConstant:
Constants.buttonHeight).isActive = true
self.floatingScrollBackground?.centerYAnchor.constraint(equalTo: floatingButton.centerYAnchor).isActive = true
self.floatingScrollBackground?.centerXAnchor.constraint(equalTo: floatingButton.centerXAnchor).isActive = true
self.floatingScrollBackground!.widthAnchor.constraint(equalToConstant:
Constants.buttonHeight*3).isActive = true
self.floatingScrollBackground!.heightAnchor.constraint(equalToConstant:
Constants.buttonHeight*3).isActive = true
}
}
@IBAction private func scrollToBottomButtonAction(_ sender: Any) {
scroll(toBottom: true)
@IBAction private func scrollToBottomButtonAction() {
scrollToBottom(animated: false)
}
private func addBadgeToButon(badge: String?) {
private func addBadgeToButton(badge: String?) {
self.scrollBadge = UILabel()
self.scrollBadge?.text = badge
self.scrollBadge?.textColor = UIColor.white
@ -86,8 +110,8 @@ public extension ChatConversationTableView {
vertical = Double(badgeInset.top) - Double(badgeInset.bottom)
horizontal = Double(badgeInset.left) - Double(badgeInset.right)
let x = (Double(scrollButton.bounds.size.width) - 10 + horizontal!)
let y = -(Double(badgeSize.height) / 2) - 10 + vertical!
let x = (Double(scrollButton.bounds.size.width) + 34 + horizontal!)
let y = -(Double(badgeSize.height) / 2) - 38 + vertical!
self.scrollBadge?.frame = CGRect(x: x, y: y, width: width, height: height)
self.scrollBadge!.layer.cornerRadius = self.scrollBadge!.frame.height/2

View file

@ -20,6 +20,7 @@
#import "HistoryDetailsTableView.h"
#import "LinphoneManager.h"
#import "Utils.h"
#import "linphoneapp-Swift.h"
@implementation HistoryDetailsTableView
@ -89,7 +90,7 @@
[LinphoneUtils durationToString:duration]]];
BOOL outgoing = (linphone_call_log_get_dir(log) == LinphoneCallOutgoing);
if (linphone_call_log_get_status(log) == LinphoneCallMissed) {
if ([SwiftUtil isCallLogMissedWithCLog:log]) {
cell.imageView.image = [UIImage imageNamed:@"call_missed.png"];
} else if (outgoing) {
cell.imageView.image = [UIImage imageNamed:@"call_outgoing.png"];

View file

@ -31,7 +31,7 @@
}
@property(weak, nonatomic) IBOutlet UIButton *backButton;
@property(weak, nonatomic) IBOutlet UILabel *contactLabel;
@property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage;
@property(nonatomic, strong) IBOutlet UIImageView *avatarImage;
@property(nonatomic, strong) IBOutlet UILabel *addressLabel;
@property(nonatomic, strong) IBOutlet UIButton *addContactButton;
@property(nonatomic, copy, setter=setCallLogId:) NSString *callLogId;
@ -41,6 +41,7 @@
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property (weak, nonatomic) IBOutlet UIRoundedImageView *linphoneImage;
@property (weak, nonatomic) IBOutlet UIView *optionsView;
@property(weak, nonatomic) IBOutlet UIButton *chatButton;
@property (weak, nonatomic) IBOutlet UIView *encryptedChatView;
- (IBAction)onBackClick:(id)event;

View file

@ -20,6 +20,7 @@
#import "HistoryDetailsView.h"
#import "PhoneMainView.h"
#import "FastAddressBook.h"
#import "linphoneapp-Swift.h"
@implementation HistoryDetailsView
@ -68,6 +69,12 @@ static UICompositeViewDescription *compositeDescription = nil;
[_headerView addGestureRecognizer:headerTapGesture];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
_chatButton.hidden = [LinphoneManager.instance lpConfigBoolForKey:@"force_lime_chat_rooms"] || [LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"];
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[self update];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_waitView.hidden = YES;
@ -87,11 +94,27 @@ static UICompositeViewDescription *compositeDescription = nil;
selector: @selector(deviceOrientationDidChange:)
name: UIDeviceOrientationDidChangeNotification
object: nil];
NSDictionary* userInfo;
[NSNotificationCenter.defaultCenter addObserver:self
selector: @selector(receivePresenceNotification:)
name: @"LinphoneFriendPresenceUpdate"
object: userInfo];
}
-(void) receivePresenceNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"LinphoneFriendPresenceUpdate"])
{
[self update];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[NSNotificationCenter.defaultCenter removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneFriendPresenceUpdate" object:nil];
[AvatarBridge removeAllObserver];
}
#pragma mark - Event Functions
@ -144,7 +167,7 @@ static UICompositeViewDescription *compositeDescription = nil;
const LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog);
_addContactButton.hidden = ([FastAddressBook getContactWithAddress:addr] != nil);
[ContactDisplay setDisplayNameLabel:_contactLabel forAddress:addr withAddressLabel:_addressLabel];
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForAddress:addr]];
Contact *contact = [FastAddressBook getContactWithAddress:addr];
const LinphonePresenceModel *model = contact.friend ? linphone_friend_get_presence_model(contact.friend) : NULL;
_linphoneImage.hidden = [LinphoneManager.instance lpConfigBoolForKey:@"hide_linphone_contacts" inSection:@"app"] ||
@ -158,7 +181,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)shouldHideEncryptedChatView:(BOOL)hasLime {
_encryptedChatView.hidden = !hasLime;
_encryptedChatView.hidden = !hasLime || [LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"];
CGRect newFrame = _optionsView.frame;
if (!hasLime) {
newFrame.origin.x = _encryptedChatView.frame.size.width * 2/3;

View file

@ -71,6 +71,36 @@
name:kLinphoneCoreUpdate
object:nil];
[self loadData];
NSDictionary* userInfo;
[NSNotificationCenter.defaultCenter addObserver:self
selector: @selector(receivePresenceNotification:)
name: @"LinphoneFriendPresenceUpdate"
object: userInfo];
}
-(void) receivePresenceNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"LinphoneFriendPresenceUpdate"])
{
NSDictionary* userInfo = notification.userInfo;
NSString* friend = (NSString*)userInfo[@"friend"];
const MSList *list = linphone_core_get_call_logs(LC);
int i = 0;
while (list != NULL) {
LinphoneCallLog *log = (LinphoneCallLog *)list->data;
const char *curi = linphone_address_as_string_uri_only(linphone_call_log_get_remote_address(log));
NSString *uri = [NSString stringWithUTF8String:curi];
if([uri isEqual:friend]){
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:0];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
}
i = i + 1;
list = list->next;
}
}
}
- (void)viewWillDisappear:(BOOL)animated {
@ -79,6 +109,8 @@
[NSNotificationCenter.defaultCenter removeObserver:self name:kLinphoneAddressBookUpdate object:nil];
[NSNotificationCenter.defaultCenter removeObserver:self name:kLinphoneCoreUpdate object:nil];
[NSNotificationCenter.defaultCenter removeObserver:self name:kLinphoneCallUpdate object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneFriendPresenceUpdate" object:nil];
[AvatarBridge removeAllObserver];
}
#pragma mark - Event Functions
@ -153,7 +185,7 @@
self.sections = [NSMutableDictionary dictionary];
while (logs != NULL) {
LinphoneCallLog *log = (LinphoneCallLog *)logs->data;
BOOL keepIt = (!missedFilter || linphone_call_log_get_status(log) == LinphoneCallMissed) && (!confFilter||linphone_call_log_was_conference(log)) ;
BOOL keepIt = (!missedFilter || [SwiftUtil isCallLogMissedWithCLog:log]) && (!confFilter||linphone_call_log_was_conference(log)) ;
if (keepIt) {
NSDate *startDate = [self
dateAtBeginningOfDayForDate:[NSDate
@ -268,9 +300,13 @@
} else {
if (linphone_call_log_was_conference(callLog)) {
LinphoneConferenceInfo *confInfo = linphone_call_log_get_conference_info(callLog);
ConferenceWaitingRoomFragment *view = VIEW(ConferenceWaitingRoomFragment);
if (linphone_conference_info_get_state(confInfo) == LinphoneConferenceInfoStateCancelled) {
[ConferenceViewModelBridge showCancelledMeetingWithCConferenceInfo:confInfo];
return;
}
ConferenceWaitingRoomView *view = VIEW(ConferenceWaitingRoomView);
[view setDetailsWithSubject:[NSString stringWithUTF8String:linphone_conference_info_get_subject(confInfo)] url:[NSString stringWithUTF8String:linphone_address_as_string(linphone_conference_info_get_uri(confInfo))]];
[PhoneMainView.instance changeCurrentView:ConferenceWaitingRoomFragment.compositeViewDescription];
[PhoneMainView.instance changeCurrentView:ConferenceWaitingRoomView.compositeViewDescription];
} else {
const LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog);
[LinphoneManager.instance call:addr];

View file

@ -67,10 +67,15 @@ static UICompositeViewDescription *compositeDescription = nil;
// Fake event
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
[_toggleSelectionButton setImage:[UIImage imageNamed:@"select_all_default.png"] forState:UIControlStateSelected];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(displayModeChanged)
name:kDisplayModeChanged
object:nil];
}
- (void) viewWillDisappear:(BOOL)animated {
self.view = NULL;
[NSNotificationCenter.defaultCenter removeObserver:self];
}
#pragma mark -
@ -100,6 +105,10 @@ static UICompositeViewDescription *compositeDescription = nil;
_selectedButtonImage.frame = frame;
}
- (void)displayModeChanged{
[self.tableController.tableView reloadData];
}
#pragma m ~ark - Action Functions
- (IBAction)onAllClick:(id)event {

View file

@ -35,6 +35,8 @@
#import <IntentsUI/IntentsUI.h>
#import "linphoneapp-Swift.h"
#import "SVProgressHUD.h"
#ifdef USE_CRASHLYTICS
#include "FIRApp.h"
@ -61,6 +63,9 @@
- (void)applicationDidEnterBackground:(UIApplication *)application {
LOGI(@"%@", NSStringFromSelector(_cmd));
if([LinphoneManager.instance lpConfigBoolForKey:@"account_push_presence_preference"]){
linphone_core_set_consolidated_presence(LC, LinphoneConsolidatedPresenceOffline);
}
if (linphone_core_get_global_state(LC) != LinphoneGlobalOff) {
[LinphoneManager.instance enterBackgroundMode];
[LinphoneManager.instance.fastAddressBook clearFriends];
@ -73,6 +78,7 @@
// To avoid crash
[PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription];
}
[CallManager.instance stopLinphoneCore];
}
[SwiftUtil resetCachedAsset];
@ -83,14 +89,24 @@
[LinphoneManager.instance startLinphoneCore];
[LinphoneManager.instance.fastAddressBook reloadFriends];
[AvatarBridge clearFriends];
if([LinphoneManager.instance lpConfigBoolForKey:@"account_push_presence_preference"]){
linphone_core_set_consolidated_presence(LC, LinphoneConsolidatedPresenceOnline);
}
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:nil];
}
- (void)applicationWillResignActive:(UIApplication *)application {
LOGI(@"%@", NSStringFromSelector(_cmd));
LinphoneCall *call = linphone_core_get_current_call(LC);
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId];
if (defaults) {
[defaults setBool:false forKey:@"appactive"];
}
if (!call)
return;
@ -113,7 +129,12 @@
}
LinphoneManager *instance = LinphoneManager.instance;
[instance becomeActive];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId];
if (defaults) {
[defaults setBool:true forKey:@"appactive"];
}
if (instance.fastAddressBook.needToUpdate) {
//Update address book for external changes
if (PhoneMainView.instance.currentView == ContactsListView.compositeViewDescription || PhoneMainView.instance.currentView == ContactDetailsView.compositeViewDescription) {
@ -137,7 +158,6 @@
if ((floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max)) {
if ([LinphoneManager.instance lpConfigBoolForKey:@"autoanswer_notif_preference"]) {
linphone_call_accept(call);
[PhoneMainView.instance changeCurrentView:ActiveCallOrConferenceView.compositeViewDescription];
} else {
[PhoneMainView.instance displayIncomingCall:call];
}
@ -156,7 +176,9 @@
[self handleShortcut:_shortcutItem];
_shortcutItem = nil;
}
#if TARGET_IPHONE_SIMULATOR
#else
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError *_Nullable error) {
if (error)
@ -182,6 +204,16 @@
}
}];
#endif
if ([UIDeviceBridge switchedDisplayMode]) {
[AvatarBridge prepareIt];
[NSNotificationCenter.defaultCenter postNotificationName:kDisplayModeChanged object:nil];
[PhoneMainView.instance.mainViewController removeEntryFromCache:ChatConversationCreateView.compositeViewDescription.name];
[PhoneMainView.instance.mainViewController changeView:PhoneMainView.instance.currentView];
[UIDeviceBridge notifyDisplayModeSwitch];
}
}
@ -250,7 +282,6 @@
intentIdentifiers:[[NSMutableArray alloc] init]
options:UNNotificationCategoryOptionCustomDismissAction];
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
NSSet *categories = [NSSet setWithObjects:cat_call, cat_msg, video_call, cat_zrtp, nil];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];
@ -263,6 +294,7 @@
[FIRApp configure];
#endif
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
if ([VFSUtil vfsEnabledWithGroupName:kLinphoneMsgNotificationAppGroupId]) {
if (TARGET_IPHONE_SIMULATOR) {
@ -331,8 +363,9 @@
return NO;
}
[PhoneMainView.instance.mainViewController getCachedController:ActiveCallOrConferenceView.compositeViewDescription.name]; // This will create the single instance of the ActiveCallOrConferenceView including listeneres
[PhoneMainView.instance.mainViewController getCachedController:SingleCallView.compositeViewDescription.name]; // This will create the single instance of the SingleCallView including listeneres
[PhoneMainView.instance.mainViewController getCachedController:ConferenceCallView.compositeViewDescription.name]; // This will create the single instance of the ConferenceCallView including listeneres
[CallsViewModelBridge setupCallsViewNavigation];
return YES;
}
@ -352,6 +385,7 @@
- (BOOL)handleShortcut:(UIApplicationShortcutItem *)shortcutItem {
BOOL success = NO;
if ([shortcutItem.type isEqualToString:@"linphone.phone.action.newMessage"]) {
[VIEW(ChatConversationCreateView) fragmentCompositeDescription];
[PhoneMainView.instance changeCurrentView:ChatConversationCreateView.compositeViewDescription];
success = YES;
}
@ -364,31 +398,39 @@
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{
NSString *scheme = [[url scheme] lowercaseString];
if ([scheme isEqualToString:@"linphone-config"] || [scheme isEqualToString:@"linphone-config"]) {
if ([scheme isEqualToString:@"linphone-config"]) {
NSString *encodedURL =
[[url absoluteString] stringByReplacingOccurrencesOfString:@"linphone-config://" withString:@""];
[[url absoluteString] stringByReplacingOccurrencesOfString:@"linphone-config:" withString:@""];
self.configURL = [encodedURL stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Remote configuration", nil)
message:NSLocalizedString(@"This operation will load a remote configuration. Continue ?", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"No", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
UIAlertAction* yesAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Yes", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self showWaitingIndicator];
[self attemptRemoteConfiguration];
}];
[errView addAction:defaultAction];
[errView addAction:yesAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
BOOL auto_apply_provisioning = [LinphoneManager.instance lpConfigBoolForKey:@"auto_apply_provisioning_config_uri_handler" inSection:@"app" withDefault:FALSE];
if (auto_apply_provisioning) {
[SVProgressHUD show];
[self attemptRemoteConfiguration];
[SVProgressHUD dismiss];
} else {
NSString *msg = [NSString stringWithFormat:NSLocalizedString(@" Do you want to download and apply configuration from this URL?\n\n%@", nil), encodedURL];
UIConfirmationDialog* remoteConfigurationDialog =[UIConfirmationDialog ShowWithMessage:msg
cancelMessage:nil
confirmMessage:NSLocalizedString(@"APPLY", nil)
onCancelClick:^() {}
onConfirmationClick:^() {
[SVProgressHUD show];
[self attemptRemoteConfiguration];
[SVProgressHUD dismiss];
}];
[remoteConfigurationDialog setSpecialColor];
}
} else if([[url scheme] isEqualToString:@"message-linphone"]) {
[PhoneMainView.instance popToView:ChatsListView.compositeViewDescription];
if ([[PhoneMainView.instance currentView] equal:ChatsListView.compositeViewDescription]) {
VIEW(ChatConversationViewSwift).sharingMedia = TRUE;
ChatsListView *view = VIEW(ChatsListView);
[view mediaSharing];
}else{
[SVProgressHUD dismiss];
VIEW(ChatConversationViewSwift).sharingMedia = TRUE;
[PhoneMainView.instance popToView:ChatsListView.compositeViewDescription];
}
} else if ([scheme isEqualToString:@"sip"]||[scheme isEqualToString:@"sips"]) {
// remove "sip://" from the URI, and do it correctly by taking resourceSpecifier and removing leading and
// trailing "/"
@ -413,8 +455,8 @@
linphone_address_unref(peer);
linphone_address_unref(local);
// TODO : Find a better fix
VIEW(ChatConversationView).markAsRead = FALSE;
[PhoneMainView.instance goToChatRoom:cr];
VIEW(ChatConversationViewSwift).markAsRead = FALSE;
[PhoneMainView.instance goToChatRoomSwift:cr];
}
}
return YES;
@ -503,33 +545,65 @@
- (void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
// If an app extension launch a user notif while app is in fg, it is catch by the app
NSString *category = [[[notification request] content] categoryIdentifier];
if (category && [category isEqualToString:@"app_active"]) {
return;
}
NSString *category = [[[notification request] content] categoryIdentifier];
if (category && [category isEqualToString:@"app_active"]) {
return;
}
if (category && [category isEqualToString:@"msg_cat"] && [UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
if ((PhoneMainView.instance.currentView == ChatsListView.compositeViewDescription))
return;
if (PhoneMainView.instance.currentView == ChatConversationView.compositeViewDescription) {
if (PhoneMainView.instance.currentView == ChatConversationViewSwift.compositeViewDescription) {
NSDictionary *userInfo = [[[notification request] content] userInfo];
NSString *peerAddress = userInfo[@"peer_addr"];
NSString *localAddress = userInfo[@"local_addr"];
if (peerAddress && localAddress) {
LinphoneAddress *peer = linphone_core_create_address([LinphoneManager getLc], peerAddress.UTF8String);
LinphoneAddress *local = linphone_core_create_address([LinphoneManager getLc], localAddress.UTF8String);
LinphoneChatRoom *room = linphone_core_find_chat_room([LinphoneManager getLc], peer, local);
LinphoneChatRoom *room = linphone_core_search_chat_room([LinphoneManager getLc], NULL, local, peer, NULL);
if (room == PhoneMainView.instance.currentRoom) return;
}
}
}
completionHandler(UNNotificationPresentationOptionAlert);
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
LOGD(@"didReceiveRemoteNotification -- backgroundPush");
NSDictionary *customPayload = [userInfo objectForKey:@"customPayload"];
if (customPayload && [customPayload objectForKey:@"token"]) {
[LinphoneManager.instance lpConfigSetString:[customPayload objectForKey:@"token"] forKey:@"account_creation_token" inSection:@"app"];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneAccountCreationAuthenticationTokenReceived object:nil];
completionHandler(UIBackgroundFetchResultNewData);
} else {
if (linphone_core_get_global_state(LC) != LinphoneGlobalOn) {
[LinphoneManager.instance startLinphoneCore];
[LinphoneManager.instance.fastAddressBook reloadFriends];
}
const MSList *accounts = linphone_core_get_account_list(LC);
while (accounts) {
LinphoneAccount *account = (LinphoneAccount *)accounts->data;
linphone_account_refresh_register(account);
accounts = accounts->next;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId];
NSMutableDictionary *chatroomsPushStatus = [[NSMutableDictionary alloc] initWithDictionary:[defaults dictionaryForKey:@"appactive"]];
if ([defaults boolForKey:@"appactive"] != TRUE) {
linphone_core_enter_background(LC);
if (linphone_core_get_calls_nb(LC) == 0) {
linphone_core_stop(LC);
}
}
completionHandler(UIBackgroundFetchResultNewData);
});
}
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
@ -537,6 +611,15 @@
withCompletionHandler:(void (^)(void))completionHandler {
LOGD(@"UN : response received");
LOGD(response.description);
if (![response.actionIdentifier isEqualToString:@"com.apple.UNNotificationDismissActionIdentifier"] &&
[response.notification.request.content.userInfo objectForKey:@"missed_call"]) {
[PhoneMainView.instance changeCurrentView:VIEW(HistoryListView).compositeViewDescription];
[PhoneMainView.instance.mainViewController didRotateFromInterfaceOrientation:PhoneMainView.instance.mainViewController.currentOrientation];
return;
}
startedInBackground = true;
NSString *callId = (NSString *)[response.notification.request.content.userInfo objectForKey:@"CallId"];
if (!callId)
@ -569,7 +652,7 @@
LinphoneAddress *local = linphone_address_new(local_address.UTF8String);
LinphoneChatRoom *room = linphone_core_find_chat_room(LC, peer, local);
if (room)
[ChatConversationView markAsRead:room];
[ChatConversationViewSwift markAsRead:room];
linphone_address_unref(peer);
linphone_address_unref(local);
@ -609,14 +692,16 @@
LinphoneAddress *local = linphone_address_new(local_address.UTF8String);
LinphoneChatRoom *room = linphone_core_find_chat_room(LC, peer, local);
if (room) {
[PhoneMainView.instance goToChatRoom:room];
[PhoneMainView.instance resetBeforeGoToChatRoomSwift];
[PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription];
[PhoneMainView.instance goToChatRoomSwift:room];
return;
} else {
[PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription];
}
[PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription];
}
} else if ([response.notification.request.content.categoryIdentifier isEqual:@"video_request"]) {
if (!call) return;
[PhoneMainView.instance changeCurrentView:ActiveCallOrConferenceView.compositeViewDescription];
NSTimer *videoDismissTimer = nil;
UIConfirmationDialog *sheet = [UIConfirmationDialog ShowWithMessage:response.notification.request.content.body
cancelMessage:nil
@ -717,7 +802,7 @@
LinphoneAddress *local = linphone_address_new(local_address.UTF8String);
LinphoneChatRoom *room = linphone_core_find_chat_room(LC, peer, local);
if (room)
[ChatConversationView markAsRead:room];
[ChatConversationViewSwift markAsRead:room];
linphone_address_unref(peer);
linphone_address_unref(local);
@ -767,6 +852,11 @@
- (void)ConfigurationStateUpdateEvent:(NSNotification *)notif {
LinphoneConfiguringState state = [[notif.userInfo objectForKey:@"state"] intValue];
if (state == LinphoneConfiguringSuccessful) {
if (linphone_config_has_entry(LinphoneManager.instance.configDb, "misc", "max_calls")) { // Not doable on core on iOS (requires CallKit) -> flag moved to app section, and have app handle it in ProviderDelegate
linphone_config_set_int(LinphoneManager.instance.configDb, "app", "max_calls", linphone_config_get_int(LinphoneManager.instance.configDb,"misc", "max_calls",10));
linphone_config_clean_entry(LinphoneManager.instance.configDb, "misc", "max_calls");
}
[NSNotificationCenter.defaultCenter removeObserver:self name:kLinphoneConfiguringStateUpdate object:nil];
[_waitingIndicator dismissViewControllerAnimated:YES completion:nil];
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Success", nil)
@ -798,23 +888,7 @@
}
}
- (void)showWaitingIndicator {
_waitingIndicator = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Fetching remote configuration...", nil)
message:@""
preferredStyle:UIAlertControllerStyleAlert];
UIActivityIndicatorView *progress = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(125, 60, 30, 30)];
progress.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
[_waitingIndicator setValue:progress forKey:@"accessoryView"];
[progress setColor:[UIColor blackColor]];
[progress startAnimating];
[PhoneMainView.instance presentViewController:_waitingIndicator animated:YES completion:nil];
}
- (void)attemptRemoteConfiguration {
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(ConfigurationStateUpdateEvent:)
name:kLinphoneConfiguringStateUpdate
@ -822,7 +896,7 @@
linphone_core_set_provisioning_uri(LC, [configURL UTF8String]);
[LinphoneManager.instance destroyLinphoneCore];
[LinphoneManager.instance launchLinphoneCore];
[LinphoneManager.instance.fastAddressBook fetchContactsInBackGroundThread];
[LinphoneManager.instance.fastAddressBook fetchContactsInBackGroundThread];
}
#pragma mark - Prevent ImagePickerView from rotating

View file

@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
@implementation LinphoneCoreSettingsStore
- (id)init {
@ -141,7 +142,9 @@
}
- (void)transformAccountToKeys:(NSString *)username {
const MSList *accountList = linphone_core_get_account_list(LC);
//const MSList *accountList = linphone_core_get_account_list(LC);
MSList *accountListToBeFreed = [LinphoneManager.instance createAccountsNotHiddenList];
MSList *accountList = accountListToBeFreed;
while (username && accountList &&
strcmp(username.UTF8String,
linphone_address_get_username(linphone_account_params_get_identity_address(linphone_account_get_params(accountList->data)))) != 0) {
@ -152,6 +155,7 @@
// default values
{
[self setBool:NO forKey:@"account_pushnotification_preference"];
[self setBool:NO forKey:@"account_bundle_mode_preference"];
[self setObject:@"" forKey:@"account_mandatory_username_preference"];
[self setObject:@"" forKey:@"account_mandatory_domain_preference"];
[self setCString:"" forKey:@"account_display_name_preference"];
@ -168,6 +172,7 @@
[self setInteger:-1 forKey:@"account_expire_preference"];
[self setInteger:-1 forKey:@"current_proxy_config_preference"];
[self setCString:"" forKey:@"account_prefix_preference"];
[self setBool:YES forKey:@"apply_international_prefix_for_calls_and_chats"];
[self setBool:NO forKey:@"account_substitute_+_by_00_preference"];
[self setBool:NO forKey:@"account_ice_preference"];
[self setCString:"" forKey:@"account_stun_preference"];
@ -180,10 +185,13 @@
{
BOOL pushEnabled = linphone_account_params_get_push_notification_allowed(accountParams);
[self setBool:pushEnabled forKey:@"account_pushnotification_preference"];
BOOL bundleModeEnabled = linphone_account_params_rtp_bundle_enabled(accountParams);
[self setBool:bundleModeEnabled forKey:@"account_bundle_mode_preference"];
const LinphoneAddress *identity_addr = linphone_account_params_get_identity_address(accountParams);
const char *server_addr = linphone_account_params_get_server_addr(accountParams);
LinphoneAddress *proxy_addr = linphone_core_interpret_url(LC, server_addr);
LinphoneAddress *proxy_addr = linphone_core_interpret_url_2(LC, server_addr, false);
if (identity_addr && proxy_addr) {
int port = linphone_address_get_port(proxy_addr);
@ -234,9 +242,11 @@
[self setCString:linphone_auth_info_get_algorithm(ai) forKey:@"ha1_algo_preference"];
}
MSList *accountsList = [LinphoneManager.instance createAccountsNotHiddenList];
int idx = (int)bctbx_list_index(linphone_core_get_account_list(LC), account);
[self setInteger:idx forKey:@"current_proxy_config_preference"];
bctbx_list_free(accountsList);
int expires = linphone_account_params_get_expires(accountParams);
[self setInteger:expires forKey:@"account_expire_preference"];
@ -251,10 +261,13 @@
{
const char *dial_prefix = linphone_account_params_get_international_prefix(accountParams);
[self setCString:dial_prefix forKey:@"account_prefix_preference"];
BOOL apply_prefix = linphone_account_params_get_use_international_prefix_for_calls_and_chats(accountParams);
[self setBool:apply_prefix forKey:@"apply_international_prefix_for_calls_and_chats"];
BOOL dial_escape_plus = linphone_account_params_get_dial_escape_plus_enabled(accountParams);
[self setBool:dial_escape_plus forKey:@"account_substitute_+_by_00_preference"];
}
}
bctbx_list_free(accountListToBeFreed);
}
@ -343,15 +356,17 @@
// root section
{
const bctbx_list_t *accounts = linphone_core_get_account_list(LC);
size_t count = bctbx_list_size(accounts);
for (size_t i = 1; i <= count; i++, accounts = accounts->next) {
MSList *accountsListToBeFreed = [lm createAccountsNotHiddenList];
MSList *accountsList = accountsListToBeFreed;
size_t count = bctbx_list_size(accountsList);
for (size_t i = 1; i <= count; i++, accountsList = accountsList->next) {
NSString *key = [NSString stringWithFormat:@"menu_account_%lu", i];
LinphoneAccount *account = (LinphoneAccount *)accounts->data;
LinphoneAccount *account = (LinphoneAccount *)accountsList->data;
[self setCString:linphone_address_get_username(linphone_account_params_get_identity_address(linphone_account_get_params(account)))
forKey:key];
}
bctbx_free(accountsListToBeFreed);
[self setBool:linphone_core_video_display_enabled(LC) forKey:@"enable_video_preference"];
[self setBool:[LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"]
forKey:@"enable_auto_answer_preference"];
@ -431,10 +446,10 @@
{
[self setCString:linphone_core_get_file_transfer_server(LC) forKey:@"file_transfer_server_url_preference"];
int maxSize = linphone_core_get_max_size_for_auto_download_incoming_files(LC);
[self setObject:maxSize==0 ? @"Always" : (maxSize==-1 ? @"Nerver" : @"Customize") forKey:@"auto_download_mode"];
[self setObject:maxSize==0 ? @"Always" : (maxSize==-1 ? @"Never" : @"Customize") forKey:@"auto_download_mode"];
[self setInteger:maxSize forKey:@"auto_download_incoming_files_max_size"];
[self setBool:[VFSUtil vfsEnabledWithGroupName:kLinphoneMsgNotificationAppGroupId] forKey:@"vfs_enabled_mode"];
[self setBool:[lm lpConfigBoolForKey:@"auto_write_to_gallery_preference" withDefault:YES] forKey:@"auto_write_to_gallery_mode"];
[self setBool:[lm lpConfigBoolForKey:@"auto_write_to_gallery_preference" withDefault:NO] forKey:@"auto_write_to_gallery_mode"];
}
// network section
@ -486,7 +501,7 @@
val = "None";
break;
}
[self setCString:val forKey:@"media_encryption_preference"];
[self setCString:val forKey:linphone_core_get_post_quantum_available() ? @"media_encryption_preference_pq_enabled" : @"media_encryption_preference"];
[self setInteger:linphone_core_get_upload_bandwidth(LC) forKey:@"upload_bandwidth_preference"];
[self setInteger:linphone_core_get_download_bandwidth(LC) forKey:@"download_bandwidth_preference"];
[self setBool:linphone_core_adaptive_rate_control_enabled(LC) forKey:@"adaptive_rate_control_preference"];
@ -509,8 +524,11 @@
}
// contacts section
if (linphone_core_ldap_available(LC)) {
[self transformLdapToKeys:nil];
{
[self setInteger:[lm lpConfigBoolForKey:@"account_push_presence_preference" withDefault:YES] forKey:@"account_push_presence_preference"];
if (linphone_core_ldap_available(LC)) {
[self transformLdapToKeys:nil];
}
}
// advanced section
@ -519,6 +537,7 @@
[self setBool:ANIMATED forKey:@"animations_preference"];
[self setBool:[lm lpConfigBoolForKey:@"backgroundmode_preference"] forKey:@"backgroundmode_preference"];
[self setBool:[lm lpConfigBoolForKey:@"start_at_boot_preference"] forKey:@"start_at_boot_preference"];
[self setBool:[lm lpConfigBoolForKey:@"screenshot_preference" withDefault:NO] forKey:@"screenshot_preference"];
[self setBool:[lm lpConfigBoolForKey:@"autoanswer_notif_preference"] forKey:@"autoanswer_notif_preference"];
[self setBool:[lm lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES] forKey:@"show_msg_in_notif"];
[self setBool:[lm lpConfigBoolForKey:@"use_rls_presence" withDefault:YES] forKey:@"use_rls_presence"];
@ -603,7 +622,9 @@
if (username && [username length] > 0 && domain && [domain length] > 0) {
int expire = [self integerForKey:@"account_expire_preference"];
BOOL pushnotification = [self boolForKey:@"account_pushnotification_preference"];
BOOL bundlemode = [self boolForKey:@"account_bundle_mode_preference"];
NSString *prefix = [self stringForKey:@"account_prefix_preference"];
BOOL use_prefix = [self boolForKey:@"apply_international_prefix_for_calls_and_chats"];
NSString *proxyAddress = [self stringForKey:@"account_proxy_preference"];
if ((!proxyAddress || [proxyAddress length] < 1) && domain) {
@ -614,7 +635,7 @@
proxyAddress = [NSString stringWithFormat:@"sip:%@", proxyAddress];
}
LinphoneAddress *proxy_addr = linphone_core_interpret_url(LC, proxyAddress.UTF8String);
LinphoneAddress *proxy_addr = linphone_core_interpret_url_2(LC, proxyAddress.UTF8String, false);
if (proxy_addr) {
LinphoneTransportType type = LinphoneTransportUdp;
@ -625,9 +646,11 @@
linphone_address_set_transport(proxy_addr, type);
}
account = bctbx_list_nth_data(linphone_core_get_account_list(LC),
MSList *accountList= [LinphoneManager.instance createAccountsNotHiddenList];
account = bctbx_list_nth_data(accountList,
[self integerForKey:@"current_proxy_config_preference"]);
bctbx_free(accountList);
// if account was deleted, it is not present anymore
if (account == NULL)
@ -670,10 +693,8 @@
linphone_nat_policy_set_stun_server(policy, stun_preference.UTF8String);
linphone_account_params_set_nat_policy(newAccountParams, policy);
if ([prefix length] > 0) {
linphone_account_params_set_international_prefix(newAccountParams, [prefix UTF8String]);
}
linphone_account_params_set_international_prefix(newAccountParams, [prefix UTF8String]);
linphone_account_params_set_use_international_prefix_for_calls_and_chats(newAccountParams, use_prefix);
if ([self objectForKey:@"account_substitute_+_by_00_preference"]) {
bool substitute_plus_by_00 = [self boolForKey:@"account_substitute_+_by_00_preference"];
linphone_account_params_set_dial_escape_plus_enabled(newAccountParams, substitute_plus_by_00);
@ -681,8 +702,10 @@
// use empty string "" instead of NULL to avoid being overwritten by default proxy config values
linphone_account_params_set_push_notification_allowed(newAccountParams, pushnotification);
linphone_account_params_enable_rtp_bundle(newAccountParams, bundlemode);
linphone_account_params_set_push_notification_allowed(newAccountParams, pushnotification);
linphone_account_params_set_remote_push_notification_allowed(newAccountParams, pushnotification);
linphone_account_params_set_register_enabled(newAccountParams, is_enabled);
linphone_account_params_set_avpf_mode(newAccountParams, use_avpf);
linphone_account_params_set_expires(newAccountParams, expire);
@ -713,7 +736,7 @@
}
char *identity = linphone_address_as_string(linphoneAddress);
LinphoneAddress *from = linphone_core_interpret_url(LC, identity);
LinphoneAddress *from = linphone_core_interpret_url_2(LC, identity, false);
ms_free(identity);
if (from) {
const char *userid_str = (userID != nil) ? [userID UTF8String] : NULL;
@ -805,7 +828,7 @@
linphone_ldap_params_set_bind_dn(newLdapParams, [self stringForKey:@"ldap_bind_dn"].UTF8String);
linphone_ldap_params_set_password(newLdapParams, [self stringForKey:@"ldap_password"].UTF8String);
LinphoneLdapAuthMethod authMethod = [[self stringForKey:@"ldap_verification_method"] isEqualToString:@"simple"] ? LinphoneLdapAuthMethodSimple : LinphoneLdapAuthMethodAnonymous;
LinphoneLdapAuthMethod authMethod = [[self stringForKey:@"ldap_auth_method"] isEqualToString:@"simple"] ? LinphoneLdapAuthMethodSimple : LinphoneLdapAuthMethodAnonymous;
linphone_ldap_params_set_auth_method(newLdapParams, authMethod);
linphone_ldap_params_enable_tls(newLdapParams, [self boolForKey:@"ldap_tls_enabled"]);
@ -829,8 +852,8 @@
// Analysis parameters
linphone_ldap_params_set_name_attribute(newLdapParams, [self stringForKey:@"ldap_name_attributes"].UTF8String);
linphone_ldap_params_set_sip_attribute(newLdapParams, [self stringForKey:@"ldap_sip_attributes"].UTF8String);
linphone_ldap_params_set_name_attribute(newLdapParams, [self stringForKey:@"ldap_name_attribute"].UTF8String);
linphone_ldap_params_set_sip_attribute(newLdapParams, [self stringForKey:@"ldap_sip_attribute"].UTF8String);
linphone_ldap_params_set_sip_domain(newLdapParams, [self stringForKey:@"ldap_sip_domain"].UTF8String);
// Miscellaneous parameters
@ -1020,7 +1043,7 @@
[LinphoneCoreSettingsStore parsePortRange:video_port_preference minPort:&videoMinPort maxPort:&videoMaxPort];
linphone_core_set_video_port_range(LC, videoMinPort, videoMaxPort);
NSString *menc = [self stringForKey:@"media_encryption_preference"];
NSString *menc = [self stringForKey:linphone_core_get_post_quantum_available() ? @"media_encryption_preference_pq_enabled" : @"media_encryption_preference"];
if (menc && [menc compare:@"SRTP"] == NSOrderedSame)
linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionSRTP);
else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame)
@ -1067,7 +1090,13 @@
}
// contacts section
BOOL push_presence = [self boolForKey:@"account_push_presence_preference"];
if (push_presence) {
linphone_core_set_consolidated_presence([LinphoneManager getLc], LinphoneConsolidatedPresenceOnline);
} else {
linphone_core_set_consolidated_presence([LinphoneManager getLc], LinphoneConsolidatedPresenceOffline);
}
[lm lpConfigSetInt:push_presence forKey:@"account_push_presence_preference"];
BOOL ldap_changed = NO;
for (NSString *key in self->changedDict) {
@ -1082,6 +1111,9 @@
// advanced section
BOOL animations = [self boolForKey:@"animations_preference"];
[lm lpConfigSetInt:animations forKey:@"animations_preference"];
BOOL screenshot = [self boolForKey:@"screenshot_preference"];
[lm lpConfigSetInt:screenshot forKey:@"screenshot_preference"];
UIDevice *device = [UIDevice currentDevice];
BOOL backgroundSupported = [device respondsToSelector:@selector(isMultitaskingSupported)] && [device isMultitaskingSupported];
@ -1096,7 +1128,9 @@
NSString *rls_uri = [lm lpConfigStringForKey:@"rls_uri" inSection:@"sip" withDefault:@"sips:rls@sip.linphone.org"];
LinphoneAddress *rls_addr = linphone_address_new(rls_uri.UTF8String);
const char *rls_domain = linphone_address_get_domain(rls_addr);
const MSList *accounts = linphone_core_get_account_list(LC);
MSList *accountListToBeFreed = [LinphoneManager.instance createAccountsNotHiddenList];
const MSList *accounts = accountListToBeFreed;
if (!accounts) // Enable it if no proxy config for first launch of app
[self setInteger:1 forKey:@"use_rls_presence"];
else {
@ -1110,6 +1144,7 @@
}
}
linphone_address_unref(rls_addr);
bctbx_free(accountListToBeFreed);
}
[lm lpConfigSetInt:[self integerForKey:@"use_rls_presence"] forKey:@"use_rls_presence"];
@ -1151,9 +1186,12 @@
}
- (void)removeAccount {
LinphoneAccount *account = bctbx_list_nth_data(linphone_core_get_account_list(LC),
MSList *accountList = [LinphoneManager.instance createAccountsNotHiddenList];
LinphoneAccount *account = bctbx_list_nth_data(accountList,
[self integerForKey:@"current_proxy_config_preference"]);
const MSList *lists = linphone_core_get_friends_lists(LC);
while (lists) {
linphone_friend_list_enable_subscriptions(lists->data, FALSE);
@ -1174,11 +1212,12 @@
if (isDefault) {
// if we removed the default proxy config, set another one instead
if (linphone_core_get_account_list(LC) != NULL) {
linphone_core_set_default_account(LC, (LinphoneAccount *)(linphone_core_get_account_list(LC)->data));
if (accountList != NULL) {
linphone_core_set_default_account(LC, (LinphoneAccount *)(accountList->data));
}
}
[self transformLinphoneCoreToKeys];
bctbx_free(accountList);
}
- (void)removeLdap {

View file

@ -65,6 +65,9 @@ extern NSString *const kLinphoneConfStateParticipantListChanged;
extern NSString *const kLinphoneConfStateChanged;
extern NSString *const kLinphoneMagicSearchStarted;
extern NSString *const kLinphoneMagicSearchFinished;
extern NSString *const kLinphoneMagicSearchMoreAvailable;
extern NSString *const kDisplayModeChanged;
extern NSString *const kLinphoneAccountCreationAuthenticationTokenReceived;
extern NSString *const kLinphoneMsgNotificationAppGroupId;
@ -174,6 +177,7 @@ typedef struct _LinphoneManagerSounds {
- (void)silentPushFailed:(NSTimer*)timer;
- (MSList *) createAccountsNotHiddenList; // needs to be unref
- (void)removeAllAccounts;
+ (BOOL)isMyself:(const LinphoneAddress *)addr;
@ -192,6 +196,8 @@ typedef struct _LinphoneManagerSounds {
- (BOOL)isCTCallCenterExist;
- (void) checkLocalNetworkPermission;
+ (BOOL) getChatroomPushEnabled:(LinphoneChatRoom *)chatroom;
+ (void) setChatroomPushEnabled:(LinphoneChatRoom *)chatroom withPushEnabled:(BOOL)enabled;
@property (readonly) BOOL isTesting;
@property(readonly, strong) FastAddressBook *fastAddressBook;

View file

@ -81,13 +81,15 @@ NSString *const kLinphoneConfStateChanged = @"kLinphoneConfStateChanged";
NSString *const kLinphoneConfStateParticipantListChanged = @"kLinphoneConfStateParticipantListChanged";
NSString *const kLinphoneMagicSearchStarted = @"LinphoneMagicSearchStarted";
NSString *const kLinphoneMagicSearchFinished = @"LinphoneMagicSearchFinished";
NSString *const kLinphoneMagicSearchMoreAvailable = @"LinphoneMagicSearchMoreAvailable";
NSString *const kDisplayModeChanged = @"DisplayModeChanged";
NSString *const kLinphoneAccountCreationAuthenticationTokenReceived = @"LinphoneAccountCreationAuthenticationTokenReceived";
NSString *const kLinphoneMsgNotificationAppGroupId = @"group.org.linphone.phone.msgNotification";
const int kLinphoneAudioVbrCodecDefaultBitrate = 36; /*you can override this from linphonerc or linphonerc-factory*/
extern void libmsamr_init(MSFactory *factory);
extern void libmsx264_init(MSFactory *factory);
extern void libmsopenh264_init(MSFactory *factory);
extern void libmssilk_init(MSFactory *factory);
extern void libmswebrtc_init(MSFactory *factory);
@ -239,7 +241,7 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
self.messagePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil];
_sounds.vibrate = kSystemSoundID_Vibrate;
//_sounds.vibrate = kSystemSoundID_Vibrate;
_logs = [[NSMutableArray alloc] init];
_pushDict = [[NSMutableDictionary alloc] init];
@ -253,6 +255,11 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
[self renameDefaultSettings];
[self copyDefaultSettings];
[self overrideDefaultSettings];
if (![self lpConfigBoolForKey:@"disable_chat_feature" withDefault:FALSE]) {
_sounds.vibrate = kSystemSoundID_Vibrate;
}
if (![self lpConfigBoolForKey:@"migration_images_done" withDefault:FALSE]) {
[self migrationAllImages];
}
@ -276,6 +283,14 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
[self lpConfigSetString:@"conflate" forKey:@"handle_content_encoding" inSection:@"misc"];
#endif
}
if ([self lpConfigStringForKey:@"display_link_account_popup"] == nil) {
[self lpConfigSetBool:true forKey:@"display_link_account_popup"];
}
if ([self lpConfigStringForKey:@"hide_link_phone_number"] == nil) {
[self lpConfigSetInt:1 forKey:@"hide_link_phone_number"];
}
[self migrateFromUserPrefs];
[self loadAvatar];
@ -372,6 +387,10 @@ static int check_should_migrate_images(void *data, int argc, char **argv, char *
}
- (void)migrationLinphoneSettings {
NSString *appDomain = [LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"];
/* AVPF migration */
if ([self lpConfigBoolForKey:@"avpf_migration_done"] == FALSE) {
const MSList *accounts = linphone_core_get_account_list(theLinphoneCore);
@ -464,6 +483,26 @@ static int check_should_migrate_images(void *data, int argc, char **argv, char *
}
[self lpConfigSetBool:TRUE forKey:@"push_notification_migration_done"];
}
if ([self lpConfigBoolForKey:@"publish_enabled_migration_done"] == FALSE) {
const MSList *accounts = linphone_core_get_account_list(theLinphoneCore);
linphone_core_set_log_collection_upload_server_url(LC, "https://www.linphone.org:444/lft.php");
[self lpConfigSetBool:TRUE forKey:@"update_presence_model_timestamp_before_publish_expires_refresh"];
while (accounts)
{
LinphoneAccount *account = (LinphoneAccount *)accounts->data;
LinphoneAccountParams *newAccountParams = linphone_account_params_clone(linphone_account_get_params(account));
if (strcmp(appDomain.UTF8String, linphone_account_params_get_domain(newAccountParams)) == 0) {
linphone_account_params_set_publish_enabled(newAccountParams, true);
linphone_account_params_set_publish_expires(newAccountParams, 120);
linphone_account_set_params(account, newAccountParams);
}
linphone_account_params_unref(newAccountParams);
accounts = accounts->next;
}
[self lpConfigSetBool:TRUE forKey:@"publish_enabled_migration_done"];
}
}
- (void)migrationPerAccount {
@ -474,27 +513,33 @@ static int check_should_migrate_images(void *data, int argc, char **argv, char *
while (accounts) {
LinphoneAccount *account = accounts->data;
LinphoneAccountParams *newAccountParams = linphone_account_params_clone(linphone_account_get_params(account));
// can not create group chat without conference factory
if (!linphone_account_params_get_conference_factory_uri(newAccountParams)) {
if (strcmp(appDomain.UTF8String, linphone_account_params_get_domain(newAccountParams)) == 0) {
if (strcmp(appDomain.UTF8String, linphone_account_params_get_domain(newAccountParams)) == 0) {
// can not create group chat without conference factory
if (!linphone_account_params_get_conference_factory_uri(newAccountParams)) {
linphone_account_params_set_conference_factory_uri(newAccountParams, "sip:conference-factory@sip.linphone.org");
linphone_account_set_params(account, newAccountParams);
}
}
if (!linphone_account_params_get_audio_video_conference_factory_address(newAccountParams) && strcmp(appDomain.UTF8String, linphone_account_params_get_domain(newAccountParams)) == 0) {
NSString *uri = [self lpConfigStringForKey:@"default_audio_video_conference_factory_uri" withDefault:@"sip:videoconference-factory2@sip.linphone.org"];
LinphoneAddress *a = linphone_factory_create_address(linphone_factory_get(), uri.UTF8String);
if (a) {
linphone_account_params_set_audio_video_conference_factory_address(newAccountParams, a);
linphone_account_set_params(account, newAccountParams);
if (!linphone_account_params_get_audio_video_conference_factory_address(newAccountParams)) {
NSString *uri = [self lpConfigStringForKey:@"default_audio_video_conference_factory_uri" withDefault:@"sip:videoconference-factory2@sip.linphone.org"];
LinphoneAddress *a = linphone_factory_create_address(linphone_factory_get(), uri.UTF8String);
if (a) {
linphone_account_params_set_audio_video_conference_factory_address(newAccountParams, a);
linphone_account_set_params(account, newAccountParams);
}
}
/*
if (!linphone_account_params_rtp_bundle_enabled(newAccountParams)) {
linphone_account_params_enable_rtp_bundle(newAccountParams, true);
linphone_account_set_params(account,newAccountParams);
}
*/
LOGI(@"Setting the sip 'expires' parameters of existing account to 1 year (31536000 seconds)");
linphone_account_params_set_expires(newAccountParams, 31536000);
}
if (strcmp(appDomain.UTF8String, linphone_account_params_get_domain(newAccountParams)) == 0 && !linphone_account_params_rtp_bundle_enabled(newAccountParams)) {
linphone_account_params_enable_rtp_bundle(newAccountParams, true);
linphone_account_set_params(account,newAccountParams);
}
linphone_account_params_unref(newAccountParams);
accounts = accounts->next;
}
@ -637,6 +682,11 @@ static void linphone_iphone_global_state_changed(LinphoneCore *lc, LinphoneGloba
if (theLinphoneCore && linphone_core_get_global_state(theLinphoneCore) != LinphoneGlobalOff)
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneGlobalStateUpdate object:self userInfo:dict];
});
if (state == LinphoneGlobalOn) {
// reload friends
[self.fastAddressBook fetchContactsInBackGroundThread];
}
}
- (void)globalStateChangedNotificationHandler:(NSNotification *)notif {
@ -865,9 +915,9 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut
return;
if (hasFile) {
if (PhoneMainView.instance.currentView == ChatConversationView.compositeViewDescription && room == PhoneMainView.instance.currentRoom)
if (PhoneMainView.instance.currentView == ChatConversationViewSwift.compositeViewDescription && room == PhoneMainView.instance.currentRoom)
return;
[ChatConversationView autoDownload:msg];
[self autoDownload:msg];
}
// Post event
@ -881,83 +931,27 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:self userInfo:dict];
}
- (void)autoDownload:(LinphoneChatMessage *)message {
LinphoneContent *content = linphone_chat_message_get_file_transfer_information(message);
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *fileType = [NSString stringWithUTF8String:linphone_content_get_type(content)];
NSString *key = [ChatConversationViewSwift getKeyFromFileType:fileType fileName:name];
[LinphoneManager setValueInMessageAppData:name forKey:key inMessage:message];
dispatch_async(dispatch_get_main_queue(), ^{
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:VIEW(ChatConversationViewSwift)];
if (![VFSUtil vfsEnabledWithGroupName:kLinphoneMsgNotificationAppGroupId] && [ConfigManager.instance lpConfigBoolForKeyWithKey:@"auto_write_to_gallery_preference"]) {
[ChatConversationViewSwift writeMediaToGalleryFromName:name fileType:fileType];
}
});
}
static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
[(__bridge LinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onMessageReceived:lc room:room message:message];
}
static void linphone_iphone_message_received_unable_decrypt(LinphoneCore *lc, LinphoneChatRoom *room,
LinphoneChatMessage *message) {
NSString *callId = [NSString stringWithUTF8String:linphone_chat_message_get_custom_header(message, "Call-ID")];
int index = [(NSNumber *)[LinphoneManager.instance.pushDict objectForKey:callId] intValue] - 1;
LOGI(@"Decrementing index of long running task for call id : %@ with index : %d", callId, index);
[LinphoneManager.instance.pushDict setValue:[NSNumber numberWithInt:index] forKey:callId];
BOOL need_bg_task = FALSE;
for (NSString *key in [LinphoneManager.instance.pushDict allKeys]) {
int value = [(NSNumber *)[LinphoneManager.instance.pushDict objectForKey:key] intValue];
if (value > 0) {
need_bg_task = TRUE;
break;
}
}
if (theLinphoneManager->pushBgTaskMsg && !need_bg_task) {
LOGI(@"Message received, stopping message background task for call-id [%@]", callId);
[[UIApplication sharedApplication] endBackgroundTask:theLinphoneManager->pushBgTaskMsg];
theLinphoneManager->pushBgTaskMsg = 0;
}
const LinphoneAddress *address = linphone_chat_message_get_peer_address(message);
NSString *strAddr = [FastAddressBook displayNameForAddress:address];
NSString *title = NSLocalizedString(@"LIME warning", nil);
NSString *body = [NSString
stringWithFormat:NSLocalizedString(@"You have received an encrypted message you are unable to decrypt from "
@"%@.\nYou need to call your correspondant in order to exchange your ZRTP "
@"keys if you want to decrypt the future messages you will receive.",
nil),
strAddr];
NSString *action = NSLocalizedString(@"Call", nil);
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = title;
content.body = body;
UNNotificationRequest *req =
[UNNotificationRequest requestWithIdentifier:@"decrypt_request" content:content trigger:NULL];
[[UNUserNotificationCenter currentNotificationCenter]
addNotificationRequest:req
withCompletionHandler:^(NSError *_Nullable error) {
// Enable or disable features based on authorization.
if (error) {
LOGD(@"Error while adding notification request :");
LOGD(error.description);
}
}];
} else {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.repeatInterval = 0;
notification.alertTitle = title;
notification.alertBody = body;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
} else {
UIAlertController *errView =
[UIAlertController alertControllerWithTitle:title message:body preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
}];
UIAlertAction *callAction = [UIAlertAction actionWithTitle:action
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[LinphoneManager.instance call:address];
}];
[errView addAction:defaultAction];
[errView addAction:callAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
}
}
- (void)onNotifyReceived:(LinphoneCore *)lc
@ -1254,7 +1248,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
[LinphoneManager.instance lpConfigSetInt:0 forKey:@"must_link_account_time"];
} else {
LinphoneAccount *account = linphone_core_get_default_account(LC);
LinphoneAccountParams const *accountParams = linphone_account_get_params(account);
LinphoneAccountParams const *accountParams = account ? linphone_account_get_params(account) : NULL;
if (account &&
strcmp(linphone_account_params_get_domain(accountParams),
[LinphoneManager.instance lpConfigStringForKey:@"domain_name"
@ -1275,7 +1269,14 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
handler:^(UIAlertAction * action) {
[PhoneMainView.instance changeCurrentView:AssistantLinkView.compositeViewDescription];
}];
UIAlertAction* otherAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Never ask again", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[LinphoneManager.instance lpConfigSetBool:false forKey:@"display_link_account_popup"];
}];
defaultAction.accessibilityLabel = @"Later";
[errView addAction:otherAction];
[errView addAction:defaultAction];
[errView addAction:continueAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
@ -1294,7 +1295,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
NSDate *nextTime =
[NSDate dateWithTimeIntervalSince1970:[self lpConfigIntForKey:@"must_link_account_time" withDefault:1]];
NSDate *now = [NSDate date];
if (nextTime.timeIntervalSince1970 > 0 && [now earlierDate:nextTime] == nextTime) {
if (nextTime.timeIntervalSince1970 > 0 && [now earlierDate:nextTime] == nextTime && [LinphoneManager.instance lpConfigBoolForKey:@"display_link_account_popup"] && ![LinphoneManager.instance lpConfigIntForKey:@"hide_link_phone_number"]) {
LinphoneAccount *account = linphone_core_get_default_account(LC);
if (account) {
const char *username = linphone_address_get_username(linphone_account_params_get_identity_address(linphone_account_get_params(account)));
@ -1334,22 +1335,37 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
}
}
- (void)activateBasicChatroomCPIMForLinphoneAccounts {
- (void)enableLinphoneAccountSpecificSettings {
const MSList *accountsList = linphone_core_get_account_list(theLinphoneCore);
while (accountsList) {
LinphoneAccount * account = accountsList->data;
LinphoneAccountParams const * currentParams = linphone_account_get_params(account);
LinphoneAddress const * currentAddress = linphone_account_params_get_identity_address(currentParams);
char * addressIdentity = linphone_address_as_string(currentAddress);
if (strcmp(linphone_address_get_domain(currentAddress), "sip.linphone.org") == 0 && !linphone_account_params_cpim_in_basic_chat_room_enabled(currentParams) ) {
LOGI(@"Enabling CPIM in basic chatroom for user %s", linphone_address_get_username(currentAddress));
if (strcmp(linphone_address_get_domain(currentAddress), "sip.linphone.org") == 0) {
LinphoneAccountParams * newParams = linphone_account_params_clone(linphone_account_get_params(account));
linphone_account_params_enable_cpim_in_basic_chat_room(newParams, true);
if (!linphone_account_params_cpim_in_basic_chat_room_enabled(currentParams) ) {
LOGI(@"Enabling CPIM in basic chatroom for account [%s]", addressIdentity);
linphone_account_params_enable_cpim_in_basic_chat_room(newParams, true);
}
const char* current_lime_url = linphone_account_params_get_lime_server_url(currentParams);
if (!current_lime_url){
const char* core_lime_url = linphone_core_get_lime_x3dh_server_url(LC);
if (core_lime_url) {
LOGI(@"Copying core's LIME X3DH server URL [%s] to account [%s]", core_lime_url, addressIdentity);
linphone_account_params_set_lime_server_url(newParams, core_lime_url);
} else {
LOGI(@"Account [%s] didn't have a LIME X3DH server URL, setting one: [%s]", addressIdentity, core_lime_url);
linphone_account_params_set_lime_server_url(newParams, "https://lime.linphone.org/lime-server/lime-server.php");
}
}
linphone_account_set_params(account, newParams);
linphone_account_params_unref(newParams);
}
ms_free(addressIdentity);
accountsList = accountsList->next;
}
}
@ -1360,7 +1376,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
linphone_core_start([LinphoneManager getLc]);
[self configurePushProviderForAccounts];
[self activateBasicChatroomCPIMForLinphoneAccounts];
[self enableLinphoneAccountSpecificSettings];
}
- (void)createLinphoneCore {
@ -1417,6 +1433,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
[ConfigManager.instance setDbWithDb:_configDb];
[CallManager.instance setCoreWithCore:theLinphoneCore];
[CallsViewModelBridge updateCore];
[LinphoneManager.instance startLinphoneCore];
@ -1429,7 +1446,6 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
MSFactory *f = linphone_core_get_ms_factory(theLinphoneCore);
libmssilk_init(f);
libmsamr_init(f);
libmsx264_init(f);
libmsopenh264_init(f);
libmswebrtc_init(f);
libmscodec2_init(f);
@ -1459,6 +1475,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
- (void)destroyLinphoneCore {
// just in case
[self removeCTCallCenterCb];
[MagicSearchSingleton destroyInstance];
if (theLinphoneCore != nil) { // just in case application terminate before linphone core initialization
@ -1469,8 +1486,11 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
[ftd stopAndDestroyAndRemove:FALSE];
}
[_fileTransferDelegates removeAllObjects];
linphone_core_destroy(theLinphoneCore);
if (linphone_core_get_global_state(LC) != LinphoneGlobalOff) {
linphone_core_stop(LC);
}
linphone_core_unref(theLinphoneCore);
LOGI(@"Destroy linphonecore %p", theLinphoneCore);
theLinphoneCore = nil;
@ -1488,8 +1508,6 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
- (void)resetLinphoneCore {
[self destroyLinphoneCore];
[self createLinphoneCore];
// reload friends
[self.fastAddressBook fetchContactsInBackGroundThread];
}
static int comp_call_id(const LinphoneCall *call, const char *callid) {
@ -1792,7 +1810,10 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
factory = factoryIpad;
}
_configDb = linphone_config_new_for_shared_core(kLinphoneMsgNotificationAppGroupId.UTF8String, @"linphonerc".UTF8String, factory.UTF8String);
linphone_config_clean_entry(_configDb, "misc", "max_calls");
if (linphone_config_has_entry(_configDb, "misc", "max_calls")) { // Not doable on core on iOS (requires CallKit) -> flag moved to app section, and have app handle it in ProviderDelegate
linphone_config_set_int(_configDb, "app", "max_calls", linphone_config_get_int(_configDb,"misc", "max_calls",10));
linphone_config_clean_entry(_configDb, "misc", "max_calls");
}
}
#pragma mark - Audio route Functions
@ -1801,7 +1822,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String);
linphone_chat_message_send(msg);
[ChatConversationView markAsRead:room];
[ChatConversationViewSwift markAsRead:room];
}
/*
@ -1884,7 +1905,10 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
}
[self checkLocalNetworkPermission];
// For OutgoingCall, show CallOutgoingView
[CallManager.instance startCallWithAddr:iaddr isSas:FALSE isVideo:false isConference:false];
LinphoneVideoActivationPolicy *policy = linphone_core_get_video_activation_policy(LC);
BOOL initiateVideoCall = linphone_video_activation_policy_get_automatically_initiate(policy);
[CallManager.instance startCallWithAddr:iaddr isSas:FALSE isVideo:initiateVideoCall isConference:false];
linphone_video_activation_policy_unref(policy);
}
#pragma mark - Misc Functions
@ -2210,6 +2234,23 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
#pragma mark -
- (MSList *) createAccountsNotHiddenList {
MSList *list = NULL;
const MSList *accounts = linphone_core_get_account_list(LC);
while (accounts) {
const char *isHidden = linphone_account_get_custom_param(accounts->data, "hidden");
if (isHidden == NULL || strcmp(linphone_account_get_custom_param(accounts->data, "hidden"), "1") != 0) {
if (!list) {
list = bctbx_list_new(accounts->data);
} else {
bctbx_list_append(list, accounts->data);
}
}
accounts = accounts->next;
}
return list;
}
- (void)removeAllAccounts {
linphone_core_clear_accounts(LC);
linphone_core_clear_all_auth_info(LC);
@ -2303,6 +2344,31 @@ void linphone_iphone_conference_state_changed(LinphoneCore *lc, LinphoneConferen
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneConfStateChanged object:nil userInfo:dict];
}
+ (BOOL) getChatroomPushEnabled:(LinphoneChatRoom *)chatroom {
bool currently_enabled = true;
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId];
NSDictionary *chatroomsPushStatus = [defaults dictionaryForKey:@"chatroomsPushStatus"];
if (chatroomsPushStatus != nil && chatroom) {
char *uri = linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(chatroom));
NSString* pushStatus = [chatroomsPushStatus objectForKey:[NSString stringWithUTF8String:uri]];
currently_enabled = (pushStatus == nil) || [pushStatus isEqualToString:@"enabled"];
ms_free(uri);
}
return currently_enabled;
}
+ (void) setChatroomPushEnabled:(LinphoneChatRoom *)chatroom withPushEnabled:(BOOL)enabled {
if (!chatroom) return;
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kLinphoneMsgNotificationAppGroupId];
NSMutableDictionary *chatroomsPushStatus = [[NSMutableDictionary alloc] initWithDictionary:[defaults dictionaryForKey:@"chatroomsPushStatus"]];
if (chatroomsPushStatus == nil) chatroomsPushStatus = [[NSMutableDictionary dictionary] init];
char *uri = linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(chatroom));
[chatroomsPushStatus setValue:(enabled ? @"enabled" : @"disabled") forKey:[NSString stringWithUTF8String:uri]];
ms_free(uri);
[defaults setObject:chatroomsPushStatus forKey:@"chatroomsPushStatus"];
}
@end

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -57,7 +57,7 @@
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onSideMenuClick:" destination="-1" eventType="touchUpInside" id="iOC-wy-MPP"/>
<action selector="onQualityClick:" destination="-1" eventType="touchUpInside" id="Pir-Ib-ywJ"/>
</connections>
</button>
</subviews>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -81,6 +81,22 @@
<rect key="frame" x="0.0" y="0.0" width="365" height="357"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="chat_read.png" translatesAutoresizingMaskIntoConstraints="NO" id="LPj-VT-0fH" userLabel="imdmIcon">
<rect key="frame" x="372" y="342" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ephemeral_messages_color_A.png" id="7JB-ZL-0lZ" userLabel="ephemeralIcon">
<rect key="frame" x="352" y="346" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00:00" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="IRV-qN-sRj" userLabel="ephemeralTime">
<rect key="frame" x="285" y="346" width="65" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VAJ-tE-fsa">
<rect key="frame" x="0.0" y="10" width="382" height="347"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -185,22 +201,6 @@
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="chat_read.png" translatesAutoresizingMaskIntoConstraints="NO" id="LPj-VT-0fH" userLabel="imdmIcon">
<rect key="frame" x="372" y="337" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ephemeral_messages_color_A.png" id="7JB-ZL-0lZ" userLabel="ephemeralIcon">
<rect key="frame" x="351" y="336" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00:00" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="IRV-qN-sRj" userLabel="ephemeralTime">
<rect key="frame" x="282" y="336" width="65" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view tag="28021" contentMode="scaleToFill" id="bhq-9n-zYF" userLabel="voiceRecording">
<rect key="frame" x="7" y="252" width="351" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
@ -261,7 +261,7 @@
<image name="color_M.png" width="2" height="2"/>
<image name="ephemeral_messages_color_A.png" width="136" height="158.39999389648438"/>
<image name="linphone_logo.png" width="41.599998474121094" height="42.400001525878906"/>
<image name="menu_reply_default.png" width="25" height="25"/>
<image name="menu_reply_default.png" width="60" height="60"/>
<image name="vr_play.png" width="200" height="200"/>
<image name="vr_wave.png" width="1078" height="90"/>
</resources>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -27,7 +27,7 @@
<rect key="frame" x="0.0" y="0.0" width="189" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="hBI-Xz-aEV" userLabel="avatarImage" customClass="UIRoundedImageView">
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="hBI-Xz-aEV" userLabel="avatarImage">
<rect key="frame" x="6" y="20" width="27" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
@ -59,14 +59,14 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<textView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." translatesAutoresizingMaskIntoConstraints="NO" id="CYa-If-oB4" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="0.0" y="0.0" width="126" height="40"/>
<rect key="frame" x="4" y="0.0" width="118" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="chat_read.png" translatesAutoresizingMaskIntoConstraints="NO" id="Nod-GX-0kg" userLabel="imdmIcon">
<rect key="frame" x="133" y="30" width="10" height="10"/>
<rect key="frame" x="133" y="28" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="00:00:00" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GDJ-O8-m6J" userLabel="ephemeralTime">
@ -93,6 +93,6 @@
<image name="chat_read.png" width="20" height="20"/>
<image name="color_A.png" width="2" height="2"/>
<image name="ephemeral_messages_color_A.png" width="136" height="158.39999389648438"/>
<image name="menu_reply_default.png" width="25" height="25"/>
<image name="menu_reply_default.png" width="60" height="60"/>
</resources>
</document>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -26,7 +26,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="86"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="19" userLabel="avatarImage" customClass="UIRoundedImageView">
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="19" userLabel="avatarImage" customClass="UIImageView">
<rect key="frame" x="10" y="11" width="42" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
@ -66,15 +66,11 @@
<nil key="highlightedColor"/>
</label>
<view hidden="YES" autoresizesSubviews="NO" userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7DE-KJ-9Q3" userLabel="unreadCountView" customClass="UIBouncingView">
<rect key="frame" x="338" y="12" width="21" height="21"/>
<rect key="frame" x="338" y="12" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" fixedFrame="YES" image="chat_list_indicator.png" translatesAutoresizingMaskIntoConstraints="NO" id="NXj-A8-YLh" userLabel="unreadCountImage">
<rect key="frame" x="0.0" y="0.0" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="9" contentMode="left" fixedFrame="YES" text="99" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="7" translatesAutoresizingMaskIntoConstraints="NO" id="ZXq-Do-7Ua" userLabel="unreadCountLabel">
<rect key="frame" x="0.0" y="0.0" width="21" height="21"/>
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" none="YES"/>
@ -88,11 +84,11 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="forward_message_default.png" id="rbY-QS-6QH" userLabel="transferIcon">
<rect key="frame" x="338" y="33" width="21" height="21"/>
<rect key="frame" x="338" y="33" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="ephemeral_messages_color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="q18-yi-ol3">
<rect key="frame" x="338" y="54" width="21" height="21"/>
<rect key="frame" x="338" y="54" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
@ -103,7 +99,6 @@
</objects>
<resources>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="chat_list_indicator.png" width="28" height="28"/>
<image name="chat_read.png" width="20" height="20"/>
<image name="ephemeral_messages_color_A.png" width="136" height="158.39999389648438"/>
<image name="forward_message_default.png" width="187" height="148"/>

View file

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -22,19 +23,19 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="Z2U-vm-azg" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="0.0" y="5" width="44" height="28"/>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="Z2U-vm-azg" userLabel="avatarImage">
<rect key="frame" x="0.0" y="8" width="44" height="28"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f3q-pd-EF5" userLabel="displayNameLabel">
<rect key="frame" x="43" y="11" width="185" height="16"/>
<rect key="frame" x="43" y="0.0" width="185" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" text="Today - 18h42" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hEV-7I-B0v" userLabel="contactDateLabel">
<rect key="frame" x="200" y="13" width="159" height="12"/>
<rect key="frame" x="229" y="16" width="130" height="12"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
@ -42,12 +43,15 @@
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</tableViewCellContentView>
<point key="canvasLocation" x="61.5" y="52"/>
<point key="canvasLocation" x="60" y="51.27436281859071"/>
</tableViewCell>
</objects>
<resources>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina5_5" orientation="landscape" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -61,7 +61,7 @@
<action selector="onDelete:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="gSd-t2-eDY"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="Zsv-H9-9Dv" userLabel="avatarImage" customClass="UIRoundedImageView">
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="Zsv-H9-9Dv" userLabel="avatarImage">
<rect key="frame" x="8" y="0.0" width="35" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -47,7 +47,7 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Linphone"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="ktO-jm-Ra6" userLabel="avatarImage" customClass="UIRoundedImageView">
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="ktO-jm-Ra6" userLabel="avatarImage">
<rect key="frame" x="10" y="10" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
@ -61,7 +61,7 @@
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="890.39999999999998" y="192.50374812593705"/>

View file

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="UIChatCreateCollectionViewCell">
<rect key="frame" x="0.0" y="0.0" width="100" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="100" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fHV-en-AZD" userLabel="displayNameLabel">
<rect key="frame" x="14" y="18" width="92" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" image="conference_delete.png" translatesAutoresizingMaskIntoConstraints="NO" id="yfP-hQ-SXb" userLabel="selectedImage">
<rect key="frame" x="1" y="23" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
<size key="customSize" width="170" height="45"/>
<connections>
<outlet property="nameLabel" destination="fHV-en-AZD" id="gOU-sp-v0V"/>
</connections>
<point key="canvasLocation" x="2" y="86"/>
</collectionViewCell>
</objects>
<resources>
<image name="conference_delete.png" width="17.600000381469727" height="17.600000381469727"/>
</resources>
</document>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<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"/>
@ -13,6 +13,7 @@
<connections>
<outlet property="contentCollection" destination="ZgY-Ye-8DD" id="hlD-Fw-g1z"/>
<outlet property="dismissButton" destination="KrT-j6-YOy" id="K5m-Mw-Cjx"/>
<outlet property="icsIcon" destination="gkH-jk-DYU" id="Xkl-Ip-skO"/>
<outlet property="leftBar" destination="Iov-AL-8Xz" id="eKb-4B-unZ"/>
<outlet property="originalMessageGone" destination="B26-sw-o4w" id="Gwh-dh-GRN"/>
<outlet property="senderName" destination="uuW-tW-1Sj" id="Yao-6A-SBh"/>
@ -68,6 +69,10 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<state key="normal" image="reply_cancel.png"/>
</button>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="voip_meeting_schedule.png" translatesAutoresizingMaskIntoConstraints="NO" id="gkH-jk-DYU">
<rect key="frame" x="16" y="23" width="35" height="35"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
@ -77,6 +82,7 @@
</objects>
<resources>
<image name="reply_cancel.png" width="60" height="60"/>
<image name="voip_meeting_schedule.png" width="20" height="20"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -11,11 +11,14 @@
<connections>
<outlet property="authButton" destination="lWW-wB-FMR" id="C7W-JM-WFQ"/>
<outlet property="authView" destination="CCn-Oz-I0M" id="fSM-6k-paN"/>
<outlet property="backgroundColor" destination="cqN-1f-6SE" id="gjg-LB-xLT"/>
<outlet property="cancelButton" destination="B1K-CB-3of" id="KKi-Xc-ldA"/>
<outlet property="confirmationButton" destination="SbQ-re-fGQ" id="yiv-a9-o8E"/>
<outlet property="firstView" destination="ef9-Iu-Bcb" id="hKx-op-r7Z"/>
<outlet property="forwardImage" destination="1Wh-Yi-cUe" id="YQq-bt-pk1"/>
<outlet property="groupCallImage" destination="SVn-4k-9yc" id="sAP-8V-ttn"/>
<outlet property="securityImage" destination="bbo-g3-bGy" id="qZa-li-yrl"/>
<outlet property="subscribeLabel" destination="Xbl-Qs-GaE" id="Qnf-pA-nL0"/>
<outlet property="titleLabel" destination="jLz-g1-cTe" id="qaj-OB-2r1"/>
<outlet property="view" destination="2Vb-Xy-rci" id="nNw-EJ-AY3"/>
</connections>
@ -25,27 +28,32 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.89999999999999991" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_C.png" translatesAutoresizingMaskIntoConstraints="NO" id="cqN-1f-6SE" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="377" height="667"/>
<view contentMode="scaleToFill" id="ef9-Iu-Bcb" userLabel="firstView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2BQ-o9-xv2">
<rect key="frame" x="28" y="139" width="320" height="365"/>
</view>
<view contentMode="scaleToFill" id="2BQ-o9-xv2">
<rect key="frame" x="25" y="114" width="325" height="440"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_C.png" translatesAutoresizingMaskIntoConstraints="NO" id="cqN-1f-6SE" userLabel="backgroundColor">
<rect key="frame" x="-17" y="-17" width="360" height="474"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.26666668059999998" green="0.26666668059999998" blue="0.26666668059999998" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
</imageView>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" image="security_2_indicator.png" translatesAutoresizingMaskIntoConstraints="NO" id="bbo-g3-bGy" userLabel="securityImage">
<rect key="frame" x="130" y="0.0" width="56" height="68"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<rect key="frame" x="130" y="15" width="64" height="68"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Are you sure you want to delete all your selection?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="jLz-g1-cTe" userLabel="titleLabel">
<rect key="frame" x="-10" y="15" width="336" height="279"/>
<rect key="frame" x="-8" y="15" width="347" height="350"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="21"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="B1K-CB-3of" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="8" y="308" width="139" height="42"/>
<rect key="frame" x="16" y="383" width="139" height="36"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="CANCEL" backgroundImage="color_H.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -57,11 +65,11 @@
</connections>
</button>
<view hidden="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CCn-Oz-I0M" userLabel="authView">
<rect key="frame" x="61" y="273" width="240" height="27"/>
<rect key="frame" x="65" y="345" width="243" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lWW-wB-FMR" userLabel="authButton">
<rect key="frame" x="26" y="2" width="17" height="22"/>
<rect key="frame" x="24" y="0.0" width="22" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="checkbox_unchecked.png"/>
<state key="selected" image="checkbox_checked.png"/>
@ -70,7 +78,7 @@
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Do not show again" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dQL-Sf-slc">
<rect key="frame" x="55" y="2" width="176" height="21"/>
<rect key="frame" x="57" y="10" width="173" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@ -79,7 +87,7 @@
</subviews>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SbQ-re-fGQ" userLabel="confirmationButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="169" y="308" width="143" height="42"/>
<rect key="frame" x="177" y="383" width="136" height="36"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="DELETE" backgroundImage="color_I.png">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -91,20 +99,34 @@
</connections>
</button>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="forward_message_default.png" translatesAutoresizingMaskIntoConstraints="NO" id="1Wh-Yi-cUe">
<rect key="frame" x="89" y="50" width="138" height="54"/>
<rect key="frame" x="100" y="50" width="136" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="voip_conference_new.png" translatesAutoresizingMaskIntoConstraints="NO" id="SVn-4k-9yc">
<rect key="frame" x="89" y="50" width="138" height="54"/>
<rect key="frame" x="100" y="50" width="136" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label hidden="YES" opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="https://subscribe.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xbl-Qs-GaE" userLabel="subscribeLabel">
<rect key="frame" x="-42" y="291" width="414" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.98766469960000003" green="0.27512490750000002" blue="0.029739789660000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<connections>
<outletCollection property="gestureRecognizers" destination="tfG-O1-yfD" appends="YES" id="Jcg-KH-U5B"/>
</connections>
</label>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<point key="canvasLocation" x="871.20000000000005" y="261.31934032983509"/>
<point key="canvasLocation" x="548" y="34"/>
</view>
<tapGestureRecognizer id="tfG-O1-yfD" userLabel="onSubscribeTap">
<connections>
<action selector="onSubscribeTap:" destination="-1" id="Zq2-mP-ccM"/>
</connections>
</tapGestureRecognizer>
</objects>
<resources>
<image name="checkbox_checked.png" width="27.200000762939453" height="27.200000762939453"/>

View file

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -14,37 +12,47 @@
<outlet property="avatarImage" destination="23" id="24"/>
<outlet property="linphoneImage" destination="25" id="27"/>
<outlet property="nameLabel" destination="6" id="26"/>
<outlet property="organizationLabel" destination="fva-Hf-er8" id="Ib6-rS-ybW"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="16">
<rect key="frame" x="0.0" y="0.0" width="360" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="360" height="49"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="23" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="6" y="6" width="32" height="32"/>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="23" userLabel="avatarImage">
<rect key="frame" x="6" y="9" width="32" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="John Doe" lineBreakMode="tailTruncation" minimumFontSize="10" id="6" userLabel="nameLabel">
<rect key="frame" x="46" y="0.0" width="256" height="44"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" fixedFrame="YES" text="John Doe" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="6" userLabel="nameLabel">
<rect key="frame" x="46" y="4" width="256" height="39"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Firstname"/>
<fontDescription key="fontDescription" type="system" pointSize="21"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="linphone_user.png" id="25" userLabel="linphoneImage">
<rect key="frame" x="319" y="10" width="25" height="25"/>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" image="linphone_user.png" translatesAutoresizingMaskIntoConstraints="NO" id="25" userLabel="linphoneImage">
<rect key="frame" x="319" y="13" width="25" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" fixedFrame="YES" text="Organization" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="fva-Hf-er8" userLabel="organizationLabel">
<rect key="frame" x="46" y="29" width="256" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Firstname"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="137.59999999999999" y="-10.794602698650676"/>
</view>
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="linphone_user.png" width="26" height="26"/>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="linphone_user.png" width="41.599998474121094" height="42.400001525878906"/>
</resources>
</document>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -61,7 +61,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="88"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="john.doe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="frB-ep-LWi" userLabel="addressLabel">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="john.doe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="frB-ep-LWi" userLabel="addressLabel" customClass="CopyableLabel" customModule="linphoneapp" customModuleProvider="target">
<rect key="frame" x="26" y="0.0" width="323" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>

View file

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIHistoryCell">
@ -18,31 +20,27 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="J9B-Wl-Qgm" userLabel="avatarImage" customClass="UIRoundedImageView">
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="J9B-Wl-Qgm" userLabel="avatarImage">
<rect key="frame" x="6" y="6" width="32" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<animations/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="history_missed_default.png" id="Jpe-IK-xK1" userLabel="stateImage">
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="history_missed_default.png" translatesAutoresizingMaskIntoConstraints="NO" id="Jpe-IK-xK1" userLabel="stateImage">
<rect key="frame" x="46" y="6" width="32" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<animations/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="John Doe" lineBreakMode="tailTruncation" minimumFontSize="10" id="zG2-Kg-0jD" userLabel="displayNameLabel">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" fixedFrame="YES" text="John Doe" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="zG2-Kg-0jD" userLabel="displayNameLabel">
<rect key="frame" x="86" y="0.0" width="237" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Firstname"/>
<fontDescription key="fontDescription" type="system" pointSize="21"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Lfl-dI-bSt" userLabel="detailsButton" customClass="UIIconButton">
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lfl-dI-bSt" userLabel="detailsButton" customClass="UIIconButton">
<rect key="frame" x="331" y="0.0" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<animations/>
<state key="normal" image="list_details_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="list_details_over.png"/>
<connections>
@ -50,17 +48,16 @@
</connections>
</button>
</subviews>
<animations/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="366.5" y="248"/>
<point key="canvasLocation" x="559.5419847328244" y="174.64788732394368"/>
</view>
</objects>
<resources>
<image name="avatar.png" width="255" height="255"/>
<image name="history_missed_default.png" width="32" height="32"/>
<image name="list_details_default.png" width="33" height="34"/>
<image name="list_details_over.png" width="33" height="34"/>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="history_missed_default.png" width="52.799999237060547" height="52.799999237060547"/>
<image name="list_details_default.png" width="54.400001525878906" height="55.200000762939453"/>
<image name="list_details_over.png" width="54.400001525878906" height="55.200000762939453"/>
</resources>
</document>

View file

@ -35,6 +35,7 @@
@property(weak, nonatomic) IBOutlet UIView *outcallView;
- (IBAction)onSecurityClick:(id)sender;
- (IBAction)onQualityClick:(id)sender;
- (IBAction)onSideMenuClick:(id)sender;
- (IBAction)onRegistrationStateClick:(id)sender;
+ (UIImage *)imageForState:(LinphoneRegistrationState)state;

View file

@ -21,6 +21,7 @@
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import <UserNotifications/UserNotifications.h>
#import "linphoneapp-Swift.h"
@implementation StatusBarView {
@ -175,6 +176,7 @@
case LinphoneRegistrationNone:
return [UIImage imageNamed:@"led_disconnected.png"];
case LinphoneRegistrationProgress:
case LinphoneRegistrationRefreshing:
return [UIImage imageNamed:@"led_inprogress.png"];
case LinphoneRegistrationOk:
return [UIImage imageNamed:@"led_connected.png"];
@ -193,17 +195,20 @@
message = NSLocalizedString(@"Fetching remote configuration", nil);
} else if (account == NULL) {
state = LinphoneRegistrationNone;
if (linphone_core_get_account_list(LC) != NULL) {
MSList *accounts = [LinphoneManager.instance createAccountsNotHiddenList];
if (accounts != NULL) {
message = NSLocalizedString(@"No default account", nil);
} else {
message = NSLocalizedString(@"No account configured", nil);
}
bctbx_free(accounts);
} else {
state = linphone_account_get_state(account);
switch (state) {
case LinphoneRegistrationOk:
case LinphoneRegistrationRefreshing:
message = NSLocalizedString(@"Connected", nil);
break;
case LinphoneRegistrationNone:
@ -329,14 +334,9 @@
correspondantCode = [code substringToIndex:2];
myCode = [code substringFromIndex:2];
}
NSString *message =
[NSString stringWithFormat:NSLocalizedString(@"\nConfirmation security\n\n"
@"Say: %@\n"
@"Confirm that your interlocutor\n"
@"says: %@",
nil),
myCode.uppercaseString, correspondantCode.uppercaseString];
NSString *message = [NSString stringWithFormat:NSLocalizedString(@"\nCommunication security:\n\nTo raise the security level, you can check the following codes with your correspondent.\n\nSay: %1$@\n\nYour correspondent must say: %2$@", nil),
myCode.uppercaseString, correspondantCode.uppercaseString];
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive &&
floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
@ -368,14 +368,14 @@
UIFont *baseFont = [UIFont systemFontOfSize:21.0];
[attrString addAttribute:NSFontAttributeName value:baseFont range:NSMakeRange(0, length)];
UIFont *boldFont = [UIFont boldSystemFontOfSize:23.0];
[attrString addAttribute:NSFontAttributeName value:boldFont range:[message rangeOfString:@"Confirmation security"]];
[attrString addAttribute:NSFontAttributeName value:boldFont range:[message rangeOfString:@"Communication security"]];
UIColor *color = [UIColor colorWithRed:(150 / 255.0) green:(193 / 255.0) blue:(31 / 255.0) alpha:1.0];
[attrString addAttribute:NSForegroundColorAttributeName value:color range:[message rangeOfString:myCode.uppercaseString]];
[attrString addAttribute:NSForegroundColorAttributeName value:color range:[message rangeOfString:correspondantCode.uppercaseString]];
securityDialog = [UIConfirmationDialog ShowWithAttributedMessage:attrString
cancelMessage:NSLocalizedString(@"DENY", nil)
confirmMessage:NSLocalizedString(@"ACCEPT", nil)
cancelMessage:NSLocalizedString(@"Later", nil)
confirmMessage:NSLocalizedString(@"Correct", nil)
onCancelClick:^() {
if (linphone_core_get_current_call(LC) == call) {
linphone_call_set_authentication_token_verified(call, NO);
@ -393,6 +393,7 @@
securityDialog.securityImage.hidden = FALSE;
[securityDialog setSpecialColor];
[securityDialog setWhiteCancel];
}
}
}
@ -400,6 +401,10 @@
}
}
- (IBAction)onQualityClick:(id)sender {
[ControlsViewModelBridge toggleStatsVisibility];
}
- (IBAction)onSideMenuClick:(id)sender {
UICompositeView *cvc = PhoneMainView.instance.mainViewController;
[cvc hideSideMenu:(cvc.sideMenuView.frame.origin.x == 0)];
@ -408,10 +413,15 @@
- (IBAction)onRegistrationStateClick:(id)sender {
if (linphone_core_get_default_account(LC)) {
linphone_core_refresh_registers(LC);
} else if (linphone_core_get_account_list(LC)) {
[PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription];
} else {
[PhoneMainView.instance changeCurrentView:AssistantView.compositeViewDescription];
MSList *accounts = [LinphoneManager.instance createAccountsNotHiddenList];
if (accounts) {
[PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription];
} else {
[PhoneMainView.instance changeCurrentView:AssistantView.compositeViewDescription];
}
bctbx_free(accounts);
}
}

View file

@ -76,16 +76,20 @@
- (void)update:(BOOL)appear {
[self updateSelectedButton:[PhoneMainView.instance currentView]];
[self updateMissedCall:linphone_core_get_missed_calls_count(LC) appear:appear];
[self updateUnreadMessage:appear];
if (![LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"]) {
[self updateUnreadMessage:appear];
}
}
- (void)updateUnreadMessage:(BOOL)appear {
int unreadMessage = [LinphoneManager unreadMessageCount];
if (unreadMessage > 0) {
_chatNotificationLabel.text = [NSString stringWithFormat:@"%i", unreadMessage];
[_chatNotificationView startAnimating:appear];
} else {
[_chatNotificationView stopAnimating:appear];
if (![LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"]) {
if (unreadMessage > 0) {
_chatNotificationLabel.text = [NSString stringWithFormat:@"%i", unreadMessage];
[_chatNotificationView startAnimating:appear];
} else {
[_chatNotificationView stopAnimating:appear];
}
}
}
@ -109,7 +113,25 @@
[view equal:ChatConversationCreateView.compositeViewDescription] ||
[view equal:ChatConversationInfoView.compositeViewDescription] ||
[view equal:ChatConversationImdnView.compositeViewDescription] ||
[view equal:ChatConversationView.compositeViewDescription];
[view equal:ChatConversationViewSwift.compositeViewDescription];
if ([LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"] && [self viewIsCurrentlyPortrait]) {
CGFloat itemWidth = [UIScreen mainScreen].bounds.size.width/3;
[_chatButton setEnabled:false];
[_chatButton setHidden:true];
[_chatNotificationView setHidden:true];
_historyButton.frame = CGRectMake(0, 0, itemWidth, 66);
_contactsButton.frame = CGRectMake(itemWidth, 0, itemWidth, 66);
_dialerButton.frame = CGRectMake(itemWidth*2, 0, itemWidth, 66);
_selectedButtonImage.frame = CGRectMake(_selectedButtonImage.frame.origin.x, _selectedButtonImage.frame.origin.y, itemWidth, 3);
} else if ([LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"] && ![self viewIsCurrentlyPortrait]) {
[_chatButton setEnabled:false];
[_chatButton setHidden:true];
[_chatNotificationView setHidden:true];
_historyButton.frame = CGRectMake(0, 20, 90, 90);
_contactsButton.frame = CGRectMake(0, 120, 90, 90);
_dialerButton.frame = CGRectMake(0, 220, 90, 90);
_selectedButtonImage.frame = CGRectMake(_selectedButtonImage.frame.origin.x, _selectedButtonImage.frame.origin.y, 3, 90);
}
CGRect selectedNewFrame = _selectedButtonImage.frame;
if ([self viewIsCurrentlyPortrait]) {
selectedNewFrame.origin.x =

View file

@ -48,7 +48,7 @@
}
- (IBAction)onBackToCallClick:(id)sender {
[PhoneMainView.instance popToView:ActiveCallOrConferenceView.compositeViewDescription];
[PhoneMainView.instance popToView:[CallsViewModelBridge callViewToDisplay]];
}
@end

View file

@ -192,14 +192,20 @@
_voiceRecordingFile = nil;
LinphoneContent *voiceContent = [UIChatBubbleTextCell voiceContent:self.message];
if (voiceContent) {
_voiceRecordingFile = [NSString stringWithUTF8String:[VFSUtil vfsEnabledWithGroupName:kLinphoneMsgNotificationAppGroupId] ? linphone_content_get_plain_file_path(voiceContent) : linphone_content_get_file_path(voiceContent)];
if ([VFSUtil vfsEnabledWithGroupName:kLinphoneMsgNotificationAppGroupId])
const char *fileName = ([VFSUtil vfsEnabledWithGroupName:kLinphoneMsgNotificationAppGroupId] ? linphone_content_get_plain_file_path(voiceContent) : linphone_content_get_file_path(voiceContent));
if (fileName == nil) {
linphone_content_set_file_path(voiceContent, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:[[NSUUID UUID] UUIDString]].UTF8String);
linphone_chat_message_download_content(self.message, voiceContent);
}
_voiceRecordingFile = fileName ? [NSString stringWithUTF8String:fileName] : nil;
if (fileName && [VFSUtil vfsEnabledWithGroupName:kLinphoneMsgNotificationAppGroupId]) {
[encrptedFilePaths setValue:_voiceRecordingFile forKey:[NSString stringWithUTF8String:linphone_content_get_name(voiceContent)]];
}
_vrTimerLabel.text = [self formattedDuration:linphone_content_get_file_duration(voiceContent)/1000];
_vrWaveMaskPlayback.frame = CGRectZero;
_vrWaveMaskPlayback.backgroundColor = linphone_chat_message_is_outgoing(self.message) ? UIColor.orangeColor : UIColor.grayColor;
}
const bctbx_list_t *contents = linphone_chat_message_get_contents(self.message);
size_t contentCount = bctbx_list_size(contents);
@ -234,7 +240,8 @@
if (strcmp(cPath, "") != 0) {
NSString *tempPath = [NSString stringWithUTF8String:cPath];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
filePath = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:@"%@/%s", [paths objectAtIndex:0],linphone_chat_message_get_message_id(super.message)];
[FileUtil ensureDirectoryExistsWithPath:filePath];
filePath = [filePath stringByAppendingPathComponent:name];
[[NSFileManager defaultManager] moveItemAtPath:tempPath toPath:filePath error:nil];
}
@ -300,7 +307,8 @@
if (strcmp(cPath, "") != 0) {
NSString *tempPath = [NSString stringWithUTF8String:cPath];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
filePath = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:@"%@/%s", [paths objectAtIndex:0],linphone_chat_message_get_message_id(super.message)];
[FileUtil ensureDirectoryExistsWithPath:filePath];
filePath = [filePath stringByAppendingPathComponent:fileName];
[[NSFileManager defaultManager] moveItemAtPath:tempPath toPath:filePath error:nil];
}

View file

@ -39,7 +39,7 @@
@property(readonly, nonatomic) LinphoneEventLog *event;
@property(readonly, nonatomic) LinphoneChatMessage *message;
@property(nonatomic, weak) IBOutlet UIImageView *backgroundColorImage;
@property(nonatomic, weak) IBOutlet UIRoundedImageView *avatarImage;
@property(nonatomic, weak) IBOutlet UIImageView *avatarImage;
@property(nonatomic, weak) IBOutlet UILabel *contactDateLabel;
//@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *statusInProgressSpinner;
@property(nonatomic, weak) IBOutlet UITextViewNoDefine *messageText;

View file

@ -46,10 +46,8 @@
[self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)];
[self addSubview:sub];
self.icsBubbleView = [[ICSBubbleView alloc] init];
self.icsBubbleView.frame = CGRectMake(_messageText.frame.origin.x, _messageText.frame.origin.y+25, CONFERENCE_INVITATION_WIDTH-80, CONFERENCE_INVITATION_HEIGHT-20);
[self.innerView addSubview:self.icsBubbleView];
[(ICSBubbleView*)self.icsBubbleView setLayoutConstraintsWithView:self.backgroundColorImage];
}
}
@ -121,16 +119,21 @@
}
- (void)setChatMessageForCbs:(LinphoneChatMessage *)amessage {
if (!amessage || amessage == _message) {
if (amessage == _message) {
return;
}
if (_message){
linphone_chat_message_unref(_message);
}
_message = amessage;
linphone_chat_message_set_user_data(_message, (void *)CFBridgingRetain(self));
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(_message);
linphone_chat_message_cbs_set_msg_state_changed(cbs, message_status);
linphone_chat_message_cbs_set_participant_imdn_state_changed(cbs, participant_imdn_status);
linphone_chat_message_cbs_set_user_data(cbs, (void *)_event);
if (amessage){
linphone_chat_message_ref(amessage);
linphone_chat_message_set_user_data(_message, (void *)CFBridgingRetain(self));
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(_message);
linphone_chat_message_cbs_set_msg_state_changed(cbs, message_status);
linphone_chat_message_cbs_set_participant_imdn_state_changed(cbs, participant_imdn_status);
linphone_chat_message_cbs_set_user_data(cbs, (void *)_event);
}
}
+ (NSString *)TextMessageForChat:(LinphoneChatMessage *)message {
@ -168,7 +171,7 @@
return;
}
if (_messageText && ![LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]) {
if (_messageText && ![LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message] && ![ICSBubbleView isConferenceInvitationMessageWithCmessage:self.message]) {
[_messageText setHidden:FALSE];
/* We need to use an attributed string here so that data detector don't mess
* with the text style. See http://stackoverflow.com/a/20669356 */
@ -198,9 +201,7 @@
_avatarImage.hidden = TRUE;
} else {
[_avatarImage setImage:[FastAddressBook imageForAddress:linphone_chat_message_get_from_address(_message)]
bordered:NO
withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForAddress:linphone_chat_message_get_from_address(_message)]];
_contactDateLabel.text = [self.class ContactDateForChat:_message];
_contactDateLabel.textAlignment = NSTextAlignmentLeft;
_avatarImage.hidden = !_isFirst;
@ -323,11 +324,13 @@
- (void)onDelete {
if (_message != NULL) {
UITableView *tableView = VIEW(ChatConversationView).tableController.tableView;
/*
UITableView *tableView = VIEW(ChatConversationViewSwift).tableController.tableView;
NSIndexPath *indexPath = [tableView indexPathForCell:self];
[tableView.dataSource tableView:tableView
commitEditingStyle:UITableViewCellEditingStyleDelete
forRowAtIndexPath:indexPath];
*/
}
}
@ -339,15 +342,17 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st
if (!linphone_chat_message_is_outgoing(msg) || (state != LinphoneChatMessageStateFileTransferDone && state != LinphoneChatMessageStateFileTransferInProgress)) {
LinphoneEventLog *event = (LinphoneEventLog *)linphone_chat_message_cbs_get_user_data(linphone_chat_message_get_callbacks(msg));
ChatConversationView *view = VIEW(ChatConversationView);
[view.tableController updateEventEntry:event];
[view.tableController scrollToBottom:true];
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
//[view.tableController updateEventEntry:event];
//[view.tableController scrollToBottom:true];
}
}
static void participant_imdn_status(LinphoneChatMessage* msg, const LinphoneParticipantImdnState *state) {
ChatConversationImdnView *imdnView = VIEW(ChatConversationImdnView);
[imdnView updateImdnList];
dispatch_async(dispatch_get_main_queue(), ^{
ChatConversationImdnView *imdnView = VIEW(ChatConversationImdnView);
[imdnView updateImdnList];
});
}
- (void)displayImdmStatus:(LinphoneChatMessageState)state {
@ -399,7 +404,7 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
return cached;
}
CGSize size = [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil];
CGSize size = [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil];
size.height += linphone_chat_message_is_forward(chat) || linphone_chat_message_is_reply(chat) ? REPLY_OR_FORWARD_TAG_HEIGHT : 0;
size.height += linphone_chat_message_is_reply(chat) ? REPLY_CHAT_BUBBLE_HEIGHT+5 : 0;
@ -491,7 +496,7 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
+ (CGSize)ViewHeightForMessageText:(LinphoneChatMessage *)chat withWidth:(int)width textForImdn:(NSString *)imdnText {
if ([ICSBubbleView isConferenceInvitationMessageWithCmessage:chat]) {
return CGSizeMake(CONFERENCE_INVITATION_WIDTH, CONFERENCE_INVITATION_HEIGHT);
return CGSizeMake(CONFERENCE_INVITATION_WIDTH, CONFERENCE_INVITATION_HEIGHT+[ICSBubbleView getDescriptionHeightFromContentWithCmessage:chat]);
}
NSString *messageText = [UIChatBubbleTextCell TextMessageForChat:chat];
@ -764,7 +769,7 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
- (void)layoutSubviews {
[super layoutSubviews];
if (_message != nil) {
UITableView *tableView = VIEW(ChatConversationView).tableController.tableView;
//UITableView *tableView = VIEW(ChatConversationViewSwift).tableController.tableView;
BOOL is_outgoing = linphone_chat_message_is_outgoing(_message);
CGRect bubbleFrame = _bubbleView.frame;
int available_width = self.frame.size.width;
@ -775,11 +780,13 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
bubbleFrame.size.width = MAX(bubbleFrame.size.width, 300);
}
/*
if (tableView.isEditing) {
origin_x = 0;
} else {
origin_x = (is_outgoing ? self.frame.size.width - bubbleFrame.size.width : 0);
}
*/
CGRect r = _messageText.frame;
r.origin.y = linphone_chat_message_is_reply(_message) ? _replyView.view.frame.origin.y + _replyView.view.frame.size.height + 5 : 3;
@ -791,6 +798,8 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
_replyTransferIcon.hidden = ! linphone_chat_message_is_reply(_message) && !linphone_chat_message_is_forward(_message);
_replyTransferLabel.hidden = ! linphone_chat_message_is_reply(_message) && !linphone_chat_message_is_forward(_message);
[(ICSBubbleView*)self.icsBubbleView updateTopLayoutConstraintsWithView:self.backgroundColorImage replyOrForward:linphone_chat_message_is_reply(_message)||linphone_chat_message_is_forward(_message)];
if (linphone_chat_message_is_reply(_message)) {
CGRect replyFrame = CGRectMake(10, _replyTransferLabel.frame.origin.y+_replyTransferLabel.frame.size.height+5,MAX(self.contactDateLabel.frame.size.width-20,180), REPLY_CHAT_BUBBLE_HEIGHT);
@ -848,10 +857,13 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
-(void) buildActions {
LinphoneChatMessage *message = self.message;
LinphoneEventLog *event = self.event;
_messageActionsTitles = [[NSMutableArray alloc] init];
_messageActionsBlocks = [[NSMutableArray alloc] init];
_messageActionsIcons = [[NSMutableArray alloc] init];
[VIEW(ChatConversationView).messageField resignFirstResponder];
UIChatBubbleTextCell *thiz = self;
LinphoneChatMessageState state = linphone_chat_message_get_state(self.message);
@ -869,7 +881,7 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
}
if (linphone_chat_message_get_utf8_text(message)) {
if (linphone_chat_message_get_utf8_text(message) && ![ICSBubbleView isConferenceInvitationMessageWithCmessage:message]) {
[_messageActionsTitles addObject:NSLocalizedString(@"Copy text", nil)];
[_messageActionsIcons addObject:@"menu_copy_text_default"];
[_messageActionsBlocks addObject:^{
@ -883,7 +895,7 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
[_messageActionsIcons addObject:@"menu_forward_default"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
VIEW(ChatConversationView).pendingForwardMessage = message;
VIEW(ChatConversationViewSwift).pendingForwardMessage = message;
[PhoneMainView.instance changeCurrentView:VIEW(ChatsListView).compositeViewDescription];
}];
@ -893,26 +905,53 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
[_messageActionsIcons addObject:@"menu_reply_default"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
[VIEW(ChatConversationView) initiateReplyViewForMessage:message];
[VIEW(ChatConversationViewSwift) initiateReplyViewForMessage:message];
}];
if (linphone_chat_message_is_outgoing(self.message) || linphone_chat_room_get_nb_participants(linphone_chat_message_get_chat_room(self.message)) > 1) {
LinphoneChatRoom *chatroom = linphone_chat_message_get_chat_room(self.message);
if (linphone_chat_room_get_nb_participants(chatroom) > 1) {
[_messageActionsTitles addObject:NSLocalizedString(@"Infos", nil)];
[_messageActionsIcons addObject:@"menu_info"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
ChatConversationImdnView *view = VIEW(ChatConversationImdnView);
view.msg = message;
view.event = event;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}];
}
if (!linphone_chat_message_is_outgoing(self.message)
&& [FastAddressBook getContactWithAddress:linphone_chat_message_get_from_address(self.message)] == nil
&& !(linphone_chat_room_get_capabilities(chatroom) & LinphoneChatRoomCapabilitiesOneToOne) ) {
LinphoneAddress *fromAddress = linphone_address_clone(linphone_chat_message_get_from_address(self.message));
[_messageActionsTitles addObject:NSLocalizedString(@"Add to contact", nil)];
[_messageActionsIcons addObject:@"contact_add_default"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
linphone_address_clean(fromAddress);
char *lAddress = linphone_address_as_string_uri_only(fromAddress);
if (lAddress != NULL) {
NSString *normSip = [NSString stringWithUTF8String:lAddress];
normSip = [normSip hasPrefix:@"sip:"] ? [normSip substringFromIndex:4] : normSip;
normSip = [normSip hasPrefix:@"sips:"] ? [normSip substringFromIndex:5] : normSip;
[ContactSelection setAddAddress:normSip];
[ContactSelection setSelectionMode:ContactSelectionModeEdit];
[ContactSelection enableSipFilter:FALSE];
[PhoneMainView.instance changeCurrentView:ContactsListView.compositeViewDescription];
ms_free(lAddress);
}
linphone_address_unref(fromAddress);
}];
}
[_messageActionsTitles addObject:NSLocalizedString(@"Delete", nil)];
[_messageActionsIcons addObject:@"menu_delete"];
[_messageActionsBlocks addObject:^{
[thiz dismissPopup];
linphone_chat_room_delete_message(linphone_chat_message_get_chat_room(message), message);
[VIEW(ChatConversationView).tableController reloadData];
//[VIEW(ChatConversationViewSwift).tableController reloadData];
}];
}
@ -924,25 +963,27 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
return;
[VIEW(ChatConversationView).tableController dismissMessagesPopups];
//[VIEW(ChatConversationViewSwift).tableController dismissMessagesPopups];
[self buildActions];
int width = 250;
int cellHeight = 45;
int numberOfItems = (int) _messageActionsTitles.count;
CGRect screenRect = UIScreen.mainScreen.bounds;
int menuHeight = numberOfItems * cellHeight + 15;
int menuHeight = numberOfItems * cellHeight;
/*
CGRect frame = CGRectMake(
linphone_chat_message_is_outgoing(self.message) ? screenRect.size.width - width - 10 : 10,
(self.frame.origin.y + self.frame.size.height) - [VIEW(ChatConversationView).tableController .tableView contentOffset].y > screenRect.size.height /2 ? self.frame.origin.y - menuHeight - 10: self.frame.origin.y + self.frame.size.height,
(self.frame.origin.y + self.frame.size.height) - [VIEW(ChatConversationViewSwift).tableController .tableView contentOffset].y > screenRect.size.height /2 ? self.frame.origin.y - menuHeight - 10: self.frame.origin.y + self.frame.size.height,
width,
menuHeight);
menuHeight);*/
_popupMenu = [[UITableView alloc]initWithFrame:frame];
//_popupMenu = [[UITableView alloc]initWithFrame:frame];
_popupMenu.scrollEnabled = false;
_popupMenu.dataSource = self;
_popupMenu.delegate = self;
_popupMenu.separatorStyle = UITableViewCellSeparatorStyleNone;
_popupMenu.layer.masksToBounds = false;
_popupMenu.layer.shadowColor = [UIColor darkGrayColor].CGColor;
@ -955,11 +996,11 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
_popupMenu.editing = NO;
_popupMenu.userInteractionEnabled = true;
[_popupMenu reloadData];
[VIEW(ChatConversationView).tableController.view addSubview:_popupMenu];
//[VIEW(ChatConversationViewSwift).tableController.view addSubview:_popupMenu];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOutsideMenu:)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.numberOfTapsRequired = 1;
[VIEW(ChatConversationView).tableController.view addGestureRecognizer:tapGestureRecognizer];
//[VIEW(ChatConversationViewSwift).tableController.view addGestureRecognizer:tapGestureRecognizer];
}
-(void) dismissPopup {
@ -972,10 +1013,12 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18;
-(void) tapOutsideMenu:(UITapGestureRecognizer *) g {
CGPoint p = [g locationInView:VIEW(ChatConversationView).tableController.view];
/*
CGPoint p = [g locationInView:VIEW(ChatConversationViewSwift).tableController.view];
if (!CGRectContainsPoint(_popupMenu.frame,p)) {
[self dismissPopup];
}
*/
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

View file

@ -29,7 +29,8 @@
LinphoneChatRoom *chatRoom;
}
@property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage;
@property(readonly, nonatomic) LinphoneEventLog *event;
@property(nonatomic, strong) IBOutlet UIImageView *avatarImage;
@property (weak, nonatomic) IBOutlet UIImageView *securityImage;
@property(nonatomic, strong) IBOutlet UILabel *addressLabel;
@property(nonatomic, strong) IBOutlet UILabel *chatContentLabel;

View file

@ -21,6 +21,7 @@
#import "PhoneMainView.h"
#import "LinphoneManager.h"
#import "Utils.h"
#import "linphoneapp-Swift.h"
@implementation UIChatCell
@ -38,6 +39,10 @@
[self addSubview:sub];
}
[_imdmIcon setHidden:TRUE];
_unreadCountView.backgroundColor = VoipTheme.primary_color;
_unreadCountView.layer.cornerRadius = 10;
_unreadCountView.clipsToBounds = true;
_unreadCountLabel.textAlignment = NSTextAlignmentCenter;
return self;
}
@ -73,14 +78,15 @@
const LinphoneAddress *addr = firstParticipant ? linphone_participant_get_address(firstParticipant) : linphone_chat_room_get_peer_address(chatRoom);
if (addr) {
[ContactDisplay setDisplayNameLabel:_addressLabel forAddress:addr];
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForAddress:addr]];
} else {
_addressLabel.text = [NSString stringWithUTF8String:LINPHONE_DUMMY_SUBJECT];
}
bctbx_list_free(participants);
} else {
const char *subject = linphone_chat_room_get_subject(chatRoom);
_addressLabel.text = [NSString stringWithUTF8String:subject ?: LINPHONE_DUMMY_SUBJECT];
[_avatarImage setImage:[UIImage imageNamed:@"chat_group_avatar.png"] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[UIImage imageNamed:@"chat_group_avatar.png"]];
}
// TODO update security image when security level changed
[_securityImage setImage:[FastAddressBook imageForSecurityLevel:linphone_chat_room_get_security_level(chatRoom)]];
@ -89,11 +95,11 @@
LinphoneChatMessage *last_msg = linphone_chat_room_get_last_message_in_history(chatRoom);
if (last_msg) {
BOOL imdnInSnap = FALSE;
BOOL imdnInSnap = TRUE;
if (imdnInSnap) {
BOOL outgoing = linphone_chat_message_is_outgoing(last_msg);
NSString *text = [UIChatBubbleTextCell TextMessageForChat:last_msg];
if (outgoing) {
if (capabilities & LinphoneChatRoomCapabilitiesOneToOne) {
// shorten long messages
/*if ([text length] > 50)
text = [[text substringToIndex:50] stringByAppendingString:@"[...]"];*/
@ -117,6 +123,12 @@
_chatContentLabel.attributedText = boldText;
}
if (outgoing){
linphone_chat_message_set_user_data(last_msg, (void *)CFBridgingRetain(self));
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(last_msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, message_status);
linphone_chat_message_cbs_set_user_data(cbs, (void *)_event);
}
LinphoneChatMessageState state = linphone_chat_message_get_state(last_msg);
if (outgoing && (state == LinphoneChatMessageStateDeliveredToUser || state == LinphoneChatMessageStateDisplayed || state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError)) {
@ -132,7 +144,8 @@
_chatContentLabel.frame = newFrame;
}
} else {
NSString *text = [[FastAddressBook displayNameForAddress:linphone_chat_message_get_from_address(last_msg)]
NSString *conferenceInfo = [ICSBubbleView getConferenceSummaryWithCmessage:last_msg];
NSString *text = conferenceInfo != nil ? conferenceInfo : [[FastAddressBook displayNameForAddress:linphone_chat_message_get_from_address(last_msg)]
stringByAppendingFormat:@" : %@", [UIChatBubbleTextCell TextMessageForChat:last_msg]];
// shorten long messages
/*if ([text length] > 50)
@ -214,4 +227,15 @@
}
}
static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState state) {
LOGI(@"State for message [%p] changed to %s", msg, linphone_chat_message_state_to_string(state));
if (state == LinphoneChatMessageStateFileTransferInProgress)
return;
if (!linphone_chat_message_is_outgoing(msg) || (state != LinphoneChatMessageStateFileTransferDone && state != LinphoneChatMessageStateFileTransferInProgress)) {
ChatsListView *view = VIEW(ChatsListView);
[view.tableController updateEventEntry:msg];
}
}
@end

View file

@ -22,7 +22,7 @@
@interface UIChatConversationImdnTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIRoundedImageView *avatar;
@property (weak, nonatomic) IBOutlet UIImageView *avatar;
@property (weak, nonatomic) IBOutlet UILabel *displayName;
@property (weak, nonatomic) IBOutlet UILabel *dateLabel;
- (id)initWithIdentifier:(NSString *)identifier;

View file

@ -22,7 +22,7 @@
@interface UIChatConversationInfoTableViewCell : UITableViewCell <UIGestureRecognizerDelegate>
@property (weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage;
@property (weak, nonatomic) IBOutlet UIImageView *avatarImage;
@property (weak, nonatomic) IBOutlet UIIconButton *removeButton;
@property (weak, nonatomic) IBOutlet UIView *adminButton;
@property (weak, nonatomic) IBOutlet UILabel *adminLabel;

View file

@ -24,7 +24,7 @@
@property(weak, nonatomic) IBOutlet UILabel *addressLabel;
@property (weak, nonatomic) IBOutlet UIImageView *selectedImage;
@property (weak, nonatomic) IBOutlet UIImageView *linphoneImage;
@property (weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage;
@property (weak, nonatomic) IBOutlet UIImageView *avatarImage;
@property (weak, nonatomic) IBOutlet UIImageView *securityImage;
@property (weak, nonatomic) IBOutlet UIView *greyView;

View file

@ -21,9 +21,8 @@
#import "ChatConversationCreateView.h"
@interface UIChatCreateCollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property UILabel *nameLabel;
@property (strong, nonatomic) ChatConversationCreateView *controller;
@property (strong, nonatomic) NSString *uri;
- (id)initWithName:(NSString *)identifier;
- (void)onDelete;
@end

View file

@ -18,27 +18,31 @@
*/
#import "UIChatCreateCollectionViewCell.h"
#import "linphoneapp-Swift.h"
@implementation UIChatCreateCollectionViewCell
- (void)awakeFromNib {
[super awakeFromNib];
}
- (id)initWithName:(NSString *)identifier {
if (self != nil) {
NSArray *arrayOfViews =
[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil];
if ([arrayOfViews count] >= 1) {
UIChatCreateCollectionViewCell *sub = ((UIChatCreateCollectionViewCell *)[arrayOfViews objectAtIndex:0]);
[self addSubview:sub];
_nameLabel = sub.nameLabel;
}
}
[_nameLabel setText:identifier];
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
self.contentView.translatesAutoresizingMaskIntoConstraints = false;
[SnapkitBridge matchParentDimensionsWithView:self.contentView topInset:10];
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
self.nameLabel.numberOfLines = 1;
[self.contentView addSubview:self.nameLabel];
[SnapkitBridge matchParentDimensionsWithView:self.nameLabel leftInset:20];
[SnapkitBridge heightWithView:self heiht:50];
UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"conference_delete"]];
image.contentMode = UIViewContentModeScaleAspectFit;
[self.contentView addSubview:image];
[SnapkitBridge squareWithView:image size:15];
[SnapkitBridge alignParentLeftWithView:image];
[SnapkitBridge centerYWithView:image];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onDelete)];
tap.numberOfTouchesRequired = 1;
[self addGestureRecognizer:tap];
[image addGestureRecognizer:tap];
image.userInteractionEnabled = true;
return self;
}
@ -60,4 +64,6 @@
[_controller.tableController.tableView reloadData];
_controller.nextButton.enabled = (_controller.tableController.contactsGroup.count > 0) || _controller.isForEditing;
}
@end

View file

@ -33,6 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (weak, nonatomic) IBOutlet UICollectionView *contentCollection;
@property NSArray *dataContent;
@property (weak, nonatomic) IBOutlet UILabel *originalMessageGone;
@property (weak, nonatomic) IBOutlet UIImageView *icsIcon;
-(void) configureForMessage:(LinphoneChatMessage *)message withDimissBlock:(void (^)(void))dismissBlock hideDismiss:(BOOL)hideDismiss withClickBlock:(void (^)(void))clickBlock;
@end

View file

@ -40,6 +40,7 @@
-(void) viewDidLoad {
_contentCollection.dataSource = self;
[_icsIcon setImageNamed:@"voip_meeting_schedule" tintColor:VoipTheme.voip_dark_gray];
[_contentCollection registerClass:UICollectionViewCell.class forCellWithReuseIdentifier:@"dataContent"];
}
@ -51,6 +52,7 @@
_contentCollection.hidden = true;
_senderName.hidden = true;
_originalMessageGone.hidden = false;
_icsIcon.hidden = true;
return;
}
if (hideDismiss) {
@ -60,9 +62,12 @@
_originalMessageGone.hidden = true;
self.message = message;
self.dataContent = [self loadDataContent];
BOOL isIcal = [ICSBubbleView isConferenceInvitationMessageWithCmessage:message];
_icsIcon.hidden = !isIcal;
NSString *sender = [FastAddressBook displayNameForAddress:linphone_chat_message_get_from_address(message)];
_senderName.text = sender;
const char * text = linphone_chat_message_get_text_content(message);
const char * text = isIcal ? [ICSBubbleView getSubjectFromContentWithCmessage:message].UTF8String : linphone_chat_message_get_text_content(message);
if (text && strlen(text) == 0)
text = nil;
_textContent.text = text ? [NSString stringWithUTF8String:text] : @"";

View file

@ -91,8 +91,8 @@
#pragma mark -
- (void)accessoryForCell:(UITableViewCell *)cell atPath:(NSIndexPath *)indexPath {
cell.selectionStyle = UITableViewCellSelectionStyleGray;
if ([self isEditing]) {
cell.selectionStyle = UITableViewCellSelectionStyleGray;
UIButton *checkBoxButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = nil;
if ([_selectedItems containsObject:indexPath]) {

View file

@ -84,6 +84,7 @@
- (UIViewController *)getCurrentViewController;
- (UIInterfaceOrientation)currentOrientation;
- (void)clearCache:(NSArray *)exclude;
- (void)removeEntryFromCache:(NSString *)key;
- (IBAction)onRightSwipe:(id)sender;

View file

@ -305,6 +305,9 @@
return nil;
}
- (void)removeEntryFromCache:(NSString *)key {
[viewControllerCache removeObjectForKey:key];
}
- (void)clearCache:(NSArray *)exclude {
@ -313,7 +316,7 @@
bool remove = true;
/*ImagePickerView can be used as popover and we do NOT want to free it*/;
if ([key isEqualToString:ImagePickerView.compositeViewDescription.name] || [key isEqualToString:ActiveCallOrConferenceView.compositeViewDescription.name]) {
if ([key isEqualToString:ImagePickerView.compositeViewDescription.name] || [key isEqualToString:SingleCallView.compositeViewDescription.name] || [key isEqualToString:ConferenceCallView.compositeViewDescription.name]) {
remove = false;
} else if (exclude != nil) {
for (UICompositeViewDescription *description in exclude) {
@ -336,6 +339,9 @@
}
- (IBAction)onRightSwipe:(id)sender {
if (linphone_core_get_calls_nb(LC) > 0) {
return;
}
[self hideSideMenu:NO];
}
@ -402,6 +408,8 @@
sideMenu:(NSNumber *)sideMenu
fullscreen:(NSNumber *)fullscreen {
currentOrientation = [self getCorrectInterfaceOrientation:[[UIDevice currentDevice] orientation]];
UIViewController *oldMainViewController = self.mainViewController;
UIViewController *oldDetailsViewController = self.detailsViewController;
UIViewController *oldStatusBarViewController = self.statusBarViewController;
@ -657,6 +665,8 @@
// 4. side menu
self.sideMenuView.frame = sideMenuFrame;
self.sideMenuViewController.view.frame = self.sideMenuView.bounds;
[PhoneMainView.instance.mainViewController.view bringSubviewToFront:_sideMenuView];
[PhoneMainView.instance.mainViewController.view bringSubviewToFront:_sideMenuViewController.view];
// Commit animation
if (tabBar != nil || statusBar != nil || sideMenu != nil || fullscreen != nil) {

View file

@ -17,11 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "UIRoundBorderedButton.h"
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
#import "UIRoundBorderedButton.h"
typedef void (^UIConfirmationBlock)(void);
@interface UIConfirmationDialog : UIViewController {
@interface UIConfirmationDialog : UIViewController <UICompositeViewDelegate, UIGestureRecognizerDelegate, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource>{
UIConfirmationBlock onCancelCb;
UIConfirmationBlock onConfirmCb;
}
@ -49,13 +52,18 @@ typedef void (^UIConfirmationBlock)(void);
@property (weak, nonatomic) IBOutlet UIImageView *groupCallImage;
@property(weak, nonatomic) IBOutlet UIRoundBorderedButton *confirmationButton;
@property (weak, nonatomic) IBOutlet UIView *authView;
@property (weak, nonatomic) IBOutlet UIImageView *backgroundColor;
@property(weak, nonatomic) IBOutlet UILabel *titleLabel;
@property(weak, nonatomic) IBOutlet UIView *firstView;
@property (weak, nonatomic) IBOutlet UIButton *authButton;
@property(weak, nonatomic) IBOutlet UILabel *subscribeLabel;
- (void)setSpecialColor;
-(void) setWhiteCancel;
- (IBAction)onCancelClick:(id)sender;
- (IBAction)onConfirmationClick:(id)sender;
- (IBAction)onAuthClick:(id)sender;
- (IBAction)onSubscribeTap:(id)sender;
- (void)dismiss;
@end

View file

@ -19,7 +19,7 @@
#import "UIConfirmationDialog.h"
#import "PhoneMainView.h"
#import "linphoneapp-Swift.h""
#import "linphoneapp-Swift.h"
@implementation UIConfirmationDialog
+ (UIConfirmationDialog *)initDialog:(NSString *)cancel
@ -33,6 +33,8 @@
dialog.view.frame = PhoneMainView.instance.mainViewController.view.frame;
[controller.view addSubview:dialog.view];
[controller addChildViewController:dialog];
dialog.backgroundColor.layer.cornerRadius = 10;
dialog.backgroundColor.layer.masksToBounds = true;
dialog->onCancelCb = onCancel;
dialog->onConfirmCb = onConfirm;
@ -48,9 +50,21 @@
[[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]] CGColor];
dialog.cancelButton.layer.borderColor =
[[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_F.png"]] CGColor];
if (linphone_core_get_post_quantum_available()) {
[dialog.securityImage setImage:[UIImage imageNamed:@"post_quantum_secure.png"]];
}
return dialog;
}
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(onCancelClick:)];
tapGestureRecognizer.delegate = self;
[self.firstView addGestureRecognizer:tapGestureRecognizer];
}
+ (UIConfirmationDialog *)ShowWithMessage:(NSString *)message
cancelMessage:(NSString *)cancel
confirmMessage:(NSString *)confirm
@ -131,4 +145,12 @@
- (void)dismiss {
[self onCancelClick:nil];
}
- (IBAction)onSubscribeTap:(id)sender {
UIGestureRecognizer *gest = sender;
NSString *url = ((UILabel *)gest.view).text;
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
}
}
@end

View file

@ -24,7 +24,8 @@
@interface UIContactCell : UITableViewCell
@property(nonatomic, strong) IBOutlet UILabel *nameLabel;
@property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage;
@property(nonatomic, strong) IBOutlet UILabel *organizationLabel;
@property(nonatomic, strong) IBOutlet UIImageView *avatarImage;
@property(weak, nonatomic) IBOutlet UIImageView *linphoneImage;
@property(nonatomic, assign) Contact *contact;

View file

@ -79,6 +79,7 @@
_linphoneImage.hidden = TRUE;
if(_contact) {
[ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact];
_organizationLabel.text = [FastAddressBook ogrganizationForContact:_contact];
_linphoneImage.hidden = [LinphoneManager.instance lpConfigBoolForKey:@"hide_linphone_contacts" inSection:@"app"] ||
! ((_contact.friend && linphone_presence_model_get_basic_status(linphone_friend_get_presence_model(_contact.friend)) == LinphonePresenceBasicStatusOpen) || [FastAddressBook contactHasValidSipDomain:_contact]);
}

View file

@ -50,28 +50,34 @@
normAddr = linphone_account_normalize_phone_number(account,
_addressLabel.text.UTF8String);
}
LinphoneAddress *addr = linphone_core_interpret_url(LC, normAddr);
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, normAddr, true);
_chatButton.enabled = _callButton.enabled = _encryptedChatButton.enabled = (addr != NULL);
_chatButton.accessibilityLabel =
[NSString stringWithFormat:NSLocalizedString(@"Chat with %@", nil), _addressLabel.text];
_callButton.accessibilityLabel = [NSString stringWithFormat:NSLocalizedString(@"Call %@", nil), _addressLabel.text];
// Test presence
Contact *contact;
contact = addr ? [FastAddressBook getContactWithAddress:(addr)] : NULL;
Contact *contact = addr ? [FastAddressBook getContactWithAddress:(addr)] : NULL;
LinphoneFriend *contactFriend = NULL;
if (contact && contact.friend) {
contactFriend = contact.friend;
} else if (addr) {
contactFriend = linphone_core_find_friend(LC, addr);
}
ContactDetailsView *contactDetailsView = VIEW(ContactDetailsView);
_linphoneImage.hidden = TRUE;
if (contact) {
const LinphonePresenceModel *model = contact.friend ? linphone_friend_get_presence_model_for_uri_or_tel(contact.friend, _addressLabel.text.UTF8String) : NULL;
if (contactFriend) {
const LinphonePresenceModel *model = contactFriend ? linphone_friend_get_presence_model_for_uri_or_tel(contactFriend, _addressLabel.text.UTF8String) : NULL;
self.linphoneImage.hidden = [LinphoneManager.instance lpConfigBoolForKey:@"hide_linphone_contacts" inSection:@"app"] ||
!((model && linphone_presence_model_get_basic_status(model) == LinphonePresenceBasicStatusOpen) ||
(account && !linphone_account_is_phone_number(account,
_addressLabel.text.UTF8String) &&
[FastAddressBook isSipURIValid:_addressLabel.text]));
ContactDetailsView *contactDetailsView = VIEW(ContactDetailsView);
self.inviteButton.hidden = !ENABLE_SMS_INVITE || [[contactDetailsView.contact sipAddresses] count] > 0 || !self.linphoneImage.hidden;
self.inviteButton.hidden = !ENABLE_SMS_INVITE || [[contactDetailsView.contact sipAddresses] count] > 0 || !self.linphoneImage.hidden;
[self shouldHideEncryptedChatView:account && linphone_account_params_get_conference_factory_uri(linphone_account_get_params(account)) && model && linphone_presence_model_has_capability(model, LinphoneFriendCapabilityLimeX3dh)];
_chatButton.hidden = [LinphoneManager.instance lpConfigBoolForKey:@"force_lime_chat_rooms"] || [LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"];
}
if (addr) {
@ -80,7 +86,7 @@
}
- (void)shouldHideEncryptedChatView:(BOOL)hasLime {
_encryptedChatView.hidden = !hasLime;
_encryptedChatView.hidden = !hasLime || [LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"];
CGRect newFrame = _optionsView.frame;
if (!hasLime) {
newFrame.origin.x = _addressLabel.frame.origin.x + _callButton.frame.size.width * 2/3;
@ -103,7 +109,7 @@
normAddr = linphone_account_normalize_phone_number(account,
_addressLabel.text.UTF8String);
}
LinphoneAddress *addr = linphone_core_interpret_url(LC, normAddr);
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, normAddr, true);
// Test presence
Contact *contact = [FastAddressBook getContactWithAddress:(addr)];

View file

@ -67,7 +67,6 @@
if (addressField && (!dtmf || !linphone_core_in_call(LC))) {
NSString *newAddress = [NSString stringWithFormat:@"%@%c", addressField.text, digit];
[addressField setText:newAddress];
linphone_core_play_dtmf(LC, digit, -1);
} else {
linphone_call_send_dtmf(linphone_core_get_current_call(LC), digit);
linphone_core_play_dtmf(LC, digit, 100);

View file

@ -28,7 +28,7 @@
@property (nonatomic, assign) LinphoneCallLog *callLog;
@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage;
@property(weak, nonatomic) IBOutlet UIImageView *avatarImage;
@property(nonatomic, strong) IBOutlet UILabel *displayNameLabel;
@property(weak, nonatomic) IBOutlet UIImageView *stateImage;
@property(weak, nonatomic) IBOutlet UIIconButton *detailsButton;

View file

@ -77,7 +77,7 @@
- (NSString *)accessibilityValue {
BOOL incoming = linphone_call_log_get_dir(callLog) == LinphoneCallIncoming;
BOOL missed = linphone_call_log_get_status(callLog) == LinphoneCallMissed;
BOOL missed = [SwiftUtil isCallLogMissedWithCLog:callLog];
NSString *call_type = incoming ? (missed ? @"Missed" : @"Incoming") : @"Outgoing";
return [NSString stringWithFormat:@"%@ call from %@", call_type, displayNameLabel.text];
}
@ -91,7 +91,7 @@
// Set up the cell...
if (linphone_call_log_was_conference(callLog)) {
const char *subject = linphone_conference_info_get_subject(linphone_call_log_get_conference_info(callLog));
displayNameLabel.text = [NSString stringWithFormat:@"%s",subject];
displayNameLabel.text = [NSString stringWithUTF8String:subject];
[_avatarImage setImage:[UIImage imageNamed:@"voip_multiple_contacts_avatar"]];
_stateImage.hidden = true;
} else {
@ -99,7 +99,7 @@
const LinphoneAddress *addr;
UIImage *image;
if (linphone_call_log_get_dir(callLog) == LinphoneCallIncoming) {
if (linphone_call_log_get_status(callLog) != LinphoneCallMissed) {
if (![SwiftUtil isCallLogMissedWithCLog:callLog]) {
image = [UIImage imageNamed:@"call_status_incoming.png"];
} else {
image = [UIImage imageNamed:@"call_status_missed.png"];
@ -118,7 +118,7 @@
[displayNameLabel.text stringByAppendingString:[NSString stringWithFormat:@" (%lu)", count]];
}
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
[_avatarImage setImage:[FastAddressBook imageForAddress:addr]];
}
}

View file

@ -92,12 +92,6 @@
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
[_stopButton setTitle:@"" forState:UIControlStateNormal];
[_stopButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemRefresh:[UIColor blackColor]] forState:UIControlStateNormal];
if (linphone_player_get_is_video_available(player)) {
linphone_player_set_window_id(player, (__bridge void *)VIEW(RecordingsListView).videoView);
VIEW(RecordingsListView).videoView.hidden = NO;
} else {
VIEW(RecordingsListView).videoView.hidden = YES;
}
}
- (BOOL)isOpened {
@ -195,6 +189,12 @@ void on_eof_reached(LinphonePlayer *pl) {
[_playButton setTitle:@"" forState:UIControlStateNormal];
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPause:[UIColor blackColor]] forState:UIControlStateNormal];
linphone_player_start(player);
if (linphone_player_get_is_video_available(player)) {
linphone_player_set_window_id(player, (__bridge void *)VIEW(RecordingsListView).videoView);
VIEW(RecordingsListView).videoView.hidden = NO;
} else {
VIEW(RecordingsListView).videoView.hidden = YES;
}
break;
case LinphonePlayerPlaying:
NSLog(@"Pause");

View file

@ -25,8 +25,6 @@
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *shareButton;
@property(nonatomic, assign) __block NSString *recording;
- (id)initWithIdentifier:(NSString*)identifier;

View file

@ -64,7 +64,8 @@ static UILinphoneAudioPlayer *player;
NSArray *parsedRecording = [LinphoneUtils parseRecordingName:_recording];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"HH:mm:ss"];
_nameLabel.text = [[[parsedRecording objectAtIndex:0] stringByAppendingString:@" @ "] stringByAppendingString:[dateFormat stringFromDate:[parsedRecording objectAtIndex:1]]];
NSString *b = [[parsedRecording objectAtIndex:0] containsString:@"conf-id"] ? NSLocalizedString(@"Meeting", nil) : [parsedRecording objectAtIndex:0];
_nameLabel.text = [[b stringByAppendingString:@" @ "] stringByAppendingString:[dateFormat stringFromDate:[parsedRecording objectAtIndex:1]]];
}
}
@ -89,7 +90,8 @@ static UILinphoneAudioPlayer *player;
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
self.selectionStyle = UITableViewCellSelectionStyleNone;
if (!VIEW(RecordingsListView).tableController.isEditing)
self.selectionStyle = UITableViewCellSelectionStyleNone;
}
- (void)updateFrame {
@ -104,10 +106,11 @@ static UILinphoneAudioPlayer *player;
-(void)setSelected:(BOOL)selected animated:(BOOL)animated{
[super setSelected:selected animated:animated];
_toolbar.hidden = !selected;
if (!selected) {
return;
}
if (!selected || (selected && VIEW(RecordingsListView).tableController.isEditing)) {
_toolbar.hidden = true;
return;
}
if (player && [player isCreated]) {
[player close];
}
@ -121,6 +124,7 @@ static UILinphoneAudioPlayer *player;
player.view.frame = _playerView.frame;
player.view.bounds = _playerView.bounds;
[player open];
_toolbar.hidden = false;
}
- (void)onShareButtonPressed {

View file

@ -20,6 +20,7 @@ import linphonesw
var previousFilter : String?
var magicSearch : MagicSearch
var magicSearchDelegate : MagicSearchDelegate?
var lastSearch : [SearchResult]?
override init() {
@ -30,10 +31,12 @@ import linphonesw
magicSearchDelegate = MagicSearchDelegateStub(onSearchResultsReceived: { (magicSearch: MagicSearch) in
self.needUpdateLastSearchContacts = true
self.ongoingSearch = false
self.lastSearch = magicSearch.lastSearch
Log.directLog(BCTBX_LOG_MESSAGE, text: "Contact magic search -- filter = \(String(describing: self.previousFilter)) -- \(magicSearch.lastSearch.count) contact founds")
NotificationCenter.default.post(name: Notification.Name(kLinphoneMagicSearchFinished), object: self)
}, onLdapHaveMoreResults: { (magicSearch: MagicSearch, ldap: Ldap) in
Log.directLog(BCTBX_LOG_MESSAGE, text: "Ldap have more result")
NotificationCenter.default.post(name: Notification.Name(kLinphoneMagicSearchMoreAvailable), object: self)
})
magicSearch.addDelegate(delegate: magicSearchDelegate!)
@ -47,17 +50,26 @@ import linphonesw
return theMagicSearchSingleton!
}
@objc static func destroyInstance() {
theMagicSearchSingleton = nil
}
func getContactFromAddr(addr: Address) -> Contact? {
return LinphoneManager.instance().fastAddressBook.addressBookMap.object(forKey: addr.asStringUriOnly() as Any) as? Contact
}
func getContactFromPhoneNb(phoneNb: String) -> Contact? {
let contactKey = FastAddressBook.localizedLabel(FastAddressBook.normalizeSipURI( lc?.defaultAccount?.normalizePhoneNumber(username: phoneNb) ?? phoneNb))
let contactKey = FastAddressBook.localizedLabel(FastAddressBook.normalizeSipURI(lc?.defaultAccount?.normalizePhoneNumber(username: phoneNb) ?? phoneNb, use_prefix: true))
return LinphoneManager.instance().fastAddressBook.addressBookMap.object(forKey: contactKey as Any) as? Contact
}
func searchAndAddMatchingContact(searchResult: SearchResult) -> Contact? {
if let friend = searchResult.friend {
if (searchResult.sourceFlags == MagicSearchSource.LdapServers.rawValue), let newContact = Contact(friend: friend.getCobject) {
// Contact comes from LDAP, creating a new one
newContact.createdFromLdapOrProvisioning = true
return newContact
}
if let addr = friend.address, let foundContact = getContactFromAddr(addr: addr) {
return foundContact
}
@ -66,11 +78,6 @@ import linphonesw
return foundContact
}
}
// No contacts found (searchResult likely comes from LDAP), creating a new one
if let newContact = Contact(friend: friend.getCobject) {
newContact.createdFromLdap = true
return newContact
}
}
if let addr = searchResult.address, let foundContact = getContactFromAddr(addr: addr) {
@ -81,6 +88,11 @@ import linphonesw
return foundContact
}
// Friend comes from provisioning
if let addr = searchResult.address, let friend = searchResult.friend, let newContact = Contact(friend: friend.getCobject) {
newContact.createdFromLdapOrProvisioning = true
return newContact
}
return nil
}
@ -91,8 +103,10 @@ import linphonesw
@objc func getLastSearchResults() -> UnsafeMutablePointer<bctbx_list_t>? {
var cList: UnsafeMutablePointer<bctbx_list_t>? = nil
for data in magicSearch.lastSearch {
cList = bctbx_list_append(cList, UnsafeMutableRawPointer(data.getCobject))
if let search = lastSearch {
for data in search {
cList = bctbx_list_append(cList, UnsafeMutableRawPointer(data.getCobject))
}
}
return cList
}
@ -100,13 +114,9 @@ import linphonesw
@objc func getLastSearchContacts() -> [Contact] {
if (needUpdateLastSearchContacts) {
lastSearchContacts = []
var addedContactNames : [String] = []
for res in magicSearch.lastSearch {
if let contact = searchAndAddMatchingContact(searchResult: res) {
if (!addedContactNames.contains(contact.displayName)) {
addedContactNames.append(contact.displayName)
lastSearchContacts.append(contact)
}
lastSearchContacts.append(contact)
}
}
needUpdateLastSearchContacts = false

View file

@ -114,6 +114,8 @@
- (void)getOrCreateOneToOneChatRoom:(const LinphoneAddress *)remoteAddress waitView:(UIView *)waitView isEncrypted:(BOOL)isEncrypted;
- (LinphoneChatRoom *)createChatRoom:(const char *)subject addresses:(bctbx_list_t *)addresses andWaitView:(UIView *)waitView isEncrypted:(BOOL)isEncrypted isGroup:(BOOL)isGroup;
- (void)goToChatRoom:(LinphoneChatRoom *)cr;
- (void)goToChatRoomSwift:(LinphoneChatRoom *)cr;
- (void)resetBeforeGoToChatRoomSwift;
+ (PhoneMainView*) instance;
- (BOOL)isIphoneXDevice;
@ -123,3 +125,4 @@
@end
void main_view_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState);
void main_view_chat_room_conference_joined(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);

View file

@ -306,9 +306,9 @@ static RootViewManager *rootViewManagerInstance = nil;
if (linphone_chat_message_is_outgoing(msg))
return;
ChatConversationView *view = VIEW(ChatConversationView);
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
// if we already are in the conversation, we should not ring/vibrate
if (view.chatRoom && _currentRoom == view.chatRoom)
if (view.linphoneChatRoom && _currentRoom == view.linphoneChatRoom)
return;
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive)
@ -374,7 +374,6 @@ static RootViewManager *rootViewManagerInstance = nil;
}
break;
}
case LinphoneCallOutgoingInit:
case LinphoneCallOutgoingEarlyMedia:
case LinphoneCallOutgoingProgress:
case LinphoneCallOutgoingRinging: {
@ -386,7 +385,7 @@ static RootViewManager *rootViewManagerInstance = nil;
}
break;
}
case LinphoneCallPausedByRemote:
case LinphoneCallPausedByRemote:break;
case LinphoneCallConnected: {
if (![LinphoneManager.instance isCTCallCenterExist]) {
/*only register CT call center CB for connected call*/
@ -418,6 +417,7 @@ static RootViewManager *rootViewManagerInstance = nil;
}
case LinphoneCallUpdating:
break;
}
if (state == LinphoneCallEnd || state == LinphoneCallError || floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max)
[self updateApplicationBadgeNumber];
@ -453,9 +453,19 @@ static RootViewManager *rootViewManagerInstance = nil;
LinphoneManager *lm = LinphoneManager.instance;
LOGI(@"%s", linphone_global_state_to_string(linphone_core_get_global_state(LC)));
NSString* groupName = [NSString stringWithFormat:@"group.%@.linphoneExtension",[[NSBundle mainBundle] bundleIdentifier]];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName];
NSDictionary *dict = [defaults valueForKey:@"photoData"];
NSDictionary *dictFile = [defaults valueForKey:@"icloudData"];
NSDictionary *dictUrl = [defaults valueForKey:@"url"];
// If we've been started by a remote push notification,
// we'll already be on the corresponding chat conversation view, no need to go anywhere else
if (![[self currentView].name isEqualToString:@"ChatConversationView"]) {
if (dict||dictFile||dictUrl){
[self changeCurrentView:ChatsListView.compositeViewDescription];
}else if (![[self currentView].name isEqualToString:@"ChatConversationViewSwift"]) {
if (linphone_core_get_global_state(LC) != LinphoneGlobalOn) {
[self changeCurrentView:DialerView.compositeViewDescription];
@ -607,7 +617,8 @@ static RootViewManager *rootViewManagerInstance = nil;
}
[self _changeCurrentView:viewStack.lastObject ?: DialerView.compositeViewDescription
transition:[PhoneMainView getBackwardTransition]
animated:ANIMATED];
animated:ANIMATED
addViewToStack:FALSE];
return [mainViewController getCurrentViewController];
}
@ -621,18 +632,19 @@ static RootViewManager *rootViewManagerInstance = nil;
- (void)changeCurrentView:(UICompositeViewDescription *)view {
[self _changeCurrentView:view transition:nil animated:ANIMATED];
[self _changeCurrentView:view transition:nil animated:ANIMATED addViewToStack:TRUE];
}
- (UIViewController *)_changeCurrentView:(UICompositeViewDescription *)view
transition:(CATransition *)transition
animated:(BOOL)animated {
animated:(BOOL)animated
addViewToStack:(BOOL)addViewToStack {
PhoneMainView *vc = [[RootViewManager instance] setViewControllerForDescription:view];
if (![view equal:vc.currentView] || vc != self) {
LOGI(@"Change current view to %@", view.name);
[self setPreviousViewName:vc.currentView.name];
NSMutableArray *viewStack = [RootViewManager instance].viewDescriptionStack;
[viewStack addObject:view];
if (addViewToStack) [viewStack addObject:view];
if (animated && transition == nil)
transition = [PhoneMainView getTransition:vc.currentView new:view];
[vc.mainViewController setViewTransition:(animated ? transition : nil)];
@ -653,7 +665,8 @@ static RootViewManager *rootViewManagerInstance = nil;
while (viewStack.count > 0 && ![[viewStack lastObject] equal:view]) {
[viewStack removeLastObject];
}
return [self _changeCurrentView:view transition:[PhoneMainView getBackwardTransition] animated:ANIMATED];
BOOL addView = (viewStack.count == 0); // if we couldn't find the view in the stack, we need to add it
return [self _changeCurrentView:view transition:[PhoneMainView getBackwardTransition] animated:ANIMATED addViewToStack:addView];
}
- (void) setPreviousViewName:(NSString*)previous{
@ -838,7 +851,7 @@ static RootViewManager *rootViewManagerInstance = nil;
return;
}
[self goToChatRoom:room];
[self goToChatRoomSwift:room];
}
- (LinphoneChatRoom *)createChatRoom:(const char *)subject addresses:(bctbx_list_t *)addresses andWaitView:(UIView *)waitView isEncrypted:(BOOL)isEncrypted isGroup:(BOOL)isGroup{
@ -861,7 +874,7 @@ static RootViewManager *rootViewManagerInstance = nil;
return nil;
}
LinphoneChatRoom *basicRoom = linphone_core_get_chat_room(LC, addresses->data);
[self goToChatRoom:basicRoom];
[self goToChatRoomSwift:basicRoom];
return nil;
}
@ -884,6 +897,7 @@ static RootViewManager *rootViewManagerInstance = nil;
LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, main_view_chat_room_state_changed);
linphone_chat_room_cbs_set_conference_joined(cbs, main_view_chat_room_conference_joined);
linphone_chat_room_add_callbacks(room, cbs);
return room;
@ -901,31 +915,50 @@ static RootViewManager *rootViewManagerInstance = nil;
[view clearMessageView];
view.chatRoom = cr;
view.peerAddress = linphone_address_as_string(linphone_chat_room_get_peer_address(cr));
view.localAddress = linphone_address_as_string(linphone_chat_room_get_local_address(cr));
self.currentRoom = view.chatRoom;
if (PhoneMainView.instance.currentView == view.compositeViewDescription)
[view configureForRoom:FALSE];
else
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
- (void)goToChatRoomSwift:(LinphoneChatRoom *)cr {
_waitView.hidden = YES;
_waitView = NULL;
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
self.currentRoom = view.linphoneChatRoom;
[view initChatRoomWithCChatRoom:cr];
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
- (void)resetBeforeGoToChatRoomSwift{
ChatConversationViewSwift *view = VIEW(ChatConversationViewSwift);
[view resetView];
}
void main_view_chat_room_conference_joined(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PhoneMainView *view = PhoneMainView.instance;
LOGI(@"Chat room [%p] conference joined.", cr);
linphone_chat_room_remove_callbacks(cr, linphone_chat_room_get_current_callbacks(cr));
[view goToChatRoomSwift:cr];
if (!IPAD)
return;
if (PhoneMainView.instance.currentView != ChatsListView.compositeViewDescription && PhoneMainView.instance.currentView != ChatConversationViewSwift.compositeViewDescription)
return;
ChatsListView *mainView = VIEW(ChatsListView);
[mainView.tableController loadData];
[mainView.tableController selectFirstRow];
}
void main_view_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
PhoneMainView *view = PhoneMainView.instance;
switch (newState) {
case LinphoneChatRoomStateCreated: {
LOGI(@"Chat room [%p] created on server.", cr);
linphone_chat_room_remove_callbacks(cr, linphone_chat_room_get_current_callbacks(cr));
[view goToChatRoom:cr];
if (!IPAD)
break;
if (PhoneMainView.instance.currentView != ChatsListView.compositeViewDescription && PhoneMainView.instance.currentView != ChatConversationView.compositeViewDescription)
break;
ChatsListView *mainView = VIEW(ChatsListView);
[mainView.tableController loadData];
[mainView.tableController selectFirstRow];
break;
}
case LinphoneChatRoomStateCreationFailed:
LOGE(@"Chat room [%p] could not be created on server.", cr);
linphone_chat_room_remove_callbacks(cr, linphone_chat_room_get_current_callbacks(cr));
@ -934,7 +967,7 @@ void main_view_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomSta
break;
case LinphoneChatRoomStateTerminated:
LOGI(@"Chat room [%p] has been terminated.", cr);
[view goToChatRoom:cr];
[view goToChatRoomSwift:cr];
break;
default:
break;
@ -958,4 +991,8 @@ void main_view_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomSta
}
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[UIDeviceBridge notifyDisplayModeSwitch];
}
@end

View file

@ -147,8 +147,6 @@
NSString *recordingPath = subAr[indexPath.row];
[cell setRecording:recordingPath];
[super accessoryForCell:cell atPath:indexPath];
//accessoryForCell set it to gray but we don't want it
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell updateFrame];
cell.contentView.userInteractionEnabled = false;
return cell;

View file

@ -22,12 +22,12 @@
#import "LinphoneAppDelegate.h"
#import "PhoneMainView.h"
#import "Utils.h"
#import "linphoneapp-Swift.h"
#import "DCRoundSwitch.h"
#import "IASKSpecifierValuesViewController.h"
#import "IASKPSTextFieldSpecifierViewCell.h"
#import "IASKPSTitleValueSpecifierViewCell.h"
#import "IASKSpecifier.h"
#import "IASKTextField.h"
#include "linphone/lpconfig.h"
@ -247,7 +247,7 @@
[field setTextColor:LINPHONE_MAIN_COLOR];
}
if ([cell isKindOfClass:[IASKPSTitleValueSpecifierViewCell class]]) {
if ([cell isKindOfClass:[UITableViewCell class]]) {
cell.detailTextLabel.textColor = [UIColor grayColor];
} else {
cell.detailTextLabel.textColor = LINPHONE_MAIN_COLOR;
@ -445,8 +445,11 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
linphone_account_creator_set_password(creator, _tmpPwd.UTF8String);
[settingsStore setObject:_tmpPwd forKey:@"account_mandatory_password_preference"];
MSList *accountList = [LinphoneManager.instance createAccountsNotHiddenList];
LinphoneAccount *account = bctbx_list_nth_data(linphone_core_get_account_list(LC),
[settingsStore integerForKey:@"current_proxy_config_preference"]);
bctbx_free(accountList);
if (account != NULL) {
const LinphoneAuthInfo *auth = linphone_account_find_auth_info(account);
if (auth) {
@ -521,11 +524,26 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
[keys addObject:@"download_bandwidth_preference"];
} else if ([@"auto_download_mode" compare:notif.object] == NSOrderedSame) {
NSString *download_mode = [notif.userInfo objectForKey:@"auto_download_mode"];
removeFromHiddenKeys = [download_mode isEqualToString:@"Customize"];
if (removeFromHiddenKeys)
[LinphoneManager.instance lpConfigSetInt:10000000 forKey:@"auto_download_incoming_files_max_size"];
[keys addObject:@"auto_download_incoming_files_max_size"];
}
if([download_mode isEqualToString:@"Customize"]){
[LinphoneManager.instance lpConfigSetBool:FALSE forKey:@"auto_download_mode_is_never"];
removeFromHiddenKeys = [download_mode isEqualToString:@"Customize"];
[LinphoneManager.instance lpConfigSetInt:10000000 forKey:@"auto_download_incoming_files_max_size"];
[keys addObject:@"auto_download_incoming_files_max_size"];
[hiddenKeys addObject:@"auto_write_to_gallery_mode"];
} else {
[LinphoneManager.instance lpConfigSetBool:FALSE forKey:@"auto_download_mode_is_never"];
[hiddenKeys addObject:@"auto_download_incoming_files_max_size"];
}
}else if ([@"vfs_enabled_mode" compare:notif.object] == NSOrderedSame) {
removeFromHiddenKeys = [[notif.userInfo objectForKey:@"vfs_enabled_mode"] boolValue];
if(removeFromHiddenKeys){
[LinphoneManager.instance lpConfigSetBool:TRUE forKey:@"vfs_enabled_mode"];
[LinphoneManager.instance lpConfigSetBool:FALSE forKey:@"auto_write_to_gallery_preference"];
[hiddenKeys addObject:@"auto_write_to_gallery_mode"];
[hiddenKeys addObject:@"vfs_enabled_mode"];
[keys addObject:@"vfs_enabled"];
}
}
for (NSString *key in keys) {
if (removeFromHiddenKeys)
@ -552,11 +570,12 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
return [[IASKSpecifier alloc] initWithSpecifier:dict];
}
} else {
if ([[specifier key] isEqualToString:@"media_encryption_preference"]) {
BOOL pq_available = linphone_core_get_post_quantum_available();
if ([[specifier key] isEqualToString:pq_available ? @"media_encryption_preference_pq_enabled" : @"media_encryption_preference"]) {
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[specifier specifierDict]];
if (!linphone_core_media_encryption_supported(LC, LinphoneMediaEncryptionZRTP)) {
NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]];
[titles removeObject:@"ZRTP"];
[titles removeObject:pq_available ? @"ZRTP" : @"ZRTP Post Quantum"];
[dict setObject:titles forKey:@"Titles"];
NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]];
[values removeObject:@"ZRTP"];
@ -583,7 +602,7 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
}
if ([specifier.key hasPrefix:@"menu_account_"]) {
const bctbx_list_t *accounts = linphone_core_get_account_list(LC);
MSList *accounts = [LinphoneManager.instance createAccountsNotHiddenList];
int index = [specifier.key substringFromIndex:@"menu_account_".length].intValue - 1;
if (index < bctbx_list_size(accounts)) {
LinphoneAccount *account = (LinphoneAccount *)bctbx_list_nth_data(accounts, index);
@ -591,6 +610,7 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
stringWithUTF8String:linphone_address_get_username(linphone_account_params_get_identity_address(linphone_account_get_params(account)))];
[specifier.specifierDict setValue:name forKey:kIASKTitle];
}
bctbx_free(accounts);
}
if ([specifier.key hasPrefix:@"ldap_"]) {
@ -625,23 +645,40 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
- (NSSet *)findHiddenKeys {
LinphoneManager *lm = LinphoneManager.instance;
NSMutableSet *hiddenKeys = [NSMutableSet set];
const MSList *accounts = linphone_core_get_account_list(LC);
MSList *accounts = [LinphoneManager.instance createAccountsNotHiddenList];
for (size_t i = bctbx_list_size(accounts) + 1; i <= 5; i++) {
[hiddenKeys addObject:[NSString stringWithFormat:@"menu_account_%lu", i]];
}
bctbx_free(accounts);
const MSList *ldaps = linphone_core_get_ldap_list(LC);
for (size_t i = bctbx_list_size(ldaps) + 1; i <= 5; i++) {
[hiddenKeys addObject:[NSString stringWithFormat:@"ldap_%lu", i]];
}
if (!linphone_core_sip_transport_supported(LC, LinphoneTransportTls)) {
[hiddenKeys addObject:@"media_encryption_preference"];
[hiddenKeys addObject:@"media_encryption_preference_pq_enabled"];
} else {
if (linphone_core_get_post_quantum_available()) {
[hiddenKeys addObject:@"media_encryption_preference"];
} else {
[hiddenKeys addObject:@"media_encryption_preference_pq_enabled"];
}
}
if (!linphone_core_ldap_available(LC)) {
[hiddenKeys addObject:@"contacts_menu"];
}
if ([LinphoneManager.instance lpConfigBoolForKey:@"disable_chat_feature"]){
[hiddenKeys addObject:@"message_menu"];
}
if ([LinphoneManager.instance lpConfigBoolForKey:@"disable_video_feature"]) {
[hiddenKeys addObject:@"enable_video_preference"];
[hiddenKeys addObject:@"video_menu"];
}
#ifndef DEBUG
[hiddenKeys addObject:@"debug_actions_group"];
[hiddenKeys addObject:@"release_button"];
@ -761,6 +798,13 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
if (![[lm lpConfigStringForKey:@"auto_download_mode"] isEqualToString:@"Customize"]) {
[hiddenKeys addObject:@"auto_download_incoming_files_max_size"];
}
if ([lm lpConfigBoolForKey:@"vfs_enabled_mode"]) {
[hiddenKeys addObject:@"auto_write_to_gallery_mode"];
[hiddenKeys addObject:@"vfs_enabled_mode"];
}else{
[hiddenKeys addObject:@"vfs_enabled"];
}
return hiddenKeys;
}
@ -851,25 +895,34 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
[PhoneMainView.instance changeCurrentView:AssistantView.compositeViewDescription];
return;
} else if ([key isEqual:@"account_mandatory_remove_button"]) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Warning", nil)
message:NSLocalizedString(@"Are you sure to want to remove your proxy setup?", nil)
preferredStyle:UIAlertControllerStyleAlert];
NSString *popUpText;
NSString *appDomain = [LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
MSList *accountList = [LinphoneManager.instance createAccountsNotHiddenList];
LinphoneAccount *account = bctbx_list_nth_data(accountList,
[settingsStore integerForKey:@"current_proxy_config_preference"]);
UIAlertAction* continueAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Yes", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[settingsStore removeAccount];
[self recomputeAccountLabelsAndSync];
[_settingsController.navigationController popViewControllerAnimated:NO];
}];
bool isLinphoneAccount = strcmp(appDomain.UTF8String, linphone_account_params_get_domain(linphone_account_get_params(account))) == 0;
if (isLinphoneAccount) {
popUpText = NSLocalizedString(@"Your account will only be deleted locally.\nTo delete it permanently, go to our account management platform:", nil);
} else {
popUpText = NSLocalizedString(@"Your account will only be deleted locally.\nTo delete it permanently, go on your SIP provider website.", nil);
}
bctbx_free(accountList);
[errView addAction:defaultAction];
[errView addAction:continueAction];
[self presentViewController:errView animated:YES completion:nil];
UIConfirmationDialog *dialog = [UIConfirmationDialog ShowWithMessage:popUpText
cancelMessage:nil
confirmMessage:nil
onCancelClick:nil
onConfirmationClick:^() {
[settingsStore removeAccount];
[self recomputeAccountLabelsAndSync];
[_settingsController.navigationController popViewControllerAnimated:NO];
}];
dialog.subscribeLabel.hidden = !isLinphoneAccount; // Only display link to https://subscribe.linphone.org for linphone accounts
} else if ([key isEqual:@"account_mandatory_change_password"]) {
UIAlertController *alertView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Change your password", nil)
message:NSLocalizedString(@"Please enter and confirm your new password", nil)
@ -901,8 +954,11 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
if (pwd && ![pwd isEqualToString:@""]) {
if ([pwd isEqualToString:conf_pwd]) {
_tmpPwd = pwd;
LinphoneAccount *account = bctbx_list_nth_data(linphone_core_get_account_list(LC),
[settingsStore integerForKey:@"current_proxy_config_preference"]);
MSList *accounts = [LinphoneManager.instance createAccountsNotHiddenList];
LinphoneAccount *account = bctbx_list_nth_data(accounts,
[settingsStore integerForKey:@"current_proxy_config_preference"]);
bctbx_free(accounts);
const LinphoneAuthInfo *ai = linphone_account_find_auth_info(account);
LinphoneAccountCreator *account_creator = linphone_account_creator_new(
@ -1072,6 +1128,14 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
// retrieve linphone logs if available
char *filepath = linphone_core_compress_log_collection();
LinphoneCoreCbs *coreCbs = linphone_factory_create_core_cbs(linphone_factory_get());
linphone_core_cbs_set_log_collection_upload_state_changed(coreCbs, core_log_collection_upload_state_changed);
linphone_core_add_callbacks(LC, coreCbs);
linphone_core_upload_log_collection(LC);
if (filepath != NULL) {
NSString *filename = [[NSString stringWithUTF8String:filepath] componentsSeparatedByString:@"/"].lastObject;
NSString *mimeType = nil;
@ -1119,6 +1183,17 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
[self emailAttachments:attachments];
}
void core_log_collection_upload_state_changed(LinphoneCore *core, LinphoneCoreLogCollectionUploadState state , const char* info) {
LOGD(@"LinphoneCoreLogCollectionUploadStateDelivered core_log_collection_upload_state_changed %s", info);
if (state == LinphoneCoreLogCollectionUploadStateDelivered) {
LOGD(@"LinphoneCoreLogCollectionUploadStateDelivered %s", info);
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = [NSString stringWithUTF8String: info];
}
}
- (void)sendEmailWithPrivacyAttachments {
NSMutableArray *attachments = [[NSMutableArray alloc] initWithCapacity:4];

Some files were not shown because too many files have changed in this diff Show more