Compare commits

..

246 commits

Author SHA1 Message Date
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
2681 changed files with 78381 additions and 54885 deletions

27
.gitignore vendored
View file

@ -1,8 +1,23 @@
Linphone.xcworkspace
Pods
Podfile.lock
xcuserdata/
Pods/
build-*
*.locuser
.DS_Store
liblinphone-sdk
liblinphone-iphone-sdk*.zip
xcuserdata/
Classes/LinphoneIOSVersion.h
Pods/
Podfile.lock
GoogleService-Info.plist
build
Linphone.xcodeproj/xcuserdata
test-reports
WORK
Makefile
OUTPUT
git-clang-format.diff
submodules/tunnel
submodules/binaries/dummy-*.a
linphone-iphone.ipa
TutorialHellowWorld/hello-world.xcodeproj/project.xcworkspace/
diff-format.patch
*.xcscmblueprint
liblinphone-iphone-sdk-*

View file

@ -1,92 +1,20 @@
# COMMENTED FOR NOW - TODO : ENABLE CALLUI TESTS IN THE CI
# USE ONLY THE release/5.1 VERSION OF THIS FILE FOR NOW
#
#
#
#variables:
# workspace: linphone.xcworkspace
# scheme: linphone
# destination: name=iPhone 13 Pro
# testResult_path: derivedData/Logs/Test
#stages:
# - Build
# - UITests
#before_script:
# - pod install
# - 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
#Compile & Build:
# stage: Build
# tags: ["macmini-m1-xcode13"]
# before_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
# - xcrun simctl shutdown "$destination" && xcrun simctl erase "$destination"
# script:
# - xcodebuild -workspace $workspace -scheme $scheme -UseModernBuildSystem=YES -destination "$destination" -derivedDataPath derivedData
# after_script: []
#
# stage: build
# 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'
# artifacts:
# paths:
# - derivedData/Build
# when: always
# expire_in: 2 hour
#after_script:
# - ${TRAINER_EXE} -p $testResult_path/*.xcresult -o $testResult_path/
# - ${XCPARSE_EXE} attachments $testResult_path/*.xcresult results --uti public.image
# - mv $testResult_path/*.xcresult results && mv derivedData/logs.txt results
#Call Views:
# stage: UITests
# tags: ["macmini-m1-xcode13"]
# dependencies: ["Compile & Build"]
# script:
# - xcodebuild test -workspace $workspace -scheme $scheme -sdk iphonesimulator -destination "$destination" -UseModernBuildSystem=YES -testPlan Default -derivedDataPath derivedData | tee derivedData/logs.txt
# artifacts:
# paths:
# - results/*
# when: always
# reports:
# junit:
# - $testResult_path/*.xml
# expire_in: 4 week
variables:
archive_scheme: Linphone
archive_path: Linphone.xcarchive
export_path: Linphone-adhoc-ipa
export_options_plist: Linphone-adhoc.plist
archive_scheme: linphone
archive_path: linphone.xcarchive
export_path: linphone-adhoc-ipa
export_options_plist: linphone-adhoc.plist
job-ios:
stage: build
tags: [ "macos-xcode15" ]
allow_failure: true
tags: [ "macos-xcode13" ]
script:
# - pod install --repo-update
- exit 1
# - 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'
- 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'
artifacts:
@ -96,4 +24,3 @@ job-ios:
when: always
expire_in: 1 week

0
.gitmodules vendored Normal file
View file

View file

@ -1,32 +0,0 @@
disabled_rules:
- trailing_whitespace
opt_in_rules:
- empty_count
- empty_string
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
line_length:
warning: 150
error: 200
ignores_function_declarations: true
ignores_comments: true
ignores_urls: true
function_body_length:
warning: 300
error: 500
function_parameter_count:
warning: 6
error: 8
type_body_length:
warning: 300
error: 500
file_length:
warning: 1000
error: 1500
ignore_comment_only_lines: true
cyclomatic_complexity:
warning: 15
error: 25
reporter: "xcode"

28
.travis.yml Normal file
View file

@ -0,0 +1,28 @@
language: objective-c
osx_image: xcode7.2
env:
global:
- secure: "JPPcWdmNIJiR3YcIwe0LRYce6qDdsiagO+eKKAp7eVk/wD9UHbz96Ms2FFkXxPhRJB1PA6Pf8FpAzIL2YRiJL9jRtKHSvtdF1cSto+57XyBkCsw7PkMVUIxp7fg6Wiwn3H3tucF8jisIkv/Pn7R+9EqePkZSqqu3+ig5AX9ApQ4="
- KIF_SCREENSHOTS=$PWD/Screens
before_install:
- brew update 1>/dev/null
- brew install doxygen nasm yasm optipng imagemagick intltool ninja antlr cmake
- wget --no-check-certificate https://raw.githubusercontent.com/FFmpeg/gas-preprocessor/master/gas-preprocessor.pl
- chmod +x gas-preprocessor.pl
- sudo mv gas-preprocessor.pl /usr/local/bin
- sudo ln -s /usr/local/bin/glibtoolize /usr/local/bin/libtoolize
- git submodule update --init --recursive
install:
- ./prepare.py -d x86_64 -G Ninja
- make -j4 -s
- mkdir -p $KIF_SCREENSHOTS
script:
- xctool -project linphone.xcodeproj -scheme linphone -sdk iphonesimulator -destination name='iPhone 6' build 1>/dev/null
- xctool -project linphone.xcodeproj -scheme linphone -sdk iphonesimulator -destination name='iPhone 6' test
after_script:
- ./Tools/imgur_upload.sh

309
.tx/config Normal file
View file

@ -0,0 +1,309 @@
[main]
host = https://www.transifex.com
minimum_perc = 1
[linphone-ios.localizablestrings]
source_lang = en
file_filter = Resources/<lang>.lproj/Localizable.strings
source_file = Resources/en.lproj/Localizable.strings
type = STRINGS
[linphone-ios.aboutviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/AboutView.strings
source_file = Classes/Base.lproj/AboutView.strings
type = STRINGS
[linphone-ios.assistantviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/AssistantView.strings
source_file = Classes/Base.lproj/AssistantView.strings
type = STRINGS
[linphone-ios.assistantviewscreensstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/AssistantViewScreens.strings
source_file = Classes/Base.lproj/AssistantViewScreens.strings
type = STRINGS
[linphone-ios.callincomingviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/CallIncomingView.strings
source_file = Classes/Base.lproj/CallIncomingView.strings
type = STRINGS
[linphone-ios.calloutgoingviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/CallOutgoingView.strings
source_file = Classes/Base.lproj/CallOutgoingView.strings
type = STRINGS
[linphone-ios.callviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/CallView.strings
source_file = Classes/Base.lproj/CallView.strings
type = STRINGS
[linphone-ios.callviewipadstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/CallView~ipad.strings
source_file = Classes/Base.lproj/CallView~ipad.strings
type = STRINGS
[linphone-ios.chatconversationcreateviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ChatConversationCreateView.strings
source_file = Classes/Base.lproj/ChatConversationCreateView.strings
type = STRINGS
[linphone-ios.chatconversationviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ChatConversationView.strings
source_file = Classes/Base.lproj/ChatConversationView.strings
type = STRINGS
[linphone-ios.chatslistviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ChatsListView.strings
source_file = Classes/Base.lproj/ChatsListView.strings
type = STRINGS
[linphone-ios.contactdetailsviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ContactDetailsView.strings
source_file = Classes/Base.lproj/ContactDetailsView.strings
type = STRINGS
[linphone-ios.contactslistviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ContactsListView.strings
source_file = Classes/Base.lproj/ContactsListView.strings
type = STRINGS
[linphone-ios.dialerviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/DialerView.strings
source_file = Classes/Base.lproj/DialerView.strings
type = STRINGS
[linphone-ios.dialerviewipadstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/DialerView~ipad.strings
source_file = Classes/Base.lproj/DialerView~ipad.strings
type = STRINGS
[linphone-ios.firstloginviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/FirstLoginView.strings
source_file = Classes/Base.lproj/FirstLoginView.strings
type = STRINGS
[linphone-ios.historydetailsviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/HistoryDetailsView.strings
source_file = Classes/Base.lproj/HistoryDetailsView.strings
type = STRINGS
[linphone-ios.historylistviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/HistoryListView.strings
source_file = Classes/Base.lproj/HistoryListView.strings
type = STRINGS
[linphone-ios.imageviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ImageView.strings
source_file = Classes/Base.lproj/ImageView.strings
type = STRINGS
[linphone-ios.settingsviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/SettingsView.strings
source_file = Classes/Base.lproj/SettingsView.strings
type = STRINGS
[linphone-ios.sidemenuviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/SideMenuView.strings
source_file = Classes/Base.lproj/SideMenuView.strings
type = STRINGS
[linphone-ios.sidemenuviewipadstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/SideMenuView~ipad.strings
source_file = Classes/Base.lproj/SideMenuView~ipad.strings
type = STRINGS
[linphone-ios.statusbarviewstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/StatusBarView.strings
source_file = Classes/LinphoneUI/Base.lproj/StatusBarView.strings
type = STRINGS
[linphone-ios.tabbarviewstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/TabBarView.strings
source_file = Classes/LinphoneUI/Base.lproj/TabBarView.strings
type = STRINGS
[linphone-ios.uicallconferencecellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UICallConferenceCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UICallConferenceCell.strings
type = STRINGS
[linphone-ios.uicallpausedcellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UICallPausedCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UICallPausedCell.strings
type = STRINGS
[linphone-ios.uichatbubblephotocellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatBubblePhotoCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings
type = STRINGS
[linphone-ios.uichatbubbletextcellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatBubbleTextCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.strings
type = STRINGS
[linphone-ios.uichatcellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatCell.strings
type = STRINGS
[linphone-ios.uichatcreatecellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatCreateCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatCreateCell.strings
type = STRINGS
[linphone-ios.uiconfirmationdialogstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIConfirmationDialog.strings
source_file = Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.strings
type = STRINGS
[linphone-ios.uicontactcellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIContactCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIContactCell.strings
type = STRINGS
[linphone-ios.uicontactdetailscellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIContactDetailsCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.strings
type = STRINGS
[linphone-ios.uihistorycellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIHistoryCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIHistoryCell.strings
type = STRINGS
[linphone-ios.inappsettingsaccountstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Account.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Account.strings
type = STRINGS
[linphone-ios.inappsettingsadvancedstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Advanced.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Advanced.strings
type = STRINGS
[linphone-ios.inappsettingsaudiostrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Audio.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Audio.strings
type = STRINGS
[linphone-ios.inappsettingscallstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Call.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Call.strings
type = STRINGS
[linphone-ios.inappsettingsnetworkstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Network.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Network.strings
type = STRINGS
[linphone-ios.inappsettingsrootstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Root.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Root.strings
type = STRINGS
[linphone-ios.inappsettingstunnelstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Tunnel.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Tunnel.strings
type = STRINGS
[linphone-ios.inappsettingsvideostrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Video.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Video.strings
type = STRINGS
[linphone-ios.shopviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ShopView.strings
source_file = Classes/en.lproj/ShopView.strings
type = STRINGS
[linphone-ios.assistantlinkviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/AssistantLinkView.strings
source_file = Classes/Base.lproj/AssistantLinkView.strings
type = STRINGS
[linphone-ios.countrylistviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/CountryListView.strings
source_file = Classes/Base.lproj/CountryListView.strings
type = STRINGS
[linphone-ios.inappsettingschatstrings]
source_lang = en
file_filter = Settings/InAppSettings.bundle/<lang>.lproj/Chat.strings
source_file = Settings/InAppSettings.bundle/en.lproj/Chat.strings
type = STRINGS
[linphone-ios.uichatconversationinfotableviewcellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatConversationInfoTableViewCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatConversationInfoTableViewCell.strings
type = STRINGS
[linphone-ios.uichatconversationimdntableviewcellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatConversationImdnTableViewCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatConversationImdnTableViewCell.strings
type = STRINGS
[linphone-ios.uichatcreatecollectionviewcellstrings]
source_lang = en
file_filter = Classes/LinphoneUI/<lang>.lproj/UIChatCreateCollectionViewCell.strings
source_file = Classes/LinphoneUI/Base.lproj/UIChatCreateCollectionViewCell.strings
type = STRINGS
[linphone-ios.chatconversationinfoviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ChatConversationInfoView.strings
source_file = Classes/Base.lproj/ChatConversationInfoView.strings
type = STRINGS
[linphone-ios.chatconversationimdnviewstrings]
source_lang = en
file_filter = Classes/<lang>.lproj/ChatConversationImdnView.strings
source_file = Classes/Base.lproj/ChatConversationImdnView.strings
type = STRINGS

View file

@ -10,50 +10,6 @@ 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.2.0] - 2023-28-12
### Added
- Added extra Czech and Japanese translations
### Changed
- Update linphone SDK to 5.3.4
### Fixed
- Re-enabled the G729 audio codec
## [5.2.0] - 2023-21-12
### Added
- Chat messages emoji "reactions"
- Hardware video codecs (H264, H265) are now used in priority when possible (SDK)
### Changed
- Minimum iOS version is now 13
- Update linphone SDK to 5.3.1
### Fixed
- Several crashes in chat conversation when receiving files
- Various UI fixes in conference views
- Fix crash upon refreshing register
## [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

38
Classes/AboutView.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
@interface AboutView : TPMultiLayoutViewController <UICompositeViewDelegate>
@property(weak, nonatomic) IBOutlet UILabel *nameLabel;
@property(weak, nonatomic) IBOutlet UILabel *descriptionLabel;
@property(weak, nonatomic) IBOutlet UILabel *appVersionLabel;
@property(weak, nonatomic) IBOutlet UILabel *libVersionLabel;
@property(weak, nonatomic) IBOutlet UILabel *licenceLabel;
@property(weak, nonatomic) IBOutlet UILabel *translateLabel;
@property(weak, nonatomic) IBOutlet UILabel *policyLabel;
- (IBAction)onLinkTap:(id)sender;
- (IBAction)onLicenceTap;
- (IBAction)onPolicyTap;
- (IBAction)onDialerBackClick:(id)sender;
@end

110
Classes/AboutView.m Normal file
View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "PhoneMainView.h"
#import "LinphoneManager.h"
#import "LinphoneIOSVersion.h"
@implementation AboutView
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:nil
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:YES
fragmentWith:nil];
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
return self.class.compositeViewDescription;
}
#pragma mark - ViewController Functions
- (void)viewDidLoad {
[super viewDidLoad];
NSString *name = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
_nameLabel.text = name;
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
NSString *curVersion = [NSString stringWithFormat:@"version %@",[infoDict objectForKey:@"CFBundleShortVersionString"]];
_appVersionLabel.text = [NSString stringWithFormat:@"%@ iOS %@", name, curVersion];
_libVersionLabel.text = [NSString stringWithFormat:@"%@ SDK %s", name, LINPHONE_SDK_VERSION];
_translateLabel.text = [NSString stringWithString:NSLocalizedString(@"Help us translate Linphone", nil)];
UITapGestureRecognizer *tapGestureRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLicenceTap)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[_licenceLabel addGestureRecognizer:tapGestureRecognizer];
_licenceLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGestureRecognizerTranslate =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTranslateTap)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[_translateLabel addGestureRecognizer:tapGestureRecognizerTranslate];
_translateLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGestureRecognizerPolicy =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onPolicyTap)];
tapGestureRecognizerPolicy.numberOfTapsRequired = 1;
[_policyLabel addGestureRecognizer:tapGestureRecognizerPolicy];
_policyLabel.userInteractionEnabled = YES;
}
#pragma mark - Action Functions
- (IBAction)onLinkTap:(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);
}
}
- (IBAction)onPolicyTap {
NSString *url = @"https://www.linphone.org/privacy-policy";
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
}
}
- (IBAction)onLicenceTap {
NSString *url = @"https://www.gnu.org/licenses/gpl-3.0.html";
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
}
}
- (IBAction)onTranslateTap {
NSString *url = @"https://weblate.linphone.org/projects/linphone-iphone";
if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) {
LOGE(@"Failed to open %@, invalid URL", url);
}
}
- (IBAction)onDialerBackClick:(id)sender {
[PhoneMainView.instance popCurrentView];
}
@end

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "PhoneMainView.h"
#import <UIKit/UIKit.h>
#import "TPKeyboardAvoidingScrollView.h"
@interface AssistantLinkView : UIViewController <UITextFieldDelegate, UICompositeViewDelegate>
@property(weak, nonatomic) IBOutlet TPKeyboardAvoidingScrollView *linkAccountView;
@property(weak, nonatomic) IBOutlet UIView *activateSMSView;
@property(weak, nonatomic) IBOutlet UIButton *countryButton;
@property(weak, nonatomic) IBOutlet UITextField *countryCodeField;
@property(weak, nonatomic) IBOutlet UITextField *activationCodeField;
@property (weak, nonatomic) IBOutlet UIRoundBorderedButton *maybeLaterButton;
@property(weak, nonatomic) IBOutlet UIRoundBorderedButton *linkAccountButton;
@property(weak, nonatomic) IBOutlet UIRoundBorderedButton *checkValidationButton;
@property(weak, nonatomic) IBOutlet UIView *waitView;
@property(weak, nonatomic) IBOutlet UITextField *phoneField;
@property (weak, nonatomic) IBOutlet UILabel *linkSMSText;
@property BOOL firstTime;
- (IBAction)onLinkAccount:(id)sender;
- (IBAction)onCheckValidationButton:(id)sender;
- (IBAction)onCountryClick:(id)sender;
- (IBAction)onDialerClick:(id)sender;
- (IBAction)onPhoneNumberDisclosureClick:(id)sender;
- (IBAction)onMaybeLater:(id)sender;
@end

343
Classes/AssistantLinkView.m Normal file
View file

@ -0,0 +1,343 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import "AssistantLinkView.h"
#import "UITextField+DoneButton.h"
#import "UIAssistantTextField.h"
@implementation AssistantLinkView {
LinphoneAccountCreator *account_creator;
}
- (void)viewDidLoad {
[super viewDidLoad];
// every UITextField subviews with phone keyboard must be tweaked to have a done button
[self addDoneButtonRecursivelyInView:self.view];
self.phoneField.delegate = self; self.firstTime = TRUE;
}
- (void)addDoneButtonRecursivelyInView:(UIView *)subview {
for (UIView *child in [subview subviews]) {
if ([child isKindOfClass:UITextField.class]) {
UITextField *tf = (UITextField *)child;
if (tf.keyboardType == UIKeyboardTypePhonePad || tf.keyboardType == UIKeyboardTypeNumberPad) {
[tf addDoneButton];
}
}
[self addDoneButtonRecursivelyInView:child];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
_linkAccountView.hidden = _activateSMSView.userInteractionEnabled = NO;
_activateSMSView.hidden = _linkAccountView.userInteractionEnabled = YES;
[self fitScrollContentSize];
if (!account_creator) {
account_creator = linphone_account_creator_new(
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_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);
LinphoneAccount *acc = linphone_core_get_default_account(LC);
LinphoneAccountParams const *accParams = (acc) ? linphone_account_get_params(acc) : NULL;
if (acc &&
strcmp([LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"
withDefault:@"sip.linphone.org"]
.UTF8String,
linphone_account_params_get_domain(accParams)) == 0) {
linphone_account_creator_set_username(
account_creator, linphone_address_get_username(linphone_account_params_get_identity_address(accParams)));
const LinphoneAuthInfo *info = linphone_account_find_auth_info(acc);
if (info) {
if (linphone_auth_info_get_passwd(info))
linphone_account_creator_set_password(account_creator, linphone_auth_info_get_passwd(info));
else
linphone_account_creator_set_ha1(account_creator, linphone_auth_info_get_ha1(info));
}
linphone_account_creator_set_domain(account_creator, linphone_account_params_get_domain(accParams));
} else {
LOGW(@"Default proxy is NOT a sip.linphone.org, aborting");
[PhoneMainView.instance popToView:DialerView.compositeViewDescription];
}
CTTelephonyNetworkInfo *networkInfo = [CTTelephonyNetworkInfo new];
CTCarrier *carrier = networkInfo.subscriberCellularProvider;
NSDictionary *country = [CountryListView countryWithIso:carrier.isoCountryCode];
if (!country) {
// fetch phone locale
for (NSString *lang in [NSLocale preferredLanguages]) {
NSUInteger idx = [lang rangeOfString:@"-"].location;
idx = (idx == NSNotFound) ? idx = 0 : idx + 1;
if ((country = [CountryListView countryWithIso:[lang substringFromIndex:idx]]) != nil)
break;
}
}
if (country && self.firstTime) {
[self didSelectCountry:country];
}
}
- (void)viewDidDisappear:(BOOL)animated {
if (account_creator) {
linphone_account_creator_unref(account_creator);
}
account_creator = NULL;
[super viewDidDisappear:animated];
}
- (void)fitScrollContentSize {
// make view scrollable only if next button is too away
CGRect viewframe = _linkAccountView.frame;
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
viewframe.size.height += 60;
}
[_linkAccountView setContentSize:viewframe.size];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self fitScrollContentSize];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:nil
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:NO
fragmentWith:nil];
compositeDescription.darkBackground = true;
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
return self.class.compositeViewDescription;
}
#pragma mark - popup
- (void)showErrorPopup:(const char *)err {
if (strcmp(err, "ERROR_KEY_DOESNT_MATCH") == 0) {
UIAlertController *errView =
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"Account configuration issue", nil)
message:[AssistantView StringForXMLRPCError:err]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
self.linkAccountView.hidden = NO;
self.linkAccountView.userInteractionEnabled = YES;
self.activateSMSView.userInteractionEnabled = NO;
self.activateSMSView.hidden = YES;
self.activationCodeField.text = @"";
}];
[errView addAction:defaultAction];
[self presentViewController:errView animated:YES completion:nil];
} else {
UIAlertController *errView =
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"Account configuration issue", nil)
message:[AssistantView StringForXMLRPCError:err]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
}];
[errView addAction:defaultAction];
[self presentViewController:errView animated:YES completion:nil];
}
}
#pragma mark - cbs
void assistant_link_phone_number_with_account(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status,
const char *resp) {
AssistantLinkView *thiz = (__bridge AssistantLinkView *)(linphone_account_creator_get_user_data(creator));
thiz.waitView.hidden = YES;
if (status == LinphoneAccountCreatorStatusRequestOk) {
thiz.linkAccountView.hidden = thiz.activateSMSView.userInteractionEnabled = YES;
NSString* phoneNumber = [NSString stringWithUTF8String:linphone_account_creator_get_phone_number(creator)];
thiz.linkSMSText.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.activateSMSView.hidden = thiz.linkAccountView.userInteractionEnabled = NO;
} else {
if (strcmp(resp, "Missing required parameters") == 0) {
[thiz showErrorPopup:"ERROR_NO_PHONE_NUMBER"];
} else {
[thiz showErrorPopup:resp];
}
}
}
void assistant_activate_phone_number_link(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status,
const char *resp) {
AssistantLinkView *thiz = (__bridge AssistantLinkView *)(linphone_account_creator_get_user_data(creator));
thiz.waitView.hidden = YES;
if (status == LinphoneAccountCreatorStatusAccountActivated) {
[LinphoneManager.instance lpConfigSetInt:0 forKey:@"must_link_account_time"];
// save country code prefix if none is already entered
LinphoneAccount *acc = linphone_core_get_default_account(LC);
LinphoneAccountParams const *accParams = linphone_account_get_params(acc);
if (linphone_account_params_get_international_prefix(accParams) == NULL) {
const char *prefix = thiz.countryCodeField.text.UTF8String;
LinphoneAccountParams * newPrefixAccountParams = linphone_account_params_clone(accParams);
linphone_account_params_set_international_prefix(newPrefixAccountParams, prefix[0] == '+' ? &prefix[1] : prefix);
linphone_account_set_params(acc, newPrefixAccountParams);
linphone_account_params_unref(newPrefixAccountParams);
}
[PhoneMainView.instance popToView:DialerView.compositeViewDescription];
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneAddressBookUpdate object:NULL];
[LinphoneManager.instance.fastAddressBook fetchContactsInBackGroundThread];
} else {
[thiz showErrorPopup:resp];
}
}
#pragma mark - other
- (void)updateCountry:(BOOL)force {
NSDictionary *c = [CountryListView countryWithCountryCode:_countryCodeField.text];
if (c || force) {
[_countryButton setTitle:c ? [c objectForKey:@"name"] : NSLocalizedString(@"Unknown country code", nil)
forState:UIControlStateNormal];
}
if ([[_countryButton currentTitle] isEqualToString:NSLocalizedString(@"Unknown country code", nil)]) {
_countryCodeField.layer.borderWidth = .8;
_countryCodeField.layer.cornerRadius = 4.f;
_countryCodeField.layer.borderColor = [[UIColor redColor] CGColor];
self.linkAccountButton.enabled = FALSE;
} else {
_countryCodeField.layer.borderColor = [[UIColor clearColor] CGColor];
if (_phoneField.layer.borderColor != [[UIColor redColor] CGColor]) {
self.linkAccountButton.enabled = TRUE;
}
}
}
- (IBAction)onCountryCodeFieldChange:(id)sender {
[self updateCountry:NO];
}
- (IBAction)onCountryCodeFieldEnd:(id)sender {
[self updateCountry:YES];
}
- (IBAction)onCountryClick:(id)sender {
self.firstTime = FALSE;
CountryListView *view = VIEW(CountryListView);
[view setDelegate:(id)self];
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
- (IBAction)onLinkAccount:(id)sender {
_waitView.hidden = NO;
NSString *newStr = [_countryCodeField.text substringWithRange:NSMakeRange(1, [_countryCodeField.text length]-1)];
linphone_account_creator_set_phone_number(account_creator, _phoneField.text.UTF8String,
newStr.UTF8String);
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
linphone_account_creator_set_language(account_creator, [[language substringToIndex:2] UTF8String]);
linphone_account_creator_link_account(account_creator);
}
- (IBAction)onCheckValidationButton:(id)sender {
_waitView.hidden = NO;
linphone_account_creator_set_activation_code(account_creator, _activationCodeField.text.UTF8String);
linphone_account_creator_activate_alias(account_creator);
}
- (IBAction)onDialerClick:(id)sender {
[PhoneMainView.instance popCurrentView];
}
- (IBAction)onPhoneNumberDisclosureClick:(id)sender {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"What will my phone number be used for?", nil)
message:NSLocalizedString(@"Your friends will find your more easily if you link your account to your "
@"phone number. \n\nYou will see in your address book who is using "
@"Linphone and your friends will know that they can reach you on Linphone "
@"as well. \n\nYou can use your phone number with only one Linphone "
@"account. If you had already linked your number to an other account but "
@"you prefer to use this one, simply link it now and your number will "
@"automatically be moved to this account.",
nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[self presentViewController:errView animated:YES completion:nil];
}
- (IBAction)onMaybeLater:(id)sender {
[PhoneMainView.instance popToView:DialerView.compositeViewDescription];
}
#pragma mark - select country delegate
- (void)didSelectCountry:(NSDictionary *)country {
[_countryButton setTitle:[country objectForKey:@"name"] forState:UIControlStateNormal];
_countryCodeField.text = [country objectForKey:@"code"];
}
#pragma mark - UITextFieldDelegate Functions
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//remove the + from the country code to avoir error when checking its validity
NSString *newStr = [_countryCodeField.text substringWithRange:NSMakeRange(1, [_countryCodeField.text length]-1)];
LinphoneAccountCreatorStatus status = linphone_account_creator_set_phone_number(account_creator, [_phoneField.text UTF8String], [newStr UTF8String]);
if (status == LinphoneAccountCreatorPhoneNumberStatusTooLong ||
status == LinphoneAccountCreatorPhoneNumberStatusTooShort) {
self.phoneField.layer.borderWidth = .8;
self.phoneField.layer.cornerRadius = 4.f;
self.phoneField.layer.borderColor = [[UIColor redColor] CGColor];
self.linkAccountButton.enabled = FALSE;
} else {
self.phoneField.layer.borderColor = [[UIColor clearColor] CGColor];
if (_countryCodeField.layer.borderColor != [[UIColor redColor] CGColor]){
self.linkAccountButton.enabled = TRUE;
}
}
return YES;
}
@end

116
Classes/AssistantView.h Normal file
View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
#import "TPKeyboardAvoidingScrollView.h"
#import "PhoneMainView.h"
@interface AssistantView : UIViewController <UITextFieldDelegate, UICompositeViewDelegate, UITextViewDelegate> {
@private
LinphoneAccountCreator *account_creator;
UIView *currentView;
UIView *nextView;
NSMutableArray *historyViews;
LinphoneAccount *new_account;
size_t number_of_accounts_before;
BOOL mustRestoreView;
long phone_number_length;
}
@property(nonatomic) UICompositeViewDescription *outgoingView;
@property (weak, nonatomic) IBOutlet UILabel *subtileLabel_useLinphoneAccount;
@property(nonatomic, strong) IBOutlet TPKeyboardAvoidingScrollView *contentView;
@property(nonatomic, strong) IBOutlet UIView *waitView;
@property(nonatomic, strong) IBOutlet UIButton *backButton;
@property (weak, nonatomic) IBOutlet UIButton *infoLoginButton;
@property (weak, nonatomic) IBOutlet UIRoundBorderedButton *linphoneLoginButton;
@property(nonatomic, strong) IBOutlet UIView *welcomeView;
@property(nonatomic, strong) IBOutlet UIView *createAccountView;
@property(nonatomic, strong) IBOutlet UIView *createAccountActivateEmailView;
@property(nonatomic, strong) IBOutlet UIView *linphoneLoginView;
@property(nonatomic, strong) IBOutlet UIView *loginView;
@property(nonatomic, strong) IBOutlet UIView *linphoneSpecificFeatureWarningView;
@property(nonatomic, strong) IBOutlet UIView *remoteProvisioningLoginView;
@property(strong, nonatomic) IBOutlet UIView *remoteProvisioningView;
@property (strong, nonatomic) IBOutlet UIView *createAccountActivateSMSView;
@property (strong, nonatomic) IBOutlet UIView *qrCodeView;
@property(nonatomic, strong) IBOutlet UIImageView *welcomeLogoImage;
@property(nonatomic, strong) IBOutlet UIButton *gotoCreateAccountButton;
@property(nonatomic, strong) IBOutlet UIButton *gotoLinphoneLoginButton;
@property(nonatomic, strong) IBOutlet UIButton *gotoLinphoneSpecificFeatureWarningButton;
@property(nonatomic, strong) IBOutlet UIButton *gotoLoginButton;
@property(nonatomic, strong) IBOutlet UIButton *gotoRemoteProvisioningButton;
@property (weak, nonatomic) IBOutlet UILabel *phoneLabel;
@property (weak, nonatomic) IBOutlet UILabel *phoneTitle;
@property (weak, nonatomic) IBOutlet UILabel *activationTitle;
@property (weak, nonatomic) IBOutlet UILabel *activationEmailText;
@property (weak, nonatomic) IBOutlet UILabel *activationSMSText;
@property (weak, nonatomic) IBOutlet UILabel *linphoneSpecificFeatureWarningText;
@property (weak, nonatomic) IBOutlet UILabel *linphoneSpecificFeatureWarningContactLink;
@property (weak, nonatomic) IBOutlet UILabel *accountLabel;
@property (weak, nonatomic) IBOutlet UIButton *qrCodeButton;
@property (weak, nonatomic) IBOutlet UIButton *downloadButton;
@property (weak, nonatomic) IBOutlet UITextField *urlLabel;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *createAccountNextButtonPositionConstraint;
@property (weak, nonatomic) IBOutlet UIButton *acceptButton;
- (IBAction)onAcceptTermsClick:(id)sender;
@property (weak, nonatomic) IBOutlet UITextView *acceptText;
+ (NSString *)StringForXMLRPCError:(const char *)err;
+ (NSString *)errorForLinphoneAccountCreatorPhoneNumberStatus:(LinphoneAccountCreatorPhoneNumberStatus)status;
+ (NSString *)errorForLinphoneAccountCreatorUsernameStatus:(LinphoneAccountCreatorUsernameStatus)status;
+ (NSString *)errorForLinphoneAccountCreatorEmailStatus:(LinphoneAccountCreatorEmailStatus)status;
+ (NSString *)errorForLinphoneAccountCreatorPasswordStatus:(LinphoneAccountCreatorPasswordStatus)status;
+ (NSString *)errorForLinphoneAccountCreatorActivationCodeStatus:(LinphoneAccountCreatorActivationCodeStatus)status;
+ (NSString *)errorForLinphoneAccountCreatorStatus:(LinphoneAccountCreatorStatus)status;
+ (NSString *)errorForLinphoneAccountCreatorDomainStatus:(LinphoneAccountCreatorDomainStatus)status;
- (void)reset;
- (void)fillDefaultValues;
- (IBAction)onBackClick:(id)sender;
- (IBAction)onGotoCreateAccountClick:(id)sender;
- (IBAction)onGotoLinphoneLoginClick:(id)sender;
- (IBAction)onGotoLoginClick:(id)sender;
- (IBAction)onGotoRemoteProvisioningClick:(id)sender;
- (IBAction)onCreateAccountClick:(id)sender;
- (IBAction)onCreateAccountActivationClick:(id)sender;
- (IBAction)onLinphoneLoginClick:(id)sender;
- (IBAction)onLoginClick:(id)sender;
- (IBAction)onRemoteProvisioningLoginClick:(id)sender;
- (IBAction)onRemoteProvisioningDownloadClick:(id)sender;
- (IBAction)onLaunchQRCodeView:(id)sender;
- (IBAction)onCreateAccountCheckActivatedClick:(id)sender;
- (IBAction)onLinkAccountClick:(id)sender;
- (IBAction)onFormSwitchToggle:(id)sender;
- (IBAction)onCountryCodeClick:(id)sender;
- (IBAction)onCountryCodeFieldChange:(id)sender;
- (IBAction)onCountryCodeFieldEnd:(id)sender;
- (IBAction)onPhoneNumberDisclosureClick:(id)sender;
@end

1830
Classes/AssistantView.m Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,300 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<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="AboutView">
<connections>
<outlet property="appVersionLabel" destination="gLk-Bc-zvx" id="81L-RE-1ad"/>
<outlet property="landscapeView" destination="sVO-4a-t1s" id="9ye-NV-onQ"/>
<outlet property="libVersionLabel" destination="ZYk-v1-CYZ" id="E4g-U8-zyp"/>
<outlet property="licenceLabel" destination="gVK-Xc-S59" id="XPV-ct-oGP"/>
<outlet property="policyLabel" destination="5Nl-Fs-ggi" id="xXc-PS-Eda"/>
<outlet property="portraitView" destination="HJH-1o-RXN" id="Hoa-uk-q9s"/>
<outlet property="translateLabel" destination="7nZ-2Q-Rxv" id="ZKn-bK-Ezf"/>
<outlet property="view" destination="HJH-1o-RXN" id="t5Y-ob-1WC"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="eP3-Qs-BZl" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HJH-1o-RXN">
<rect key="frame" x="0.0" y="66" width="414" height="830"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Whz-oo-Pwx" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" 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" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ETk-tB-ZNl" userLabel="dialerBackButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="106" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="PJX-d2-pSh"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="ABOUT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iNt-9d-7si" userLabel="titleLabel">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view clipsSubviews="YES" multipleTouchEnabled="YES" tag="6" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="er6-WR-NP1">
<rect key="frame" x="0.0" y="66" width="414" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_C.png" translatesAutoresizingMaskIntoConstraints="NO" id="fbO-x9-0Ue" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="414" height="262"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Linphone iOS 8.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gLk-Bc-zvx" userLabel="appVersionLabel">
<rect key="frame" x="-8" y="221" width="414" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Linphone Core 3.14.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZYk-v1-CYZ" userLabel="libVersionLabel">
<rect key="frame" x="-8" y="241" width="414" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1pe-zf-cQh" userLabel="siteURLLabel">
<rect key="frame" x="0.0" y="270" 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.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<connections>
<outletCollection property="gestureRecognizers" destination="l7c-wq-pii" appends="YES" id="olo-CD-gM3"/>
</connections>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="5Nl-Fs-ggi" userLabel="policyLabel">
<rect key="frame" x="0.0" y="302" width="414" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Help us translate Linphone" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="7nZ-2Q-Rxv" userLabel="policyLabel">
<rect key="frame" x="0.0" y="398" width="414" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.9497097135" green="0.27055108550000001" blue="0.030769694600000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="splashscreen.png" translatesAutoresizingMaskIntoConstraints="NO" id="wSQ-YD-dIQ" userLabel="logoImage">
<rect key="frame" x="0.0" y="8" width="414" height="166"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" translatesAutoresizingMaskIntoConstraints="NO" id="siH-xH-Z5X" userLabel="descLabel">
<rect key="frame" x="88" y="179" width="239" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
<fragment content="The ">
<attributes>
<color key="NSColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
<fragment content="libre">
<attributes>
<color key="NSColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue-Italic"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
<fragment content=" SIP client">
<attributes>
<color key="NSColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="gVK-Xc-S59" userLabel="licenseLabel">
<rect key="frame" x="0.0" y="334" width="414" height="61"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<string key="text">GNU General Public License V3
© 2010-2020 Belledonne Communications</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="376" y="286.05697151424289"/>
</view>
<view contentMode="scaleToFill" id="FcM-rg-Qrt" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sVO-4a-t1s">
<rect key="frame" x="0.0" y="66" width="414" height="719"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OGe-ZS-scH" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" 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="Vi5-Wh-iOm" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vX8-wO-ZEN" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="106" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="vfB-jG-YPr"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="ABOUT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wKp-iH-ojJ" userLabel="titleLabel">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<view clipsSubviews="YES" multipleTouchEnabled="YES" tag="6" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wvv-4f-Oa6">
<rect key="frame" x="0.0" y="66" width="414" height="243"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_C.png" translatesAutoresizingMaskIntoConstraints="NO" id="UBx-Gi-qTi" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="414" height="152"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" translatesAutoresizingMaskIntoConstraints="NO" id="ASG-VC-Riv" userLabel="descLabel">
<rect key="frame" x="197" y="35" width="160" height="45"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
<fragment content="The ">
<attributes>
<color key="NSColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
<fragment content="libre">
<attributes>
<color key="NSColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue-Italic"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
<fragment content=" SIP client">
<attributes>
<color key="NSColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" size="26" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Linphone iPhone 3.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oYk-ih-BBi" userLabel="appVersionLabel">
<rect key="frame" x="141" y="88" width="273" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jGU-DX-XcO" userLabel="siteURLLabel">
<rect key="frame" x="0.0" y="154" 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"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="nld-cR-eba" userLabel="policyLabel">
<rect key="frame" x="0.0" y="173" width="414" height="41"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Linphone Core 3.9.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="g2W-u5-yxg" userLabel="libVersionLabel">
<rect key="frame" x="141" y="117" width="273" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="splashscreen.png" translatesAutoresizingMaskIntoConstraints="NO" id="UhZ-5i-eU5" userLabel="logoImage">
<rect key="frame" x="7" y="0.0" width="157" height="152"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="GNU General Public License V3 © 2010-2020 Belledonne Communications" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="vqn-sI-DiC" userLabel="licenseLabel">
<rect key="frame" x="0.0" y="415" width="614" height="64"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="1393.5999999999999" y="223.08845577211397"/>
</view>
<tapGestureRecognizer id="l7c-wq-pii" userLabel="onLinkTap">
<connections>
<action selector="onLinkTap:" destination="-1" id="Ay5-Uz-RDo"/>
</connections>
</tapGestureRecognizer>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_C.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="splashscreen.png" width="852.79998779296875" height="617.5999755859375"/>
<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>

Binary file not shown.

View file

@ -0,0 +1,260 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AssistantLinkView">
<connections>
<outlet property="activateSMSView" destination="2Nl-QG-fTA" id="32Y-Z3-OYi"/>
<outlet property="activationCodeField" destination="PXL-cl-haZ" id="faz-N0-sjR"/>
<outlet property="checkValidationButton" destination="bIM-bh-Huy" id="yr2-9j-ejj"/>
<outlet property="countryButton" destination="rLT-uU-cJS" id="lNp-Qo-AKx"/>
<outlet property="countryCodeField" destination="DBr-NA-Ibx" id="cRz-xe-r5D"/>
<outlet property="linkAccountButton" destination="D25-6f-qRg" id="aid-PS-8mU"/>
<outlet property="linkAccountView" destination="ImD-Y4-3nC" id="231-q3-rGe"/>
<outlet property="linkSMSText" destination="Dvq-wa-3k8" id="4Ne-Ud-aA1"/>
<outlet property="maybeLaterButton" destination="bes-x4-C4l" id="l5a-ON-h9a"/>
<outlet property="phoneField" destination="cEN-WO-5qv" id="Ftl-EA-afz"/>
<outlet property="view" destination="FBm-gC-sIQ" id="Bhr-VA-MJs"/>
<outlet property="waitView" destination="J3A-Fb-Dpg" id="zbb-YB-ace"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="fhP-nP-aaU" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FBm-gC-sIQ">
<rect key="frame" x="0.0" y="66" width="375" height="601"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="c7I-Cv-d4R" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="367" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VlN-Em-1V6" userLabel="dialerBackButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerClick:" destination="-1" eventType="touchUpInside" id="WUU-Oh-Ofu"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="ASSISTANT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zrj-TX-1RP" userLabel="titleLabel">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view hidden="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ImD-Y4-3nC" userLabel="linkAccountView" customClass="TPKeyboardAvoidingScrollView">
<rect key="frame" x="0.0" y="66" width="375" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="LINK YOUR ACCOUNT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="0xQ-6c-cAc" userLabel="titleLabel">
<rect key="frame" x="38" y="0.0" width="299" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="24"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="Please confirm your country code and enter your phone number" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumFontSize="11" translatesAutoresizingMaskIntoConstraints="NO" id="RQz-tT-5vp" userLabel="subtitleLabel">
<rect key="frame" x="38" y="66" width="299" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" red="0.4266758859" green="0.42666310070000002" blue="0.42667034269999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="122" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="PHONE NUMBER" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="v2Q-jf-BdL" userLabel="phoneLabel">
<rect key="frame" x="38" y="131" width="299" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.4266758859" green="0.42666310070000002" blue="0.42667034269999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="150" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rLT-uU-cJS" userLabel="countryButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="38" y="153" width="299" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="Select your country">
<color key="titleColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
</state>
<state key="highlighted" title="Choose your country" backgroundImage="color_F.png"/>
<connections>
<action selector="onCountryClick:" destination="-1" eventType="touchUpInside" id="AUl-nx-xOA"/>
</connections>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="88g-7g-gGM" userLabel="phoneNumberView">
<rect key="frame" x="38" y="189" width="299" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" tag="109" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="+1" textAlignment="center" minimumFontSize="5" translatesAutoresizingMaskIntoConstraints="NO" id="DBr-NA-Ibx" userLabel="countryCodeField">
<rect key="frame" x="1" y="7" width="54" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" keyboardType="phonePad"/>
<connections>
<action selector="onCountryCodeFieldChange:" destination="-1" eventType="editingChanged" id="cot-au-ukn"/>
<action selector="onCountryCodeFieldEnd:" destination="-1" eventType="editingDidEnd" id="5v7-YR-eTh"/>
</connections>
</textField>
<textField opaque="NO" clipsSubviews="YES" tag="107" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="cEN-WO-5qv" userLabel="phoneField">
<rect key="frame" x="58" y="7" width="242" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Username"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="phonePad" returnKeyType="next"/>
</textField>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="0.0" maxX="299" maxY="0.0"/>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="infoDark" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9cd-3u-fU5" userLabel="infoButton">
<rect key="frame" x="300" y="127" width="22" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<connections>
<action selector="onPhoneNumberDisclosureClick:" destination="-1" eventType="touchUpInside" id="FEb-Xm-Pyx"/>
</connections>
</button>
<button opaque="NO" tag="130" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="D25-6f-qRg" userLabel="linkAccountButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="38" y="252" width="299" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Create account">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="LINK ACCOUNT">
<color key="titleColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
</state>
<state key="disabled">
<color key="titleColor" red="0.71885228160000003" green="0.71883076430000004" blue="0.71884298319999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_F.png"/>
<connections>
<action selector="onLinkAccount:" destination="-1" eventType="touchUpInside" id="wd4-6V-tMa"/>
</connections>
</button>
<button opaque="NO" tag="130" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bes-x4-C4l" userLabel="maybeLaterButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="38" y="312" width="299" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Finish configuration">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="MAYBE LATER">
<color key="titleColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
</state>
<state key="disabled">
<color key="titleColor" red="0.71885228160000003" green="0.71883076430000004" blue="0.71884298319999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_F.png"/>
<connections>
<action selector="onMaybeLater:" destination="-1" eventType="touchUpInside" id="IcP-2Y-18k"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Nl-QG-fTA" userLabel="activateSMSView">
<rect key="frame" x="0.0" y="66" width="375" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="LINK YOUR ACCOUNT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="5aj-17-dC2" userLabel="titleLabel">
<rect key="frame" x="38" y="0.0" width="303" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="24"/>
<color key="textColor" red="0.20521381499999999" green="0.20520767570000001" blue="0.2052111626" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="2/2" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="bU8-Tu-9O4" userLabel="subtitleLabel">
<rect key="frame" x="38" y="66" width="303" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.4266758859" green="0.42666310070000002" blue="0.42667034269999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="108" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Activation code" textAlignment="center" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="PXL-cl-haZ" userLabel="activationCodeField">
<rect key="frame" x="38" y="214" width="303" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="26"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numberPad" returnKeyType="done"/>
</textField>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="We have sent you a SMS with a validation code. To complete your phone number verification, please enter the 4 digit code below:" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="8" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Dvq-wa-3k8" userLabel="activateDescLabel">
<rect key="frame" x="38" y="103" width="303" height="96"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<button opaque="NO" tag="130" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bIM-bh-Huy" userLabel="checkValidationButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="38" y="252" width="299" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Finish configuration">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="LINK ACCOUNT">
<color key="titleColor" red="0.20521381499999999" green="0.20520767570000001" blue="0.2052111626" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled">
<color key="titleColor" red="0.71885228160000003" green="0.71883076430000004" blue="0.71884298319999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_F.png"/>
<connections>
<action selector="onCheckValidationButton:" destination="-1" eventType="touchUpInside" id="v0K-hd-CHi"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="J3A-Fb-Dpg" userLabel="waitView">
<rect key="frame" x="0.0" y="-33" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="mQl-pi-5rq" userLabel="activityIndicatorView">
<rect key="frame" x="179" y="322" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="376.80000000000001" y="286.50674662668666"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
</resources>
</document>

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,83 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AssistantView">
<connections>
<outlet property="backButton" destination="edC-CG-eZr" id="aXO-xT-kQ1"/>
<outlet property="contentView" destination="98" id="99"/>
<outlet property="view" destination="12" id="20"/>
<outlet property="waitView" destination="91" id="96"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="BrP-Xy-m1Y">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="12">
<rect key="frame" x="0.0" y="42" width="414" height="854"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vsu-Ew-BxE" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="ASSISTANT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1EG-3g-3uU" userLabel="titleLabel">
<rect key="frame" x="92" y="0.0" width="230" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="edC-CG-eZr" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<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"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="KeZ-8e-Ci2"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="7" contentMode="scaleToFill" fixedFrame="YES" bounces="NO" translatesAutoresizingMaskIntoConstraints="NO" id="98" userLabel="contentView" customClass="TPKeyboardAvoidingScrollView">
<rect key="frame" x="0.0" y="66" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</scrollView>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="91" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="414" height="854"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="90" userLabel="activityIndicatorView">
<rect key="frame" x="199" y="416" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="58.695652173913047" y="176.45089285714286"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
</resources>
</document>

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<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="21207"/>
<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="ChatConversationCreateView">
<connections>
<outlet property="allButton" destination="r3z-SM-lMq" id="DUC-gQ-gKu"/>
<outlet property="backButton" destination="fNt-yb-wsf" id="3Xj-Dv-LmO"/>
<outlet property="chiffreButton" destination="uUN-bl-g4c" id="w8f-8e-vBx"/>
<outlet property="chiffreImage" destination="jIQ-qM-GVG" id="mSL-Kf-21s"/>
<outlet property="chiffreOptionView" destination="9gK-1a-7Hl" id="gXA-hF-uGd"/>
<outlet property="collectionView" destination="KRQ-Fm-3cQ" id="otM-cN-lEg"/>
<outlet property="linphoneButton" destination="8lQ-fv-INK" id="zaP-UT-K4y"/>
<outlet property="nextButton" destination="rBc-dQ-eIj" id="QHB-Xp-PTA"/>
<outlet property="selectedButtonImage" destination="ibu-Ra-oZO" id="jvl-ay-cfh"/>
<outlet property="switchView" destination="d5Q-XR-FNz" id="Xeo-ZG-6cr"/>
<outlet property="tableController" destination="4" id="18"/>
<outlet property="topBar" destination="7" id="svd-IV-RZN"/>
<outlet property="view" destination="5" id="14"/>
<outlet property="voipTitle" destination="Cwe-p4-hji" id="NLX-Og-4HS"/>
<outlet property="waitView" destination="Ztm-hK-aBp" id="qYh-M5-heN"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tapGestureRecognizer id="jFh-hw-yg2" userLabel="chiffreClick">
<connections>
<action selector="onChiffreClick:" destination="-1" id="Hz6-Ey-gAh"/>
</connections>
</tapGestureRecognizer>
<view contentMode="scaleToFill" id="WKv-mw-S2B" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="0.0" y="42" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d5Q-XR-FNz" userLabel="switchView">
<rect key="frame" x="248" y="0.0" width="166" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="r3z-SM-lMq" userLabel="allButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="All contacts filter"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<inset key="titleEdgeInsets" minX="-38" minY="15" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="16" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" image="contacts_all_default.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contacts_all_disabled.png"/>
<state key="selected" image="contacts_all_selected.png">
<color key="titleColor" red="0.98766469960000003" green="0.27512490750000002" blue="0.029739789660000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAllClick:" destination="-1" eventType="touchUpInside" id="TG9-Df-iTU"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="ibu-Ra-oZO" userLabel="selectedButtonImage">
<rect key="frame" x="0.0" y="63" width="83" height="3"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8lQ-fv-INK" userLabel="sipButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="83" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Linphone contacts filter"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<state key="normal" image="contacts_sip_default.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contacts_sip_disabled.png"/>
<state key="selected" image="contacts_sip_selected.png">
<color key="titleColor" red="0.98766469960000003" green="0.27512490750000002" blue="0.029739789660000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onLinphoneClick:" destination="-1" eventType="touchUpInside" id="wNL-jl-TU6"/>
</connections>
</button>
</subviews>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fNt-yb-wsf" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="463-Qr-hJG"/>
</connections>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9gK-1a-7Hl" userLabel="chiffreOptionView">
<rect key="frame" x="72" y="0.0" width="150" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4Be-pr-fmB" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_toogle_icon_grey.png"/>
<state key="disabled" image="security_toogle_icon_grey.png"/>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dH1-Al-sJ7">
<rect key="frame" x="56" y="24" width="36" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="security_toogle_background_grey.png" translatesAutoresizingMaskIntoConstraints="NO" id="jIQ-qM-GVG" userLabel="chiffreImage">
<rect key="frame" x="0.0" y="0.0" width="36" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uUN-bl-g4c" userLabel="chiffreButton">
<rect key="frame" x="0.0" y="2" width="14" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_toogle_button.png"/>
<connections>
<action selector="onChiffreClick:" destination="-1" eventType="touchUpInside" id="ZyW-ow-b4Y"/>
</connections>
</button>
</subviews>
<connections>
<outletCollection property="gestureRecognizers" destination="jFh-hw-yg2" appends="YES" id="kX3-iI-ZpX"/>
</connections>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9Py-cO-YGv">
<rect key="frame" x="76" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_toogle_icon_green.png"/>
<state key="disabled" image="security_toogle_icon_green.png"/>
</button>
</subviews>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Cwe-p4-hji" userLabel="voipTitle">
<rect key="frame" x="82" y="0.0" width="249" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rBc-dQ-eIj" userLabel="nextButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="next_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="next_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onNextClick:" destination="-1" eventType="touchUpInside" id="yFF-js-mRx"/>
</connections>
</button>
</subviews>
<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="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="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"/>
<connections>
<outlet property="dataSource" destination="4" id="11"/>
<outlet property="delegate" destination="4" id="12"/>
</connections>
</tableView>
<searchBar contentMode="redraw" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Rd9-hK-nqR" userLabel="Contact address">
<rect key="frame" x="0.0" y="66" width="414" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no"/>
<connections>
<outlet property="delegate" destination="4" id="MJr-oP-Hib"/>
</connections>
</searchBar>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ztm-hK-aBp" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="nqH-qD-vgE" userLabel="activityIndicatorView">
<rect key="frame" x="199" y="380" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
</view>
<view hidden="YES" contentMode="scaleToFill" id="Vhn-Z4-Z4Q" userLabel="loadingView">
<rect key="frame" x="5" y="178" width="403" height="610"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Loading contacts..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="tQD-oL-wLO">
<rect key="frame" x="100" y="10" width="145" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="medium" id="xS4-I7-COE">
<rect key="frame" x="75" y="10" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="53.600000000000001" y="80.50974512743629"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="4" userLabel="Suggested addresses" customClass="ChatConversationCreateTableView">
<extendedEdge key="edgesForExtendedLayout"/>
<nil key="simulatedStatusBarMetrics"/>
<connections>
<outlet property="loadingView" destination="Vhn-Z4-Z4Q" id="FvB-Bn-31o"/>
<outlet property="searchBar" destination="Rd9-hK-nqR" id="rLn-7q-CwC"/>
<outlet property="view" destination="6" id="13"/>
<outlet property="waitView" destination="Ztm-hK-aBp" id="uSB-4b-n7e"/>
</connections>
<point key="canvasLocation" x="740.79999999999995" y="80.959520239880064"/>
</tableViewController>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="contacts_all_default.png" width="52" height="44"/>
<image name="contacts_all_disabled.png" width="52" height="44"/>
<image name="contacts_all_selected.png" width="52" height="44"/>
<image name="contacts_sip_default.png" width="39.5" height="39.5"/>
<image name="contacts_sip_disabled.png" width="38" height="30"/>
<image name="contacts_sip_selected.png" width="39.5" height="39.5"/>
<image name="next_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="next_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="security_toogle_background_grey.png" width="52" height="27"/>
<image name="security_toogle_button.png" width="21" height="21"/>
<image name="security_toogle_icon_green.png" width="33.599998474121094" height="38.400001525878906"/>
<image name="security_toogle_icon_grey.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>

Binary file not shown.

View file

@ -0,0 +1,89 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<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="ChatConversationImdnView">
<connections>
<outlet property="msgView" destination="VK8-0e-Hsa" id="sWi-sR-kan"/>
<outlet property="tableView" destination="HjO-C8-Itr" id="cuC-QY-xbT"/>
<outlet property="view" destination="1g1-pp-Uhi" id="Km4-Mj-txf"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1g1-pp-Uhi" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7Tm-Jz-Rvb">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X8x-9L-bCY" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="Delivery status" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="bc0-Ql-lPE" userLabel="addressLabel">
<rect key="frame" x="123" y="0.0" width="166" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JYS-Be-ffH" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="7Fg-hr-OL1"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VK8-0e-Hsa" userLabel="msgView">
<rect key="frame" x="8" y="74" width="398" height="123"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</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="HjO-C8-Itr">
<rect key="frame" x="8" y="229" width="398" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="separatorColor" red="0.67030966280000004" green="0.71867996450000005" blue="0.75078284740000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</tableView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-247.5" y="14.5"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
<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>

Binary file not shown.

View file

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<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="21207"/>
<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="ChatConversationInfoView">
<connections>
<outlet property="addButton" destination="XSI-9T-NtW" id="BlB-bn-XWt"/>
<outlet property="nameLabel" destination="69I-Un-ASz" id="qmU-o2-TmF"/>
<outlet property="nextButton" destination="0v1-qv-lPd" id="nPu-w2-iy3"/>
<outlet property="participantsBar" destination="n8e-tx-jlu" id="kNr-kM-7MJ"/>
<outlet property="quitButton" destination="Hnm-7C-dBQ" id="Kp1-Aw-FQq"/>
<outlet property="tableView" destination="pMq-Gv-0uu" id="ELS-RQ-olX"/>
<outlet property="view" destination="zgv-a8-72k" id="1Cq-i3-h2W"/>
<outlet property="waitView" destination="nt8-fb-6Re" id="zRw-iF-DnL"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="BKk-x7-cO3" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zgv-a8-72k">
<rect key="frame" x="0.0" y="42" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<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="pMq-Gv-0uu">
<rect key="frame" x="8" y="148" width="398" height="581"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="separatorColor" red="0.67030966280000004" green="0.71867996450000005" blue="0.75078284740000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</tableView>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Meo-HD-uD0" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="Info" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="tJn-Nv-Duq" userLabel="addressLabel">
<rect key="frame" x="124" y="0.0" width="166" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HVD-Ql-SJG" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="83" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="MaN-Ja-qM2"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0v1-qv-lPd" userLabel="nextButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="valid_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="valid_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onNextClick:" destination="-1" eventType="touchUpInside" id="OC1-up-De3"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<view alpha="0.69999999999999996" contentMode="scaleToFill" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="n8e-tx-jlu" userLabel="particpantsBar">
<rect key="frame" x="0.0" y="112" width="414" height="28"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="Participants" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="vof-h9-AN3" userLabel="participantsLabel">
<rect key="frame" x="0.0" y="0.0" width="414" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<nil key="textColor"/>
<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="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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="chat_group_add.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="valid_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddClick:" destination="-1" eventType="touchUpInside" id="Dcn-sR-xRc"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="wordWrap" translatesAutoresizingMaskIntoConstraints="NO" id="Hnm-7C-dBQ" userLabel="quitButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="113" y="737" width="189" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.98273354768753052" green="0.36591529846191406" blue="0.0092478422448039055" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Use SIP account">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="LEAVE THE GROUP">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<state key="highlighted" backgroundImage="color_F.png">
<color key="titleColor" red="0.67030966280000004" green="0.71867996450000005" blue="0.75078284740000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onQuitClick:" destination="-1" eventType="touchUpInside" id="TT0-hW-JMh"/>
</connections>
</button>
<textField opaque="NO" clipsSubviews="YES" tag="100" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Name the group" textAlignment="center" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="69I-Un-ASz" userLabel="chatRoomNameField">
<rect key="frame" x="9" y="74" width="396" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
<accessibility key="accessibilityConfiguration" label="ChatRoomName"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="next" enablesReturnKeyAutomatically="YES"/>
</textField>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nt8-fb-6Re" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="SNK-Vt-iQa" userLabel="activityIndicatorView">
<rect key="frame" x="199" y="380" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="31" y="88"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="chat_group_add.png" width="42" height="42"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="valid_default.png" width="44.799999237060547" height="30.399999618530273"/>
<image name="valid_disabled.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>

Binary file not shown.

View file

@ -0,0 +1,714 @@
<?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_1" orientation="portrait" appearance="light"/>
<dependencies>
<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>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ChatConversationView">
<connections>
<outlet property="addressLabel" destination="40" id="43"/>
<outlet property="backButton" destination="9" id="Jcb-ET-bKd"/>
<outlet property="backToCallButton" destination="Hc0-GX-fC5" id="pYe-gN-Z64"/>
<outlet property="callButton" destination="Wzg-i0-spp" id="w9L-aT-1AD"/>
<outlet property="chatView" destination="49" id="Rxt-Zy-19x"/>
<outlet property="composeIndicatorView" destination="fx4-ao-53M" id="xk5-nK-lur"/>
<outlet property="composeLabel" destination="fpY-Fv-ht2" id="4L6-ik-ZAe"/>
<outlet property="encryptedButton" destination="tjL-Vc-5gN" id="zxw-Fs-ofB"/>
<outlet property="ephemeralndicator" destination="LN7-ci-kNn" id="hqU-98-qkJ"/>
<outlet property="imagesCollectionView" destination="JGQ-p2-HCX" id="6dt-1f-jpa"/>
<outlet property="imagesView" destination="3qd-ys-t2L" id="f9L-FU-PMI"/>
<outlet property="landscapeView" destination="VoU-7Q-fgp" id="iRJ-sh-thF"/>
<outlet property="listSwipeGestureRecognizer" destination="dzw-n4-l9i" id="JVP-Vl-lIa"/>
<outlet property="listTapGestureRecognizer" destination="tkk-Tm-A7C" id="gqU-iJ-RGm"/>
<outlet property="messageField" destination="pqa-tg-5ml" id="emj-yI-K60"/>
<outlet property="messageView" destination="14" id="89"/>
<outlet property="particpantsLabel" destination="Ncq-Zc-X6j" id="tQM-q1-cey"/>
<outlet property="pictureButton" destination="73" id="84"/>
<outlet property="popupMenu" destination="gdT-1Q-vU2" id="M7Q-tv-zRF"/>
<outlet property="portraitView" destination="6" id="xJJ-1H-6N6"/>
<outlet property="replyView" destination="wve-MK-7ME" id="fhJ-ne-9Xx"/>
<outlet property="sendButton" destination="15" id="27"/>
<outlet property="tableController" destination="29" id="32"/>
<outlet property="toggleMenuButton" destination="CPn-Oc-9PX" id="QdS-xO-bfA"/>
<outlet property="toggleRecord" destination="aTi-pm-fAG" id="RYV-0Q-v5p"/>
<outlet property="toggleSelectionButton" destination="c9z-aq-2UP" id="kiK-wF-8iU"/>
<outlet property="topBar" destination="7" id="JH8-F4-Bdq"/>
<outlet property="view" destination="6" id="11"/>
<outlet property="vrDeleteButton" destination="wi9-en-JCZ" id="09B-Bm-ECJ"/>
<outlet property="vrDurationLabel" destination="dMW-Ix-4k0" id="Ugl-f5-r2m"/>
<outlet property="vrInnerView" destination="eXD-Gd-FXA" id="wBh-N1-Au9"/>
<outlet property="vrPlayButton" destination="FNM-bb-AlC" id="NOD-GE-eIA"/>
<outlet property="vrView" destination="Tru-Zm-4EZ" id="Rx2-ls-nMc"/>
<outlet property="vrWave" destination="m9m-2e-T7E" id="F07-qS-Yj6"/>
<outlet property="vrWaveMask" destination="TzM-ND-yp4" id="FKT-Gu-CyA"/>
<outlet property="vrWaveMaskPlayer" destination="OTf-Od-TDn" id="g9D-K1-Gf0"/>
</connections>
</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"/>
<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"/>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="12"/>
</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"/>
<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"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="29" eventType="touchUpInside" id="tdO-wP-Ttr"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="c6C-ow-Yhi"/>
</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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<nil key="textColor"/>
<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"/>
<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"/>
</state>
<state key="disabled" image="call_alt_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="Dsf-nS-K3V"/>
</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"/>
<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"/>
</state>
<state key="disabled" image="call_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackToCallClick:" destination="-2" eventType="touchUpInside" id="bOG-ra-UpM"/>
<outlet property="tableView" destination="8" id="w1i-Px-Wdf"/>
</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"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="JoY-wC-JQy"/>
</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"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="29" eventType="touchUpInside" id="2Q7-xM-Shx"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="0we-lw-TyJ"/>
</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"/>
<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"/>
<state key="normal" image="more_menu_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onToggleMenu:" destination="-1" eventType="touchUpInside" id="Mlz-Hp-FXl"/>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onSelectionToggle:" destination="29" eventType="touchUpInside" id="eP5-bU-LEA"/>
</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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
<connections>
<outlet property="dataSource" destination="29" id="6U9-NJ-Z7W"/>
<outlet property="delegate" destination="29" id="8Lv-aI-a0V"/>
<outletCollection property="gestureRecognizers" destination="dzw-n4-l9i" appends="YES" id="ba4-aY-7EA"/>
<outletCollection property="gestureRecognizers" destination="tkk-Tm-A7C" appends="YES" id="rxU-cr-Kav"/>
</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"/>
<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="10" y="-5" width="406" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label=""/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send picture"/>
<state key="normal" image="chat_attachment_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_attachment_disabled.png"/>
<state key="highlighted" image="chat_attachment_over.png"/>
<connections>
<action selector="onPictureClick:" destination="-1" eventType="touchUpInside" id="87"/>
</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"/>
<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"/>
<state key="normal" image="vr_off.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="selected" image="vr_on.png"/>
<connections>
<action selector="onVrStart:" destination="-1" eventType="touchUpInside" id="6QP-19-E8o"/>
</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"/>
<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"/>
<state key="normal" image="chat_send_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_send_disabled.png"/>
<state key="highlighted" image="chat_send_over.png"/>
<connections>
<action selector="onSendClick:" destination="-1" eventType="touchUpInside" id="25"/>
</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"/>
<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"/>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="delete_default.png"/>
<connections>
<action selector="onVrDelete:" destination="-1" eventType="touchUpInside" id="yV4-iY-mvE"/>
</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"/>
<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"/>
<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"/>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="vr_play.png"/>
<connections>
<action selector="onvrPlayPauseStop:" destination="-1" eventType="touchUpInside" id="Wka-en-Ic8"/>
</connections>
</button>
</subviews>
<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"/>
<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"/>
<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">
<size key="itemSize" width="50" height="100"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
</collectionView>
</subviews>
<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="372" y="8" width="34" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_1_indicator.png"/>
<connections>
<action selector="onEncryptedDevicesClick:" destination="-1" eventType="touchUpInside" id="K1W-Ao-IDg"/>
</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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</tableView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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"/>
<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"/>
<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"/>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="oLf-ke-zgQ"/>
</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"/>
<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"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="29" eventType="touchUpInside" id="EVj-uP-wVf"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="hGj-xz-K5n"/>
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" text="Contact1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="uEp-mD-eik" userLabel="addressLabel">
<rect key="frame" x="67" y="1" width="366" height="57"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="22"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="NWL-CQ-eNR"/>
</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"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="29" eventType="touchUpInside" id="4ei-sX-oIk"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="fNp-ya-dag"/>
</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"/>
<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"/>
<state key="normal" image="more_menu_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onToggleMenu:" destination="-1" eventType="touchUpInside" id="vYL-BQ-UTF"/>
</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"/>
<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"/>
</state>
<state key="disabled" image="call_alt_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="gcb-ac-VkW"/>
</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"/>
<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"/>
</state>
<state key="disabled" image="call_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackToCallClick:" destination="-2" eventType="touchUpInside" id="5cp-dW-Oc7"/>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onSelectionToggle:" destination="29" eventType="touchUpInside" id="17V-y4-JHi"/>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</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"/>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
<connections>
<outlet property="dataSource" destination="29" id="hC0-KH-0e3"/>
<outlet property="delegate" destination="29" id="sSq-5N-DaD"/>
</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"/>
<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"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label=""/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<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"/>
<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"/>
<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">
<rect key="frame" x="0.0" y="0.0" width="66" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send picture"/>
<state key="normal" image="chat_attachment_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_attachment_disabled.png"/>
<state key="highlighted" image="chat_attachment_over.png"/>
<connections>
<action selector="onPictureClick:" destination="-1" eventType="touchUpInside" id="Ag3-po-DGR"/>
</connections>
</button>
<button opaque="NO" tag="9019" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zub-Ow-smm" userLabel="audioRecordingButton">
<rect key="frame" x="66" y="0.0" width="66" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Send picture"/>
<state key="normal" image="vr_off.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="selected" image="vr_on.png"/>
<connections>
<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"/>
<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"/>
<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"/>
<state key="normal" image="chat_send_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_send_disabled.png"/>
<state key="highlighted" image="chat_send_over.png"/>
<connections>
<action selector="onSendClick:" destination="-1" eventType="touchUpInside" id="dx4-lF-ekG"/>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</imageView>
</subviews>
</view>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</tableView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-875.36231884057975" y="-137.27678571428569"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="29" userLabel="messagesTableView" customClass="ChatConversationTableView">
<extendedEdge key="edgesForExtendedLayout"/>
<nil key="simulatedStatusBarMetrics"/>
<connections>
<outlet property="cancelButton" destination="bci-3K-AcG" id="ZTI-gJ-SEL"/>
<outlet property="deleteButton" destination="Wag-Nx-kd6" id="hOb-3g-mnR"/>
<outlet property="editButton" destination="FqM-Ud-i58" id="9L7-rC-Aqy"/>
<outlet property="toggleSelectionButton" destination="c9z-aq-2UP" id="a2J-JQ-rhX"/>
<outlet property="view" destination="8" id="g4m-ne-lbP"/>
</connections>
<point key="canvasLocation" x="1022.4" y="295.05247376311848"/>
</tableViewController>
<swipeGestureRecognizer direction="left" id="dzw-n4-l9i">
<connections>
<action selector="onListSwipe:" destination="-1" id="bd8-v2-u8H"/>
</connections>
</swipeGestureRecognizer>
<tapGestureRecognizer enabled="NO" id="tkk-Tm-A7C">
<connections>
<action selector="onListTap:" destination="-1" id="ejK-2Q-qkC"/>
</connections>
</tapGestureRecognizer>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="call_alt_start_default.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="call_alt_start_disabled.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="call_back_default.png" width="61.599998474121094" height="44"/>
<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="chat_attachment_default.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_attachment_disabled.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_attachment_over.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_send_default.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_send_disabled.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_send_over.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="ephemeral_messages_color_A.png" width="136" height="158.39999389648438"/>
<image name="more_menu_default.png" width="118.40000152587891" height="118.40000152587891"/>
<image name="security_1_indicator.png" width="27.5" height="32.5"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="vr_off.png" width="40" height="40"/>
<image name="vr_on.png" width="40" height="40"/>
<image name="vr_play.png" width="200" height="200"/>
<image name="vr_wave.png" width="1078" height="90"/>
<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>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,236 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<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="ChatsListView">
<connections>
<outlet property="addButton" destination="Z5G-IF-PBY" id="Tzw-rz-Bwe"/>
<outlet property="addGroupChatButton" destination="glf-ni-nqe" id="0hy-5m-7C7"/>
<outlet property="backToCallButton" destination="Fac-hy-za4" id="8I3-TM-oJ7"/>
<outlet property="cancelForwardButton" destination="Kxx-SO-CB0" id="LFJ-NQ-YrU"/>
<outlet property="forwardTitle" destination="waa-HU-xFW" id="Qqs-p4-k9A"/>
<outlet property="tableController" destination="4" id="18"/>
<outlet property="toggleSelectionButton" destination="uqG-2T-VOa" id="cAk-tz-5Z0"/>
<outlet property="view" destination="5" id="14"/>
<outlet property="waitView" destination="cpj-Jc-imm" id="t7Q-YM-znJ"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="WKv-mw-S2B" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="0.0" y="42" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z5G-IF-PBY" userLabel="addButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="New discussion"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="chat_add_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_add_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddClick:" destination="-1" eventType="touchUpInside" id="g4q-By-6nW"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="glf-ni-nqe" userLabel="addGroupButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="82" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="New discussion"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="chat_add_group.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_add_group.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddGroupChatClick:" destination="-1" eventType="touchUpInside" id="tem-mm-w62"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KhE-c3-2Zj" userLabel="cancelButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" 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"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="4" eventType="touchUpInside" id="8xd-cU-loG"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="hKF-q1-5DJ"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Kxx-SO-CB0" userLabel="cancelForwardButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" 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"/>
<state key="normal" image="cancel_forward.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelForwardClicked:" destination="-1" eventType="touchUpInside" id="2gp-RW-sJE"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fac-hy-za4" userLabel="backToCallButton" customClass="UIBackToCallButton">
<rect key="frame" x="165" y="0.0" width="83" height="66"/>
<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"/>
</state>
<state key="disabled" image="call_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackToCallClick:" destination="-2" eventType="touchUpInside" id="eUD-Gk-qji"/>
<outlet property="tableView" destination="6" id="ePS-cV-S6m"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uqG-2T-VOa" userLabel="toggleSelectionButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="248" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onSelectionToggle:" destination="4" eventType="touchUpInside" id="ct6-0c-d1q"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rxo-0W-iqY" userLabel="deleteButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" 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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="m6p-pf-GLX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qem-Y1-v78" userLabel="editButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="4" eventType="touchUpInside" id="COv-sY-0TU"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="e2C-A0-kjU"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="60" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="6" userLabel="tableView">
<rect key="frame" x="0.0" y="66" width="414" height="722"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outlet property="dataSource" destination="4" id="11"/>
<outlet property="delegate" destination="4" id="12"/>
</connections>
</tableView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="waa-HU-xFW" userLabel="forwardTitle">
<rect key="frame" x="0.0" y="66" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No conversations" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MSn-PY-yf1" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="66" width="414" height="722"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<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="cpj-Jc-imm" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="DjR-Dv-uoX" userLabel="activityIndicatorView">
<rect key="frame" x="198" y="380" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/>
</view>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="50.724637681159422" y="93.080357142857139"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="4" userLabel="tableController" customClass="ChatsListTableView">
<extendedEdge key="edgesForExtendedLayout"/>
<nil key="simulatedStatusBarMetrics"/>
<connections>
<outlet property="cancelButton" destination="KhE-c3-2Zj" id="0BM-Q1-ZaR"/>
<outlet property="deleteButton" destination="Rxo-0W-iqY" id="vsb-dD-1zl"/>
<outlet property="editButton" destination="qem-Y1-v78" id="Ba4-I1-fI5"/>
<outlet property="emptyView" destination="MSn-PY-yf1" id="C72-01-4pD"/>
<outlet property="toggleSelectionButton" destination="uqG-2T-VOa" id="ytx-bj-7Qr"/>
<outlet property="view" destination="6" id="13"/>
</connections>
</tableViewController>
</objects>
<resources>
<image name="call_back_default.png" width="61.599998474121094" height="44"/>
<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="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"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
<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>

Binary file not shown.

View file

@ -0,0 +1,325 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ContactDetailsView">
<connections>
<outlet property="avatarImage" destination="B6X-C9-2vm" id="tQc-xv-nJg"/>
<outlet property="backButton" destination="9" id="50"/>
<outlet property="cancelButton" destination="bPQ-aJ-Lk6" id="QHN-qi-QNv"/>
<outlet property="contentView" destination="8D6-vy-obt" id="GZW-ov-Wfv"/>
<outlet property="deleteButton" destination="MuB-yy-R9o" id="cni-lk-awn"/>
<outlet property="editButton" destination="8" id="31"/>
<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="portraitView" destination="1" id="k69-5P-ieM"/>
<outlet property="tableController" destination="20" id="27"/>
<outlet property="view" destination="1" id="3"/>
<outlet property="waitView" destination="JK8-Td-I1i" id="nFS-hz-vYl"/>
</connections>
</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"/>
<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"/>
<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"/>
<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"/>
<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"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="yyu-9r-MIh"/>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleColor" red="0.28619974851608276" green="0.32144349813461304" blue="0.35980013012886047" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="10"/>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="delete_default.png">
<color key="titleColor" red="0.28619974851608276" green="0.32144349813461304" blue="0.35980013012886047" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="vxj-6p-8lE"/>
</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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="edit_default.png">
<color key="titleColor" red="0.28619974851608276" green="0.32144349813461304" blue="0.35980013012886047" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="edit_disabled.png"/>
<state key="selected" image="valid_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="-1" eventType="touchUpInside" id="30"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</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"/>
<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"/>
<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"/>
<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>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<connections>
<outlet property="dataSource" destination="20" id="28"/>
<outlet property="delegate" destination="20" id="29"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-632.60869565217399" y="128.90625"/>
</view>
<view contentMode="scaleToFill" id="gnD-7x-PSh" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lgD-Mw-h57">
<rect key="frame" x="0.0" y="42" width="667" height="333"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="L0a-sZ-jGX" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="WKb-RL-2xW" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button hidden="YES" opaque="NO" tag="3" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XGy-cw-7de" userLabel="cancelButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="133" 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"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="v96-rt-8t6"/>
</connections>
</button>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XFH-3u-WFI" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="133" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleColor" red="0.28619974851608276" green="0.32144349813461304" blue="0.35980013012886047" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="9Bf-9b-t68"/>
</connections>
</button>
<button opaque="NO" tag="5" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XSh-gg-HmZ" userLabel="deleteButton" customClass="UIToggleButton">
<rect key="frame" x="400" y="0.0" width="134" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="delete_default.png">
<color key="titleColor" red="0.28619974851608276" green="0.32144349813461304" blue="0.35980013012886047" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="9ng-e2-HNr"/>
</connections>
</button>
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tQx-Wr-TFA" userLabel="editButton" customClass="UIToggleButton">
<rect key="frame" x="534" y="0.0" width="133" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="edit_default.png">
<color key="titleColor" red="0.28619974851608276" green="0.32144349813461304" blue="0.35980013012886047" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="edit_disabled.png"/>
<state key="selected" image="valid_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="-1" eventType="touchUpInside" id="ZOh-tv-N0H"/>
</connections>
</button>
</subviews>
</view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="7" contentMode="scaleToFill" fixedFrame="YES" directionalLockEnabled="YES" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8D6-vy-oby" userLabel="contentView">
<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">
<rect key="frame" x="46" y="8" width="62" height="62"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="9" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ozv-hZ-xHz" userLabel="nameLabel">
<rect key="frame" x="116" y="8" width="551" height="62"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="27"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="WMA-Yo-NbI" userLabel="tableView" customClass="TPKeyboardAvoidingTableView">
<rect key="frame" x="0.0" y="84" width="667" height="183"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<connections>
<outlet property="dataSource" destination="20" id="YTH-Qp-Xwq"/>
<outlet property="delegate" destination="20" id="C42-FH-IyU"/>
</connections>
</tableView>
</subviews>
</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="oFA-SG-IDe" userLabel="emptyLabel">
<rect key="frame" x="0.0" y="66" width="667" height="267"/>
<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"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EdP-53-rq9" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="667" height="333"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="T1j-jc-5iP" userLabel="activityIndicatorView">
<rect key="frame" x="326" y="155" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="36.956521739130437" y="184.48660714285714"/>
</view>
<tableViewController id="20" userLabel="tableController" customClass="ContactDetailsTableView">
<extendedEdge key="edgesForExtendedLayout"/>
<connections>
<outlet property="editButton" destination="8" id="wZf-wX-YIu"/>
<outlet property="view" destination="19" id="26"/>
</connections>
</tableViewController>
<tapGestureRecognizer id="8bV-f4-pLL" userLabel="onAvatarClick">
<connections>
<action selector="onAvatarClick:" destination="-1" id="olM-C9-dHO"/>
</connections>
</tapGestureRecognizer>
</objects>
<resources>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<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="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<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"/>
</resources>
</document>

Binary file not shown.

View file

@ -0,0 +1,260 @@
<?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"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<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="ContactsListView">
<connections>
<outlet property="addButton" destination="6" id="91"/>
<outlet property="allButton" destination="4" id="27"/>
<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="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"/>
<outlet property="view" destination="2" id="16"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1YR-9t-hRk" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="93" userLabel="switchView">
<rect key="frame" x="0.0" y="0.0" width="150" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4" userLabel="allButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="All contacts filter"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<inset key="titleEdgeInsets" minX="-38" minY="15" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="16" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" image="contacts_all_default.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contacts_all_disabled.png"/>
<state key="selected" image="contacts_all_selected.png">
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAllClick:" destination="-1" eventType="touchUpInside" id="29"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="A9k-KU-Dlm" userLabel="selectedButtonImage">
<rect key="frame" x="0.0" y="63" width="75" height="3"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5" userLabel="sipButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="75" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Linphone contacts filter"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<state key="normal" image="contacts_sip_default.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contacts_sip_disabled.png"/>
<state key="selected" image="contacts_sip_selected.png">
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onLinphoneClick:" destination="-1" eventType="touchUpInside" id="47"/>
</connections>
</button>
</subviews>
</view>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MZP-cb-ntf" userLabel="cancelButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="TJG-JZ-YRR" eventType="touchUpInside" id="1nW-5f-kbI"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="PL4-Js-Xvg"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tFB-Vf-lUX" userLabel="deleteButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="300" y="0.0" width="75" 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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="VJS-p2-Jsp"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DZc-zR-1Q7" userLabel="editButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="TJG-JZ-YRR" eventType="touchUpInside" id="CKU-6b-3F2"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="uvi-82-4ka"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5lZ-u7-Yex" userLabel="toggleSelectionButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onSelectionToggle:" destination="TJG-JZ-YRR" eventType="touchUpInside" id="YcH-HT-zyi"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6" userLabel="addButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="contact_add_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contact_add_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddContactClick:" destination="-1" eventType="touchUpInside" id="86"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<searchBar contentMode="redraw" fixedFrame="YES" showsCancelButton="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5jE-oF-d45" userLabel="searchBar">
<rect key="frame" x="0.0" y="66" width="375" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textInputTraits key="textInputTraits"/>
<connections>
<outlet property="delegate" destination="-1" id="Fk3-Tl-dY0"/>
</connections>
</searchBar>
<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="zOo-FS-W6l" userLabel="tableView">
<rect key="frame" x="0.0" y="110" width="375" height="449"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outlet property="dataSource" destination="TJG-JZ-YRR" id="334-RR-jEi"/>
<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"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<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>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" animating="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="udQ-TE-UlZ">
<rect key="frame" x="80" y="8" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Loading contacts..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="qSa-Ba-dq9">
<rect key="frame" x="108" y="8" width="145" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="5.7971014492753632" y="141.96428571428569"/>
</view>
<tableViewController id="TJG-JZ-YRR" userLabel="tableController" customClass="ContactsListTableView">
<connections>
<outlet property="cancelButton" destination="MZP-cb-ntf" id="4Hf-l6-Qyp"/>
<outlet property="deleteButton" destination="tFB-Vf-lUX" id="dF5-uF-nhK"/>
<outlet property="editButton" destination="DZc-zR-1Q7" id="TkL-MM-OFA"/>
<outlet property="emptyView" destination="JR3-k7-gVP" id="3vV-F3-Eit"/>
<outlet property="toggleSelectionButton" destination="5lZ-u7-Yex" id="C99-nu-2wJ"/>
<outlet property="view" destination="zOo-FS-W6l" id="cM7-Da-i7e"/>
</connections>
<point key="canvasLocation" x="739.13043478260875" y="137.94642857142856"/>
</tableViewController>
</objects>
<resources>
<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="color_A.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="contact_add_default.png" width="55.200000762939453" height="47.200000762939453"/>
<image name="contact_add_disabled.png" width="55.200000762939453" height="47.200000762939453"/>
<image name="contacts_all_default.png" width="52" height="44"/>
<image name="contacts_all_disabled.png" width="52" height="44"/>
<image name="contacts_all_selected.png" width="52" height="44"/>
<image name="contacts_sip_default.png" width="39.5" height="39.5"/>
<image name="contacts_sip_disabled.png" width="38" height="30"/>
<image name="contacts_sip_selected.png" width="39.5" height="39.5"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
<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>

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,71 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CountryListView">
<connections>
<outlet property="tableView" destination="UcW-gD-iwL" id="878-PR-Gn9"/>
<outlet property="view" destination="1" id="3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="418-8u-hzT" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="SELECT A COUNTRY" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MLt-gO-M3J" userLabel="titleLabel">
<rect key="frame" x="92" y="0.0" width="230" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hOj-Kl-K9W" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<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"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="DTU-Ur-aPJ"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" rowHeight="40" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="UcW-gD-iwL">
<rect key="frame" x="0.0" y="66" width="414" height="830"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="separatorColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<inset key="separatorInset" minX="15" minY="0.0" maxX="0.0" maxY="0.0"/>
<connections>
<outlet property="dataSource" destination="-1" id="29f-d6-ctV"/>
<outlet property="delegate" destination="-1" id="Dg5-gz-Qgm"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" red="0.93620026111602783" green="0.94070994853973389" blue="0.95069998502731323" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<point key="canvasLocation" x="134" y="143"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
</resources>
</document>

Binary file not shown.

View file

@ -0,0 +1,349 @@
<?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"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<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="DialerView">
<connections>
<outlet property="addContactButton" destination="222" id="225"/>
<outlet property="addressField" destination="4" id="205"/>
<outlet property="backButton" destination="183" id="d75-ly-K6w"/>
<outlet property="backspaceButton" destination="8dc-hj-rvt" id="6p9-p4-QAN"/>
<outlet property="callButton" destination="224" id="231"/>
<outlet property="eightButton" destination="35" id="204"/>
<outlet property="fiveButton" destination="31" id="195"/>
<outlet property="fourButton" destination="30" id="194"/>
<outlet property="hashButton" destination="41" id="4Vx-Tl-ywI"/>
<outlet property="landscapeView" destination="171" id="mdM-t5-k4V"/>
<outlet property="nineButton" destination="36" id="200"/>
<outlet property="oneButton" destination="38" id="191"/>
<outlet property="padView" destination="180" id="bxG-9v-Pvj"/>
<outlet property="portraitView" destination="171" id="GLX-cG-iOA"/>
<outlet property="sevenButton" destination="34" id="197"/>
<outlet property="sixButton" destination="33" id="196"/>
<outlet property="starButton" destination="39" id="199"/>
<outlet property="threeButton" destination="29" id="193"/>
<outlet property="twoButton" destination="37" id="192"/>
<outlet property="view" destination="171" id="176"/>
<outlet property="zeroButton" destination="40" id="198"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="qaB-qV-B0p" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="540" height="960"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="171">
<rect key="frame" x="0.0" y="42" width="540" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view clipsSubviews="YES" alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="178" userLabel="dialer">
<rect key="frame" x="0.0" y="0.0" width="540" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<textField opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter a number or an address" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" minimumFontSize="15" translatesAutoresizingMaskIntoConstraints="NO" id="4" userLabel="addressField" customClass="UIAddressTextField">
<rect key="frame" x="31" y="0.0" width="426" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Enter an address"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" returnKeyType="join"/>
<connections>
<action selector="onAddressChange:" destination="-1" eventType="editingChanged" id="FdS-Kl-3dS"/>
<outlet property="delegate" destination="-1" id="190"/>
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8dc-hj-rvt" userLabel="backspaceButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="475" y="0.0" width="60" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<state key="normal" image="backspace_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="backspace_disabled.png"/>
<state key="highlighted" image="backspace_over.png"/>
<connections>
<action selector="onBackspaceClick:" destination="-1" eventType="touchUpInside" id="sWE-Ch-kAr"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<imageView userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="dialer_background.png" translatesAutoresizingMaskIntoConstraints="NO" id="AH0-S5-0Ku" userLabel="logoImage">
<rect key="frame" x="100" y="279" width="340" height="294"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="180" userLabel="pad">
<rect key="frame" x="0.0" y="66" width="540" height="720"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="38" userLabel="1" customClass="UIDigitButton">
<rect key="frame" x="0.0" y="0.0" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.40000001000000002" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="1"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_1_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_1_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="240"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="37" userLabel="2" customClass="UIDigitButton">
<rect key="frame" x="184" y="0.0" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="2"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_2_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_2_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="241"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="29" userLabel="3" customClass="UIDigitButton">
<rect key="frame" x="367" y="0.0" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="3"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_3_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_3_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="242"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="30" userLabel="4" customClass="UIDigitButton">
<rect key="frame" x="0.0" y="180" width="173" height="171"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="4"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_4_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_4_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="243"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="31" userLabel="5" customClass="UIDigitButton">
<rect key="frame" x="184" y="180" width="173" height="171"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_5_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_5_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="244"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="33" userLabel="6" customClass="UIDigitButton">
<rect key="frame" x="367" y="180" width="173" height="171"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="6"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_6_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_6_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="245"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="34" userLabel="7" customClass="UIDigitButton">
<rect key="frame" x="0.0" y="361" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="7"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_7_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_7_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="246"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="35" userLabel="8" customClass="UIDigitButton">
<rect key="frame" x="184" y="361" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="8"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_8_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_8_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="247"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="36" userLabel="9" customClass="UIDigitButton">
<rect key="frame" x="367" y="361" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="9"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_9_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_9_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="248"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="39" userLabel="*" customClass="UIDigitButton">
<rect key="frame" x="0.0" y="543" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Star"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_star_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_star_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="249"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="40" userLabel="0" customClass="UIDigitButton">
<rect key="frame" x="184" y="543" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="0"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_0_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_0_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="250"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="41" userLabel="#" customClass="UIDigitButton">
<rect key="frame" x="367" y="543" width="173" height="170"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Hash"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_hash_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_hash_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="251"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="182" userLabel="bottomBar">
<rect key="frame" x="0.0" y="786" width="540" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="183" userLabel="backButton">
<rect key="frame" x="0.0" y="0.0" width="180" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_alt_back_default.png" backgroundImage="color_F.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_alt_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="233"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="222" userLabel="addContactButton">
<rect key="frame" x="0.0" y="0.0" width="180" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="contact_add_default.png" backgroundImage="color_F.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contact_add_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddContactClick:" destination="-1" eventType="touchUpInside" id="230"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="224" userLabel="callButton" customClass="UICallButton">
<rect key="frame" x="180" y="0.0" width="360" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_audio_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_audio_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_L.png"/>
<connections>
<outlet property="addressField" destination="4" id="235"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-98.550724637681171" y="149.33035714285714"/>
</view>
</objects>
<resources>
<image name="backspace_default.png" width="58.400001525878906" height="30.399999618530273"/>
<image name="backspace_disabled.png" width="58.400001525878906" height="30.399999618530273"/>
<image name="backspace_over.png" width="58.400001525878906" height="30.399999618530273"/>
<image name="call_alt_back_default.png" width="81.599998474121094" height="58.400001525878906"/>
<image name="call_alt_back_disabled.png" width="81.599998474121094" height="58.400001525878906"/>
<image name="call_audio_start_default.png" width="58.400001525878906" height="58.400001525878906"/>
<image name="call_audio_start_disabled.png" width="58.400001525878906" height="58.400001525878906"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="color_L.png" width="2" height="2"/>
<image name="contact_add_default.png" width="55.200000762939453" height="47.200000762939453"/>
<image name="contact_add_disabled.png" width="55.200000762939453" height="47.200000762939453"/>
<image name="dialer_background.png" width="1200" height="1030"/>
<image name="numpad_0_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_0_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_1_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_1_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_2_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_2_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_3_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_3_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_4_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_4_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_5_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_5_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_6_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_6_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_7_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_7_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_8_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_8_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_9_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_9_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_hash_default.png" width="84.800003051757812" height="78.400001525878906"/>
<image name="numpad_hash_over.png" width="84.800003051757812" height="78.400001525878906"/>
<image name="numpad_over_background.png" width="2" height="2"/>
<image name="numpad_star_default.png" width="84.800003051757812" height="81.599998474121094"/>
<image name="numpad_star_over.png" width="84.800003051757812" height="81.599998474121094"/>
<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>

Binary file not shown.

View file

@ -0,0 +1,674 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="DialerView">
<connections>
<outlet property="addContactButton" destination="222" id="225"/>
<outlet property="addressField" destination="4" id="205"/>
<outlet property="backButton" destination="183" id="d75-ly-K6w"/>
<outlet property="backspaceButton" destination="8dc-hj-rvt" id="6p9-p4-QAN"/>
<outlet property="callButton" destination="224" id="231"/>
<outlet property="eightButton" destination="35" id="204"/>
<outlet property="fiveButton" destination="31" id="195"/>
<outlet property="fourButton" destination="30" id="194"/>
<outlet property="hashButton" destination="41" id="4Vx-Tl-ywI"/>
<outlet property="landscapeView" destination="MqR-YI-CLm" id="18Z-8w-XWB"/>
<outlet property="nineButton" destination="36" id="200"/>
<outlet property="oneButton" destination="38" id="191"/>
<outlet property="portraitView" destination="171" id="yo2-xo-4wI"/>
<outlet property="sevenButton" destination="34" id="197"/>
<outlet property="sixButton" destination="33" id="196"/>
<outlet property="starButton" destination="39" id="199"/>
<outlet property="threeButton" destination="29" id="193"/>
<outlet property="twoButton" destination="37" id="192"/>
<outlet property="videoPreview" destination="30b-JN-Ibj" id="Kwj-av-WIg"/>
<outlet property="view" destination="171" id="176"/>
<outlet property="zeroButton" destination="40" id="198"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="qaB-qV-B0p" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="800" height="1290"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="171">
<rect key="frame" x="0.0" y="60" width="800" height="1130"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="1" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_D.png" translatesAutoresizingMaskIntoConstraints="NO" id="PI3-CU-FXR" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="800" height="1130"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="dialer_background.png" translatesAutoresizingMaskIntoConstraints="NO" id="tsy-aZ-cHg" userLabel="logoImage">
<rect key="frame" x="8" y="112" width="784" height="480"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<view tag="3" contentMode="scaleAspectFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="30b-JN-Ibj" userLabel="preview">
<rect key="frame" x="0.0" y="0.0" width="800" height="1210"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view tag="4" contentMode="scaleAspectFit" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="g6f-Xa-Veg">
<rect key="frame" x="245" y="600" width="310" height="450"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<view clipsSubviews="YES" alpha="0.90000000000000002" tag="5" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="178" userLabel="dialer">
<rect key="frame" x="0.0" y="0.0" width="310" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<textField opaque="NO" clearsContextBeforeDrawing="NO" tag="7" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter a number or an address" adjustsFontSizeToFit="NO" minimumFontSize="5" translatesAutoresizingMaskIntoConstraints="NO" id="4" userLabel="addressField" customClass="UIAddressTextField">
<rect key="frame" x="8" y="0.0" width="239" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Enter an address"/>
<fontDescription key="fontDescription" type="system" pointSize="21"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" returnKeyType="join"/>
<connections>
<action selector="onAddressChange:" destination="-1" eventType="editingChanged" id="FdS-Kl-3dS"/>
<outlet property="delegate" destination="-1" id="190"/>
</connections>
</textField>
<button opaque="NO" tag="8" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8dc-hj-rvt" userLabel="backspaceButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="245" y="0.0" width="60" height="80"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<state key="normal" image="backspace_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="backspace_disabled.png"/>
<state key="highlighted" image="backspace_over.png"/>
<connections>
<action selector="onBackspaceClick:" destination="-1" eventType="touchUpInside" id="sWE-Ch-kAr"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view tag="9" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="180" userLabel="pad">
<rect key="frame" x="0.0" y="80" width="310" height="290"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="10" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="38" userLabel="1" customClass="UIDigitButton">
<rect key="frame" x="27" y="8" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.40000001000000002" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="1"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_1_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_1_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="240"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="11" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="37" userLabel="2" customClass="UIDigitButton">
<rect key="frame" x="130" y="8" width="49" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="2"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_2_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_2_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="241"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="12" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="29" userLabel="3" customClass="UIDigitButton">
<rect key="frame" x="232" y="8" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="3"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_3_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_3_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="242"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="13" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="30" userLabel="4" customClass="UIDigitButton">
<rect key="frame" x="27" y="78" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="4"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_4_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_4_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="243"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="14" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="31" userLabel="5" customClass="UIDigitButton">
<rect key="frame" x="130" y="78" width="49" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_5_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_5_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="244"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="15" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="33" userLabel="6" customClass="UIDigitButton">
<rect key="frame" x="232" y="78" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="6"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_6_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_6_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="245"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="16" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="34" userLabel="7" customClass="UIDigitButton">
<rect key="frame" x="27" y="150" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="7"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_7_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_7_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="246"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="17" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="35" userLabel="8" customClass="UIDigitButton">
<rect key="frame" x="130" y="150" width="49" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="8"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_8_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_8_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="247"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="18" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="36" userLabel="9" customClass="UIDigitButton">
<rect key="frame" x="232" y="150" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="9"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_9_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_9_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="248"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="19" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="39" userLabel="*" customClass="UIDigitButton">
<rect key="frame" x="27" y="223" width="50" height="61"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Star"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_star_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_star_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="249"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="20" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="40" userLabel="0" customClass="UIDigitButton">
<rect key="frame" x="130" y="223" width="49" height="61"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="0"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_0_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_0_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="250"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="21" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="41" userLabel="#" customClass="UIDigitButton">
<rect key="frame" x="232" y="223" width="50" height="61"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Hash"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_hash_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_hash_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="4" id="251"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</view>
<view tag="22" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="182" userLabel="bottomBar">
<rect key="frame" x="0.0" y="370" width="310" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button hidden="YES" opaque="NO" tag="23" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="183" userLabel="backButton">
<rect key="frame" x="0.0" y="0.0" width="102" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_alt_back_default.png" backgroundImage="color_F.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_alt_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="233"/>
</connections>
</button>
<button opaque="NO" tag="24" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="222" userLabel="addContactButton">
<rect key="frame" x="0.0" y="0.0" width="102" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="contact_add_default.png" backgroundImage="color_F.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contact_add_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddContactClick:" destination="-1" eventType="touchUpInside" id="230"/>
</connections>
</button>
<button opaque="NO" tag="25" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="224" userLabel="callButton" customClass="UICallButton">
<rect key="frame" x="102" y="0.0" width="208" height="80"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_audio_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_audio_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_L.png"/>
<connections>
<outlet property="addressField" destination="4" id="235"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<button opaque="NO" tag="28" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ufj-N6-yzz" userLabel="videoCameraSwitch" customClass="UICamSwitch">
<rect key="frame" x="52" y="52" width="52" height="52"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Switch camera"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="camera_switch_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="camera_switch_disabled.png"/>
<state key="selected" image="camera_switch_over.png"/>
<state key="highlighted" image="camera_switch_over.png"/>
<connections>
<outlet property="preview" destination="30b-JN-Ibj" id="k1G-ea-6Rx"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-98.550724637681171" y="148.66071428571428"/>
</view>
<view contentMode="scaleToFill" id="bb3-7f-P2J" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="1290" height="800"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MqR-YI-CLm">
<rect key="frame" x="50" y="30" width="1240" height="770"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="1" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_D.png" translatesAutoresizingMaskIntoConstraints="NO" id="zau-s9-ek6" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="1240" height="770"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="dialer_background.png" translatesAutoresizingMaskIntoConstraints="NO" id="bV0-6N-YFL" userLabel="logoImage">
<rect key="frame" x="143" y="265" width="240" height="240"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<view tag="3" contentMode="scaleAspectFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lTn-ab-KJ5" userLabel="preview">
<rect key="frame" x="0.0" y="0.0" width="1240" height="770"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view tag="4" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PoL-pc-Siz">
<rect key="frame" x="800" y="150" width="308" height="450"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<view clipsSubviews="YES" tag="5" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bWv-bb-iGU" userLabel="dialer">
<rect key="frame" x="0.0" y="0.0" width="308" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="6" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="oRb-An-MG9" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="308" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<textField opaque="NO" clearsContextBeforeDrawing="NO" tag="7" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter a number or an address" adjustsFontSizeToFit="NO" minimumFontSize="5" translatesAutoresizingMaskIntoConstraints="NO" id="Omx-NU-xKz" userLabel="addressField" customClass="UIAddressTextField">
<rect key="frame" x="8" y="0.0" width="237" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Enter an address"/>
<fontDescription key="fontDescription" type="system" pointSize="21"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" returnKeyType="join"/>
<connections>
<action selector="onAddressChange:" destination="-1" eventType="editingChanged" id="Mrk-Jf-aVG"/>
<outlet property="delegate" destination="-1" id="I1Q-pW-WqW"/>
</connections>
</textField>
<button opaque="NO" tag="8" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Zzz-qk-9Nv" userLabel="backspaceButton" customClass="UIIconButton">
<rect key="frame" x="243" y="0.0" width="60" height="80"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<state key="normal" image="backspace_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="backspace_disabled.png"/>
<state key="highlighted" image="backspace_over.png"/>
<connections>
<action selector="onBackspaceClick:" destination="-1" eventType="touchUpInside" id="a6G-bZ-MUN"/>
</connections>
</button>
</subviews>
</view>
<view tag="9" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WVV-JM-vAB" userLabel="pad">
<rect key="frame" x="0.0" y="80" width="308" height="290"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="10" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XNH-ME-cgh" userLabel="1" customClass="UIDigitButton">
<rect key="frame" x="27" y="9" width="50" height="57"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.40000001000000002" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="1"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_1_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_1_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="fde-ao-erE"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="11" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="80y-z2-xNu" userLabel="2" customClass="UIDigitButton">
<rect key="frame" x="127" y="9" width="50" height="57"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="2"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_2_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_2_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="dgP-Dh-hKr"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="12" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2VD-Qx-3nV" userLabel="3" customClass="UIDigitButton">
<rect key="frame" x="231" y="9" width="48" height="57"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="3"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_3_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_3_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="GJu-8d-P6C"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="13" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0v7-Yf-R1e" userLabel="4" customClass="UIDigitButton">
<rect key="frame" x="27" y="74" width="50" height="62"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="4"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_4_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_4_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="LLR-dd-7Bw"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="14" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uoL-3m-hHe" userLabel="5" customClass="UIDigitButton">
<rect key="frame" x="127" y="74" width="50" height="62"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_5_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_5_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="aYv-Av-5ln"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="15" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="O8K-fk-DbU" userLabel="6" customClass="UIDigitButton">
<rect key="frame" x="231" y="74" width="48" height="62"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="6"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_6_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_6_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="18X-Wm-Y74"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="16" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bc0-Lq-cOG" userLabel="7" customClass="UIDigitButton">
<rect key="frame" x="27" y="148" width="50" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="7"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_7_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_7_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="WlQ-5m-Q74"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="17" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4qk-Qr-8je" userLabel="8" customClass="UIDigitButton">
<rect key="frame" x="127" y="148" width="50" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="8"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_8_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_8_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="Flg-0Q-Ajz"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="18" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EXT-Ir-0wP" userLabel="9" customClass="UIDigitButton">
<rect key="frame" x="231" y="148" width="48" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="9"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_9_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_9_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="HhR-xs-sWe"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="19" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="G19-A6-Rxb" userLabel="*" customClass="UIDigitButton">
<rect key="frame" x="27" y="223" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Star"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_star_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_star_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="r6k-FB-rTc"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="20" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="X2v-mg-lUX" userLabel="0" customClass="UIDigitButton">
<rect key="frame" x="127" y="223" width="50" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="0"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_0_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_0_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="5FS-Ah-Er0"/>
</connections>
</button>
<button opaque="NO" clearsContextBeforeDrawing="NO" tag="21" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Gy0-g6-fkd" userLabel="#" customClass="UIDigitButton">
<rect key="frame" x="231" y="223" width="48" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Hash"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" image="numpad_hash_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="numpad_hash_over.png" backgroundImage="numpad_over_background.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="XHz-7y-W70"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view tag="22" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uZC-xM-Vr8" userLabel="bottomBar">
<rect key="frame" x="0.0" y="370" width="308" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button hidden="YES" opaque="NO" tag="23" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NXp-Xe-hoC" userLabel="backButton">
<rect key="frame" x="0.0" y="0.0" width="101" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_alt_back_default.png" backgroundImage="color_F.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_alt_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="Spu-0j-69j"/>
</connections>
</button>
<button opaque="NO" tag="24" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J9S-Iv-omW" userLabel="addContactButton">
<rect key="frame" x="0.0" y="0.0" width="101" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="contact_add_default.png" backgroundImage="color_F.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contact_add_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddContactClick:" destination="-1" eventType="touchUpInside" id="h8a-GJ-PF6"/>
</connections>
</button>
<button opaque="NO" tag="25" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bDX-Vc-MA9" userLabel="callButton" customClass="UICallButton">
<rect key="frame" x="101" y="0.0" width="207" height="80"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_audio_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_audio_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_L.png"/>
<connections>
<outlet property="addressField" destination="Omx-NU-xKz" id="L5w-fg-hu4"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<button opaque="NO" tag="28" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jLj-JN-7LZ" userLabel="videoCameraSwitch" customClass="UICamSwitch">
<rect key="frame" x="52" y="52" width="52" height="52"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Switch camera"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="camera_switch_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="camera_switch_disabled.png"/>
<state key="selected" image="camera_switch_over.png"/>
<state key="highlighted" image="camera_switch_over.png"/>
<connections>
<outlet property="preview" destination="lTn-ab-KJ5" id="iAl-HJ-S5k"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-98.550724637681171" y="148.99553571428569"/>
</view>
</objects>
<resources>
<image name="backspace_default.png" width="58.400001525878906" height="30.399999618530273"/>
<image name="backspace_disabled.png" width="58.400001525878906" height="30.399999618530273"/>
<image name="backspace_over.png" width="58.400001525878906" height="30.399999618530273"/>
<image name="call_alt_back_default.png" width="81.599998474121094" height="58.400001525878906"/>
<image name="call_alt_back_disabled.png" width="81.599998474121094" height="58.400001525878906"/>
<image name="call_audio_start_default.png" width="58.400001525878906" height="58.400001525878906"/>
<image name="call_audio_start_disabled.png" width="58.400001525878906" height="58.400001525878906"/>
<image name="camera_switch_default.png" width="83.199996948242188" height="81.599998474121094"/>
<image name="camera_switch_disabled.png" width="83.199996948242188" height="81.599998474121094"/>
<image name="camera_switch_over.png" width="83.199996948242188" height="81.599998474121094"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_D.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="color_L.png" width="2" height="2"/>
<image name="contact_add_default.png" width="55.200000762939453" height="47.200000762939453"/>
<image name="contact_add_disabled.png" width="55.200000762939453" height="47.200000762939453"/>
<image name="dialer_background.png" width="1200" height="1030"/>
<image name="numpad_0_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_0_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_1_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_1_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_2_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_2_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_3_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_3_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_4_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_4_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_5_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_5_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_6_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_6_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_7_default.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_7_over.png" width="84.800003051757812" height="77.599998474121094"/>
<image name="numpad_8_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_8_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_9_default.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_9_over.png" width="84.800003051757812" height="79.199996948242188"/>
<image name="numpad_hash_default.png" width="84.800003051757812" height="78.400001525878906"/>
<image name="numpad_hash_over.png" width="84.800003051757812" height="78.400001525878906"/>
<image name="numpad_over_background.png" width="2" height="2"/>
<image name="numpad_star_default.png" width="84.800003051757812" height="81.599998474121094"/>
<image name="numpad_star_over.png" width="84.800003051757812" height="81.599998474121094"/>
</resources>
</document>

Binary file not shown.

View file

@ -0,0 +1,310 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="FirstLoginView">
<connections>
<outlet property="domainField" destination="w8z-ad-o8e" id="QC5-dU-UKn"/>
<outlet property="landscapeView" destination="fFD-iL-Jo0" id="RoE-70-E4p"/>
<outlet property="loginButton" destination="8H9-Gf-7ZL" id="e1g-x6-PCO"/>
<outlet property="passwordField" destination="BBC-uD-FIM" id="JEo-he-9QU"/>
<outlet property="portraitView" destination="Wa7-dw-UAu" id="cFs-v7-z1R"/>
<outlet property="usernameField" destination="vaw-qL-SCR" id="KTu-qn-3am"/>
<outlet property="view" destination="Wa7-dw-UAu" id="6r1-Cb-nOi"/>
<outlet property="waitView" destination="31" id="57"/>
</connections>
</placeholder>
<view contentMode="scaleToFill" id="Wa7-dw-UAu">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Be1-UD-ZIL" customClass="TPKeyboardAvoidingScrollView">
<rect key="frame" x="20" y="115" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="linphone_logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="JsZ-cm-gih" userLabel="logoImage">
<rect key="frame" x="20" y="46" width="93" height="93"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="left" fixedFrame="YES" text="Welcome" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="ddC-mF-O2L" userLabel="titleLabel">
<rect key="frame" x="121" y="46" width="254" height="48"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Welcome"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="33"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="4" contentMode="left" fixedFrame="YES" text="Enter your credentials" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="h9m-R1-9c4" userLabel="subtitleLabel">
<rect key="frame" x="121" y="98" width="254" height="42"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label=""/>
<fontDescription key="fontDescription" type="system" pointSize="19"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="USERNAME" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aM8-yf-s5d" userLabel="usernameLabel">
<rect key="frame" x="20" y="186" width="334" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.42667588591575623" green="0.4266631007194519" blue="0.42667034268379211" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="vaw-qL-SCR" userLabel="usernameField" customClass="UIAssistantTextField">
<rect key="frame" x="20" y="214" width="334" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Username"/>
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="next"/>
<connections>
<outlet property="delegate" destination="-1" id="Fml-De-aww"/>
<outlet property="errorLabel" destination="Ym3-AJ-VDD" id="YzJ-Uo-FtX"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" tag="7" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Invalid username" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Ym3-AJ-VDD" userLabel="usernameErrorLabel">
<rect key="frame" x="20" y="259" width="334" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="0.98594832420349121" green="0.0" blue="0.026950567960739136" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="8" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="DOMAIN" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FdB-x1-lgt" userLabel="domainLabel">
<rect key="frame" x="20" y="288" width="334" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.42667588591575623" green="0.4266631007194519" blue="0.42667034268379211" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="9" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="sip.linphone.org" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="w8z-ad-o8e" userLabel="domainField" customClass="UIAssistantTextField">
<rect key="frame" x="20" y="311" width="334" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Domain"/>
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="next"/>
<connections>
<outlet property="delegate" destination="-1" id="CgQ-c2-2d9"/>
<outlet property="errorLabel" destination="sng-3P-5z8" id="DHj-OF-TIc"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Invalid domain" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="sng-3P-5z8" userLabel="domainErrorLabel">
<rect key="frame" x="20" y="357" width="334" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="0.98594832420349121" green="0.0" blue="0.026950567960739136" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="PASSWORD" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kjU-P0-ji6" userLabel="passwordLabel">
<rect key="frame" x="20" y="386" width="334" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.42667588591575623" green="0.4266631007194519" blue="0.42667034268379211" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="12" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="BBC-uD-FIM" userLabel="passwordField" customClass="UIAssistantTextField">
<rect key="frame" x="20" y="408" width="334" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Password"/>
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
<connections>
<outlet property="delegate" destination="-1" id="e4F-kt-Udb"/>
<outlet property="errorLabel" destination="zTY-fc-a6l" id="uAR-NP-WXe"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Invalid password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="zTY-fc-a6l" userLabel="passwordErrorLabel">
<rect key="frame" x="20" y="458" width="334" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="0.98594832420349121" green="0.0" blue="0.026950567960739136" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="14" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8H9-Gf-7ZL" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="20" y="497" width="334" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Fetch and apply">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="LOGIN"/>
<connections>
<action selector="onLoginClick:" destination="-1" eventType="touchUpInside" id="BX7-xj-kmf"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</scrollView>
<view hidden="YES" clearsContextBeforeDrawing="NO" tag="16" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="31" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" tag="17" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="32" userLabel="activityIndicator">
<rect key="frame" x="189" y="428" width="37" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.66000000000000003" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="132" y="106"/>
</view>
<view contentMode="scaleToFill" id="fFD-iL-Jo0">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="i7c-YH-msu" customClass="TPKeyboardAvoidingScrollView">
<rect key="frame" x="0.0" y="260.5" width="667" height="375"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="linphone_logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="eAY-9z-N0l" userLabel="logoImage">
<rect key="frame" x="158" y="23" width="64" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="left" fixedFrame="YES" text="Welcome" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="HUU-k8-6kx" userLabel="titleLabel">
<rect key="frame" x="238" y="23" width="270" height="31"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Welcome"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="33"/>
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="4" contentMode="left" fixedFrame="YES" text="Enter your credentials" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="0qN-Jr-OXT" userLabel="subtitleLabel">
<rect key="frame" x="238" y="62" width="270" height="25"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label=""/>
<fontDescription key="fontDescription" type="system" pointSize="19"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="USERNAME" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qbs-8f-pLW" userLabel="usernameLabel">
<rect key="frame" x="158" y="105" width="350" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.42667588591575623" green="0.4266631007194519" blue="0.42667034268379211" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="0Yf-d2-ElR" userLabel="usernameField" customClass="UIAssistantTextField">
<rect key="frame" x="158" y="123" width="350" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Username"/>
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="next"/>
<connections>
<outlet property="delegate" destination="-1" id="98R-AI-m4z"/>
<outlet property="errorLabel" destination="Bgv-t3-ZGF" id="s0p-Zx-jPj"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" tag="7" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Invalid username" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Bgv-t3-ZGF" userLabel="usernameErrorLabel">
<rect key="frame" x="158" y="146" width="350" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="0.98594832420349121" green="0.0" blue="0.026950567960739136" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="8" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="DOMAIN" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1GT-Pk-UQT" userLabel="domainLabel">
<rect key="frame" x="158" y="182" width="350" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.42667588591575623" green="0.4266631007194519" blue="0.42667034268379211" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="9" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="sip.linphone.org" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="xOE-NA-3hm" userLabel="domainField" customClass="UIAssistantTextField">
<rect key="frame" x="158" y="200" width="350" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Domain"/>
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="next"/>
<connections>
<outlet property="delegate" destination="-1" id="65y-5D-Gja"/>
<outlet property="errorLabel" destination="Q6W-CO-Qyo" id="SeN-ng-mAi"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Invalid domain" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Q6W-CO-Qyo" userLabel="domainErrorLabel">
<rect key="frame" x="158" y="223" width="350" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="0.98594832420349121" green="0.0" blue="0.026950567960739136" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="PASSWORD" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3ie-wD-Jq5" userLabel="passwordLabel">
<rect key="frame" x="158" y="259" width="350" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.42667588591575623" green="0.4266631007194519" blue="0.42667034268379211" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="12" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="iFV-rZ-JMe" userLabel="passwordField" customClass="UIAssistantTextField">
<rect key="frame" x="158" y="277" width="350" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Password"/>
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
<connections>
<outlet property="delegate" destination="-1" id="EGl-fH-SOC"/>
<outlet property="errorLabel" destination="sac-b3-hPk" id="Cfh-39-Ehh"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Invalid password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="sac-b3-hPk" userLabel="passwordErrorLabel">
<rect key="frame" x="158" y="300" width="350" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<color key="textColor" red="0.98594832420349121" green="0.0" blue="0.026950567960739136" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="14" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0lR-zp-xF9" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="158" y="328" width="350" height="39"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Fetch and apply">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="LOGIN"/>
<connections>
<action selector="onLoginClick:" destination="-1" eventType="touchUpInside" id="mzP-1O-F9z"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</scrollView>
<view hidden="YES" clearsContextBeforeDrawing="NO" tag="16" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lh1-8l-fdW" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" tag="17" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="U6u-rm-UlH" userLabel="activityIndicator">
<rect key="frame" x="188.5" y="426.5" width="37" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.66000000000000003" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
</objects>
<resources>
<image name="linphone_logo.png" width="41.599998474121094" height="42.400001525878906"/>
</resources>
</document>

Binary file not shown.

View file

@ -0,0 +1,500 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_0" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<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>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="HistoryDetailsView">
<connections>
<outlet property="addContactButton" destination="50" id="52"/>
<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"/>
<outlet property="headerView" destination="33" id="iv2-Rj-j3j"/>
<outlet property="landscapeView" destination="NHC-7w-48z" id="kTJ-YT-Ejm"/>
<outlet property="linphoneImage" destination="mfN-Ai-9RX" id="Ubt-oH-lra"/>
<outlet property="optionsView" destination="k0D-99-OKO" id="5uE-lN-M3B"/>
<outlet property="portraitView" destination="4" id="0gH-12-O02"/>
<outlet property="tableView" destination="baU-d4-eu3" id="3q4-5X-yCB"/>
<outlet property="view" destination="4" id="10"/>
<outlet property="waitView" destination="dEJ-xc-518" id="ofo-cG-8s5"/>
</connections>
</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="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="-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="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="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"/>
<state key="normal" image="back_default.png"/>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="11"/>
</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="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"/>
<state key="normal" image="contact_add_default.png"/>
<state key="disabled" image="contact_add_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddContactClick:" destination="-1" eventType="touchUpInside" id="53"/>
</connections>
</button>
</subviews>
<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="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="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="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"/>
<nil key="textColor"/>
<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="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="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"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="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="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"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="Vlx-14-3CH"/>
</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="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"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="Dd5-7a-ev8"/>
</connections>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JU4-bf-tVI" userLabel="encryptedChatView">
<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="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">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onEncryptedChatClick:" destination="-1" eventType="touchUpInside" id="1Ci-9Q-eP2"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="security_toogle_icon_green.png" translatesAutoresizingMaskIntoConstraints="NO" id="YuZ-ep-Rtj" userLabel="securityImage">
<rect key="frame" x="33" y="0.0" width="19" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
</subviews>
</view>
</subviews>
<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="389" height="419"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<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="65" width="389" height="670"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<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="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="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"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="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="-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="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="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="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"/>
<state key="normal" image="back_default.png"/>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="zZF-e0-7RY"/>
</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="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"/>
<state key="normal" image="contact_add_default.png"/>
<state key="disabled" image="contact_add_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddContactClick:" destination="-1" eventType="touchUpInside" id="pow-32-7RJ"/>
</connections>
</button>
</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="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>
<outlet property="dataSource" destination="baU-d4-eu3" id="fI9-T2-u1D"/>
<outlet property="delegate" destination="baU-d4-eu3" id="xk6-7r-gBl"/>
</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="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="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"/>
<bool key="isElement" value="YES"/>
</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="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"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="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"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="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="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"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="QPr-DZ-52f"/>
</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="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"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="1Xg-su-cG3"/>
</connections>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="m90-u6-x3J" userLabel="encryptedChatView">
<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="-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">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onEncryptedChatClick:" destination="-1" eventType="touchUpInside" id="IYO-Rc-SGp"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="security_toogle_icon_green.png" translatesAutoresizingMaskIntoConstraints="NO" id="8D9-me-ZdS" userLabel="securityImage">
<rect key="frame" x="33" y="0.0" width="19" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
</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="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"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
</subviews>
<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="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"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="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="185" y="385" width="21" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="702.39999999999998" y="-45.877061469265371"/>
</view>
<tableViewController id="baU-d4-eu3" customClass="HistoryDetailsTableView">
<connections>
<outlet property="view" destination="k6N-Av-eOu" id="Dos-d4-5l5"/>
</connections>
<point key="canvasLocation" x="1316.8" y="236.58170914542731"/>
</tableViewController>
</objects>
<resources>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="call_start_body_default.png" width="82.400001525878906" height="82.400001525878906"/>
<image name="call_start_body_disabled.png" width="82.400001525878906" height="82.400001525878906"/>
<image name="call_start_body_over.png" width="82.400001525878906" height="82.400001525878906"/>
<image name="chat_start_body_default.png" width="82.400001525878906" height="82.400001525878906"/>
<image name="chat_start_body_disabled.png" width="82.400001525878906" height="82.400001525878906"/>
<image name="chat_start_body_over.png" width="82.400001525878906" height="82.400001525878906"/>
<image name="color_E.png" width="2" height="2"/>
<image name="contact_add_default.png" width="55.200000762939453" height="47.200000762939453"/>
<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">
YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05T
S2V5ZWRBcmNoaXZlctEICVRyb290gAGvEBALDBccEyEmJy4xND5GR0tOVSRudWxs1Q0ODxAREhMUFRZW
JGNsYXNzXk5TUmVzaXppbmdNb2RlXE5TSW1hZ2VGbGFnc1ZOU1JlcHNXTlNDb2xvcoAPEAASAMAAAIAC
gArSGA0ZG1pOUy5vYmplY3RzoRqAA4AJ0hgNHSCiHh+ABIAFgAjTDSIjJCUTXxAUTlNUSUZGUmVwcmVz
ZW50YXRpb25fEBlOU0ludGVybmFsTGF5b3V0RGlyZWN0aW9ugAeABk8RAj5NTQAqAAAADOHh4eEADwEA
AAMAAAABAAIAAAEBAAMAAAABAAIAAAECAAMAAAABAAgAAAEDAAMAAAABAAEAAAEGAAMAAAABAAEAAAEK
AAMAAAABAAEAAAERAAQAAAABAAAACAESAAMAAAABAAEAAAEVAAMAAAABAAEAAAEWAAMAAAABAAIAAAEX
AAQAAAABAAAABAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFTAAMAAAABAAEAAIdzAAcAAAF4AAAAxgAA
AAAAAAF4YXBwbAIQAABtbnRyR1JBWVhZWiAH1QAHAAEAAAAAAABhY3NwQVBQTAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAARkZXNjAAAAtAAAAHVjcHJ0AAABLAAAACd3dHB0AAABVAAAABRrVFJDAAABaAAA
AA5kZXNjAAAAAAAAABtDYWxpYnJhdGVkIEdyYXkgQ29sb3JzcGFjZQAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
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>

Binary file not shown.

View file

@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" 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="19454"/>
<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="HistoryListView">
<connections>
<outlet property="allButton" destination="4" id="27"/>
<outlet property="conferenceButton" destination="VWZ-Nd-W2s" id="wy8-oW-FqP"/>
<outlet property="missedButton" destination="5" id="28"/>
<outlet property="selectedButtonImage" destination="o8E-gw-vhI" id="hNf-FA-7aQ"/>
<outlet property="tableController" destination="18" id="26"/>
<outlet property="toggleSelectionButton" destination="nhN-oH-LQ9" id="pE7-Y3-aT3"/>
<outlet property="view" destination="2" id="16"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="o8E-Bz-RWL" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="38" userLabel="switchView">
<rect key="frame" x="0.0" y="0.0" width="225" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4" userLabel="allButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="All contacts filter"/>
<inset key="titleEdgeInsets" minX="0.0" minY="16" maxX="0.0" maxY="0.0"/>
<state key="normal" image="history_all_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="history_all_disabled.png"/>
<state key="selected" image="history_all_selected.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAllClick:" destination="-1" eventType="touchUpInside" id="29"/>
</connections>
</button>
<button opaque="NO" contentMode="bottom" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5" userLabel="missedButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="75" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Missed contacts filter"/>
<state key="normal" image="history_missed_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="history_missed_disabled.png"/>
<state key="selected" image="history_missed_selected.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onMissedClick:" destination="-1" eventType="touchUpInside" id="30"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleAspectFit" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VWZ-Nd-W2s" userLabel="conferenceButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="150" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Missed contacts filter"/>
<inset key="imageEdgeInsets" minX="10" minY="5" maxX="10" maxY="5"/>
<state key="normal" image="voip_conference_new.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="history_missed_disabled.png"/>
<state key="selected" image="voip_conference_new_selected.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onConferenceClick:" destination="-1" eventType="touchUpInside" id="9hJ-lr-NB7"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="o8E-gw-vhI" userLabel="selectedButtonImage">
<rect key="frame" x="0.0" y="63" width="75" height="3"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
</imageView>
</subviews>
</view>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="00K-MU-NUc" userLabel="cancelButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="18" eventType="touchUpInside" id="DAX-W6-l0H"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="WQf-rB-DUt"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nhN-oH-LQ9" userLabel="toggleSelectionButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onSelectionToggle:" destination="18" eventType="touchUpInside" id="ADr-KR-SmA"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="35" userLabel="deleteButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="300" y="0.0" width="75" 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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="37"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6" userLabel="editButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="18" eventType="touchUpInside" id="5Ft-HW-cVh"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="9gC-6R-w0j"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="35" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="17" userLabel="tableView">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outlet property="dataSource" destination="18" id="23"/>
<outlet property="delegate" destination="18" id="24"/>
</connections>
</tableView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No call in your history" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xtr-Fp-60Z" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="355.79710144927537" y="250.11160714285714"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="18" userLabel="tableController" customClass="HistoryListTableView">
<extendedEdge key="edgesForExtendedLayout"/>
<connections>
<outlet property="cancelButton" destination="00K-MU-NUc" id="KSi-MC-Usk"/>
<outlet property="deleteButton" destination="35" id="n8o-lE-u1t"/>
<outlet property="editButton" destination="6" id="Sgc-Z3-NeQ"/>
<outlet property="emptyView" destination="xtr-Fp-60Z" id="hgd-7A-cLI"/>
<outlet property="toggleSelectionButton" destination="nhN-oH-LQ9" id="77r-l0-3Yi"/>
<outlet property="view" destination="17" id="25"/>
</connections>
<point key="canvasLocation" x="863.768115942029" y="204.24107142857142"/>
</tableViewController>
</objects>
<resources>
<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="color_A.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="history_all_default.png" width="52.799999237060547" height="51.200000762939453"/>
<image name="history_all_disabled.png" width="52.799999237060547" height="51.200000762939453"/>
<image name="history_all_selected.png" width="52.799999237060547" height="51.200000762939453"/>
<image name="history_missed_default.png" width="52.799999237060547" height="52.799999237060547"/>
<image name="history_missed_disabled.png" width="52.799999237060547" height="52.799999237060547"/>
<image name="history_missed_selected.png" width="52.799999237060547" height="52.799999237060547"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="voip_conference_new.png" width="97.599998474121094" height="97.599998474121094"/>
<image name="voip_conference_new_selected.png" width="97.599998474121094" height="97.599998474121094"/>
<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>

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,64 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ImageView">
<connections>
<outlet property="backButton" destination="RW1-kp-wn7" id="DJc-Ps-J3p"/>
<outlet property="scrollView" destination="12" id="13"/>
<outlet property="view" destination="1" id="3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="zEp-6r-r9n" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<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="414" height="788"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2E4-s5-jYL" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RW1-kp-wn7" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="New Discussion"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="vyb-kn-xSQ"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" minimumZoomScale="0.0" maximumZoomScale="10" translatesAutoresizingMaskIntoConstraints="NO" id="12" userLabel="scrollView" customClass="UIImageScrollView">
<rect key="frame" x="0.0" y="66" width="414" height="722"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</scrollView>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="132" y="110"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
</resources>
</document>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,48 @@
<?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">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PhoneMainView">
<connections>
<outlet property="mainViewController" destination="208" id="209"/>
<outlet property="statusBarBG" destination="6sv-JD-j8Z" id="CCl-1v-2B7"/>
<outlet property="view" destination="152" id="WV3-Jd-QMD"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="Po9-aN-gz9" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="152">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="avX-6g-QDq" userLabel="background">
<rect key="frame" x="0.0" y="0.0" width="375" height="559"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6sv-JD-j8Z" userLabel="statusBarBG">
<rect key="frame" x="0.0" y="0.0" width="375" height="35"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="47.10144927536232" y="57.924107142857139"/>
</view>
<viewController nibName="UICompositeView" wantsFullScreenLayout="YES" id="208" userLabel="mainViewController" customClass="UICompositeView">
<extendedEdge key="edgesForExtendedLayout"/>
<nil key="simulatedStatusBarMetrics"/>
</viewController>
</objects>
</document>

View file

@ -0,0 +1,167 @@
<?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" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RecordingsListView">
<connections>
<outlet property="backButton" destination="rAc-tI-AVp" id="CVb-Cy-yWP"/>
<outlet property="deleteButton" destination="zDs-pW-vyA" id="mye-fK-RaT"/>
<outlet property="tableController" destination="1pR-qo-CIP" id="FD0-NI-8ox"/>
<outlet property="toggleSelectionButton" destination="16S-9G-2cb" id="D22-yK-HPS"/>
<outlet property="topBar" destination="See-Aw-LPP" id="daF-pK-NHy"/>
<outlet property="videoView" destination="5gX-xE-my9" id="I5t-Ex-N4v"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="See-Aw-LPP" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CqG-tB-maQ" userLabel="cancelButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onCancelClick:" destination="1pR-qo-CIP" eventType="touchUpInside" id="qcZ-s6-jgK"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="vly-0H-4W2"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zDs-pW-vyA" userLabel="deleteButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" 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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="8LI-ry-dTU"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CWx-9g-0JG" userLabel="editButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="331" y="0.0" width="83" height="66"/>
<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"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="1pR-qo-CIP" eventType="touchUpInside" id="0LH-n9-p0c"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="IeY-Yd-XP2"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="16S-9G-2cb" userLabel="toggleSelectionButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="248" y="0.0" width="83" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onSelectionToggle:" destination="1pR-qo-CIP" eventType="touchUpInside" id="Hfi-f6-qfI"/>
</connections>
</button>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rAc-tI-AVp" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" 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"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleColor" red="0.28619974850000002" green="0.3214434981" blue="0.3598001301" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackPressed:" destination="-1" eventType="touchUpInside" id="Quz-zf-q3K"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="3b0-Nd-4r0">
<rect key="frame" x="0.0" y="74" width="414" height="822"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<connections>
<outlet property="dataSource" destination="1pR-qo-CIP" id="z2V-Yd-AwQ"/>
<outlet property="delegate" destination="1pR-qo-CIP" id="eJQ-AV-7ts"/>
</connections>
</tableView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No recording found" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zXd-Ic-rwm" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="74" width="414" height="822"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5gX-xE-my9">
<rect key="frame" x="136" y="575" width="278" height="321"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="Q5M-cg-NOt"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<point key="canvasLocation" x="24.637681159420293" y="50.892857142857139"/>
</view>
<tableViewController id="1pR-qo-CIP" customClass="RecordingsListTableView">
<connections>
<outlet property="cancelButton" destination="CqG-tB-maQ" id="C90-0S-5WL"/>
<outlet property="deleteButton" destination="zDs-pW-vyA" id="mgV-PB-law"/>
<outlet property="editButton" destination="CWx-9g-0JG" id="hAA-6f-kX8"/>
<outlet property="emptyView" destination="zXd-Ic-rwm" id="D4k-nO-LKW"/>
<outlet property="toggleSelectionButton" destination="16S-9G-2cb" id="6pj-Yn-hy1"/>
<outlet property="view" destination="3b0-Nd-4r0" id="ng8-q5-bwm"/>
</connections>
<point key="canvasLocation" x="478" y="52"/>
</tableViewController>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<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="color_E.png" width="2" height="2"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
<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>

Binary file not shown.

View file

@ -0,0 +1,86 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SettingsView">
<connections>
<outlet property="backButton" destination="gTj-vM-UtG" id="RTt-uX-4Lf"/>
<outlet property="navigationController" destination="10" id="15"/>
<outlet property="settingsController" destination="6" id="8"/>
<outlet property="subView" destination="Qjf-HX-coQ" id="f2I-hh-aOI"/>
<outlet property="titleLabel" destination="SqM-h2-idp" id="shs-j2-U5I"/>
<outlet property="view" destination="4" id="9"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="20" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
<rect key="frame" x="0.0" y="42" width="414" height="791"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SRV-nz-KWT" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="SETTINGS" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SqM-h2-idp" userLabel="titleLabel">
<rect key="frame" x="92" y="0.0" width="230" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gTj-vM-UtG" userLabel="backButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="91" height="66"/>
<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"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="0PT-42-Pyi"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qjf-HX-coQ" userLabel="subView">
<rect key="frame" x="0.0" y="66" width="414" height="725"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-61.594202898550726" y="175.11160714285714"/>
</view>
<navigationController definesPresentationContext="YES" navigationBarHidden="YES" id="10" userLabel="navigationController" customClass="UINavigationControllerEx">
<extendedEdge key="edgesForExtendedLayout"/>
<nil key="simulatedStatusBarMetrics"/>
<nil key="simulatedTopBarMetrics"/>
<navigationBar key="navigationBar" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" barStyle="black" translucent="NO" id="11" userLabel="navigationBar" customClass="UINavigationBarEx">
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
</navigationController>
<viewController autoresizesArchivedViewToFullSize="NO" id="6" userLabel="settingsController" customClass="IASKAppSettingsViewControllerEx">
<extendedEdge key="edgesForExtendedLayout"/>
<navigationItem key="navigationItem" id="14" userLabel="settingsItem"/>
</viewController>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
</resources>
</document>

Binary file not shown.

View file

@ -0,0 +1,93 @@
<?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">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ShopView">
<connections>
<outlet property="tableViewController" destination="sBe-ML-IzT" id="8zr-PW-7c4"/>
<outlet property="view" destination="HJH-1o-RXN" id="AhB-ik-484"/>
<outlet property="waitingView" destination="tuB-rE-DiO" id="1cH-Ht-tQE"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="eP3-Qs-BZl" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="299" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HJH-1o-RXN">
<rect key="frame" x="0.0" y="66" width="414" height="830"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.90000000000000002" tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Whz-oo-Pwx" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ETk-tB-ZNl" userLabel="dialerBackButton" customClass="UIInterfaceStyleButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="IrL-W4-g5z"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="SHOP" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iNt-9d-7si" userLabel="titleLabel">
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" bounces="NO" style="plain" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="cnd-cB-B4W">
<rect key="frame" x="0.0" y="66" width="414" height="764"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<connections>
<outlet property="dataSource" destination="sBe-ML-IzT" id="EPO-Za-dkU"/>
<outlet property="delegate" destination="sBe-ML-IzT" id="T0H-aj-0UQ"/>
</connections>
</tableView>
<view hidden="YES" tag="288" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tuB-rE-DiO" userLabel="waitView">
<rect key="frame" x="0.0" y="66" width="414" height="797"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" fixedFrame="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="7Jb-oC-FC5" userLabel="activityIndicatorView">
<rect key="frame" x="199" y="387" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-600.72463768115949" y="-494.53125"/>
</view>
<tableViewController id="sBe-ML-IzT" customClass="ShopTableView">
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
<connections>
<outlet property="view" destination="cnd-cB-B4W" id="hcK-9Y-fd5"/>
</connections>
<point key="canvasLocation" x="49.275362318840585" y="-484.82142857142856"/>
</tableViewController>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
</resources>
</document>

Binary file not shown.

View file

@ -0,0 +1,128 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SideMenuView">
<connections>
<outlet property="addressLabel" destination="V8A-tK-4iV" id="YMm-ry-yJa"/>
<outlet property="avatarImage" destination="BNQ-7N-NGT" id="LXr-Yr-zSK"/>
<outlet property="grayBackground" destination="ccB-VK-LF9" id="Rbz-Ix-k62"/>
<outlet property="nameLabel" destination="XbU-2B-u1b" id="rKF-4e-1HA"/>
<outlet property="presenceImage" destination="C88-Ag-nm7" id="LH2-Mq-xLz"/>
<outlet property="sideMenuTableViewController" destination="Yyh-z6-IGO" id="6Xq-OQ-vYm"/>
<outlet property="swipeGestureRecognizer" destination="JRs-i1-zCl" id="YA3-UP-6Dc"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<swipeGestureRecognizer direction="left" id="JRs-i1-zCl" userLabel="OnLateralSwipe">
<connections>
<action selector="onLateralSwipe:" destination="-1" id="5td-pZ-6Vc"/>
<outlet property="delegate" destination="-1" id="yhK-9x-aT0"/>
</connections>
</swipeGestureRecognizer>
<view contentMode="scaleToFill" id="82U-ej-eJb" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="42" width="414" height="854"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view hidden="YES" alpha="0.69999999999999996" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ccB-VK-LF9">
<rect key="frame" x="0.0" y="0.0" width="414" height="854"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outletCollection property="gestureRecognizers" destination="56h-cQ-B5V" appends="YES" id="umX-R7-2IR"/>
</connections>
</view>
<view alpha="0.90000000000000002" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="i1P-cG-q8h" userLabel="headerView">
<rect key="frame" x="0.0" y="0.0" width="300" height="100"/>
<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" minimumFontSize="19" translatesAutoresizingMaskIntoConstraints="NO" id="XbU-2B-u1b" userLabel="nameLabel">
<rect key="frame" x="76" y="15" width="224" height="31"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="25"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="john.doe@sip.linphone.org" lineBreakMode="middleTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="V8A-tK-4iV" userLabel="addressLabel">
<rect key="frame" x="76" y="54" width="208" height="38"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="led_connected.png" translatesAutoresizingMaskIntoConstraints="NO" id="C88-Ag-nm7" userLabel="presenceImage">
<rect key="frame" x="284" y="58" width="16" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="BNQ-7N-NGT" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="3" y="15" width="68" height="77"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<connections>
<outletCollection property="gestureRecognizers" destination="Kej-uL-ntg" appends="YES" id="eog-XV-xok"/>
</connections>
</imageView>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
<connections>
<outletCollection property="gestureRecognizers" destination="1kD-az-BAx" appends="YES" id="OGc-fj-HQy"/>
</connections>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" bounces="NO" style="plain" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Ttt-1k-jAm">
<rect key="frame" x="0.0" y="100" width="300" height="754"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<connections>
<outlet property="dataSource" destination="Yyh-z6-IGO" id="ytx-b8-NGX"/>
<outlet property="delegate" destination="Yyh-z6-IGO" id="c1j-vG-TbB"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
<connections>
<outletCollection property="gestureRecognizers" destination="JRs-i1-zCl" appends="YES" id="SPs-Nb-Y0e"/>
</connections>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="467.39130434782612" y="140.29017857142856"/>
</view>
<tableViewController id="Yyh-z6-IGO" customClass="SideMenuTableView">
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
<connections>
<outlet property="view" destination="Ttt-1k-jAm" id="Njc-lf-vXv"/>
</connections>
<point key="canvasLocation" x="1181.1594202898552" y="129.91071428571428"/>
</tableViewController>
<tapGestureRecognizer id="Kej-uL-ntg" userLabel="OnAvatarClicked">
<connections>
<action selector="onAvatarClick:" destination="-1" id="KyX-RA-m6A"/>
</connections>
</tapGestureRecognizer>
<tapGestureRecognizer id="1kD-az-BAx" userLabel="OnHeaderClicked">
<connections>
<action selector="onHeaderClick:" destination="-1" id="yqn-58-lbb"/>
</connections>
</tapGestureRecognizer>
<tapGestureRecognizer id="56h-cQ-B5V" userLabel="onBackgroundClicked">
<connections>
<action selector="onBackgroundClicked:" destination="-1" id="U5P-C2-4FD"/>
</connections>
</tapGestureRecognizer>
</objects>
<resources>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="led_connected.png" width="19.200000762939453" height="19.200000762939453"/>
</resources>
</document>

Binary file not shown.

View file

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SideMenuView">
<connections>
<outlet property="addressLabel" destination="ypg-P8-Els" id="gRv-Fz-Dbk"/>
<outlet property="avatarImage" destination="BNQ-7N-NGT" id="LXr-Yr-zSK"/>
<outlet property="grayBackground" destination="ccB-VK-LF9" id="Rbz-Ix-k62"/>
<outlet property="nameLabel" destination="XbU-2B-u1b" id="rKF-4e-1HA"/>
<outlet property="presenceImage" destination="tNM-uE-Eum" id="dfy-Sb-hgE"/>
<outlet property="sideMenuTableViewController" destination="Yyh-z6-IGO" id="6Xq-OQ-vYm"/>
<outlet property="swipeGestureRecognizer" destination="JRs-i1-zCl" id="YA3-UP-6Dc"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<swipeGestureRecognizer direction="left" id="JRs-i1-zCl" userLabel="OnLateralSwipe">
<connections>
<action selector="onLateralSwipe:" destination="-1" id="5td-pZ-6Vc"/>
<outlet property="delegate" destination="-1" id="yhK-9x-aT0"/>
</connections>
</swipeGestureRecognizer>
<view contentMode="scaleToFill" id="82U-ej-eJb" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="42" width="375" height="625"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view hidden="YES" alpha="0.80000000000000004" contentMode="scaleToFill" id="ccB-VK-LF9">
<rect key="frame" x="0.0" y="0.0" width="375" height="625"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outletCollection property="gestureRecognizers" destination="56h-cQ-B5V" appends="YES" id="umX-R7-2IR"/>
</connections>
</view>
<view contentMode="scaleToFill" id="i1P-cG-q8h" userLabel="headerView">
<rect key="frame" x="0.0" y="0.0" width="187" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="90B-Re-hmt" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="187" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="19" id="XbU-2B-u1b" userLabel="nameLabel">
<rect key="frame" x="76" y="15" width="111" height="31"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="25"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@sip.linphone.org" lineBreakMode="middleTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="ypg-P8-Els" userLabel="addressLabel">
<rect key="frame" x="74" y="54" width="95" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="led_connected.png" id="tNM-uE-Eum" userLabel="presenceImage">
<rect key="frame" x="169" y="54" width="16" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar.png" id="BNQ-7N-NGT" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="8" y="20" width="60" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<connections>
<outletCollection property="gestureRecognizers" destination="Kej-uL-ntg" appends="YES" id="eog-XV-xok"/>
</connections>
</imageView>
</subviews>
<gestureRecognizers/>
<connections>
<outletCollection property="gestureRecognizers" destination="1kD-az-BAx" appends="YES" id="OGc-fj-HQy"/>
</connections>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" bounces="NO" style="plain" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="Ttt-1k-jAm">
<rect key="frame" x="0.0" y="100" width="187" height="525"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="dataSource" destination="Yyh-z6-IGO" id="ytx-b8-NGX"/>
<outlet property="delegate" destination="Yyh-z6-IGO" id="c1j-vG-TbB"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<gestureRecognizers/>
<connections>
<outletCollection property="gestureRecognizers" destination="JRs-i1-zCl" appends="YES" id="SPs-Nb-Y0e"/>
</connections>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="322.5" y="209.5"/>
</view>
<tableViewController id="Yyh-z6-IGO" customClass="SideMenuTableView">
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics"/>
<connections>
<outlet property="view" destination="Ttt-1k-jAm" id="Njc-lf-vXv"/>
</connections>
<point key="canvasLocation" x="815" y="194"/>
</tableViewController>
<tapGestureRecognizer id="Kej-uL-ntg" userLabel="OnAvatarClicked">
<connections>
<action selector="onAvatarClick:" destination="-1" id="KyX-RA-m6A"/>
</connections>
</tapGestureRecognizer>
<tapGestureRecognizer id="1kD-az-BAx" userLabel="OnHeaderClicked">
<connections>
<action selector="onHeaderClick:" destination="-1" id="yqn-58-lbb"/>
</connections>
</tapGestureRecognizer>
<tapGestureRecognizer id="56h-cQ-B5V" userLabel="onBackgroundClicked">
<connections>
<action selector="onBackgroundClicked:" destination="-1" id="U5P-C2-4FD"/>
</connections>
</tapGestureRecognizer>
</objects>
<resources>
<image name="avatar.png" width="255" height="255"/>
<image name="color_F.png" width="2" height="2"/>
<image name="led_connected.png" width="11" height="11"/>
</resources>
</document>

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
@interface ChatConversationCreateCollectionViewController : UICollectionViewController
@end

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "ChatConversationCreateCollectionViewController.h"
@interface ChatConversationCreateCollectionViewController ()
@end
@implementation ChatConversationCreateCollectionViewController
static NSString * const reuseIdentifier = @"Cell";
- (void)viewDidLoad {
[super viewDidLoad];
// Register cell classes
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
@interface ChatConversationCreateTableView : UITableViewController <UISearchBarDelegate>
@property(nonatomic) Boolean allFilter;
@property(nonatomic) Boolean notFirstTime;
@property(nonatomic) Boolean reloadMagicSearch;
@property(nonatomic, strong) NSMutableArray *contactsGroup;
@property(weak, nonatomic) IBOutlet UISearchBar *searchBar;
@property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@property (weak, nonatomic) IBOutlet UIButton *controllerNextButton;
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property (weak, nonatomic) IBOutlet UIView *loadingView;
@property(nonatomic) Boolean isForEditing;
@property(nonatomic) Boolean isGroupChat;
@property(nonatomic) Boolean isEncrypted;
- (void) loadData;
@end

View file

@ -0,0 +1,362 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "linphoneapp-Swift.h"
#import "ChatConversationCreateTableView.h"
#import "UIChatCreateCell.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "UIChatCreateCollectionViewCell.h"
@interface ChatConversationCreateTableView ()
@property(nonatomic, strong) NSMutableArray *addresses;
@property(nonatomic, strong) NSMutableArray *phoneOrAddr;
@property(nonatomic, strong) NSMutableArray *addressesCached;
@property(readonly, nonatomic) NSMutableDictionary *ldapAndProvisioningContactAddressBookMap;
@end
@implementation ChatConversationCreateTableView
- (void)viewWillAppear:(BOOL)animated {
if (!_ldapAndProvisioningContactAddressBookMap) {
_ldapAndProvisioningContactAddressBookMap = [NSMutableDictionary dictionary];
}
[super viewWillAppear:animated];
int y = _contactsGroup.count > 0
? _collectionView.frame.origin.y + _collectionView.frame.size.height
: _searchBar.frame.origin.y + _searchBar.frame.size.height;
[UIView animateWithDuration:0
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self.tableView setFrame:CGRectMake(self.tableView.frame.origin.x,
y,
self.tableView.frame.size.width,
_waitView.frame.size.height - _waitView.frame.origin.y - y)];
}
completion:nil];
_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];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onChatMagicSearchStarted:)
name:kLinphoneMagicSearchStarted
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onChatMagicSearchFinished:)
name:kLinphoneMagicSearchFinished
object:nil];
if(_notFirstTime) {
for(NSString *addr in _contactsGroup) {
[_collectionView registerClass:UIChatCreateCollectionViewCell.class forCellWithReuseIdentifier:addr];
}
[self searchBar:_searchBar textDidChange:_searchBar.text];
return;
}
_contactsGroup = [[NSMutableArray alloc] init];
[_searchBar setText:@""];
[self searchBar:_searchBar textDidChange:_searchBar.text];
self.tableView.accessibilityIdentifier = @"Suggested addresses";
}
- (void) viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
_notFirstTime = FALSE;
}
- (void)onChatMagicSearchStarted:(NSNotification *)k {
_loadingView.hidden = FALSE;
}
- (void)onChatMagicSearchFinished:(NSNotification *)k {
[self buildChatContactTable];
_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 *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]) {
continue;
}
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 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) {
continue;
}
if (account) {
char *normalizedPhoneNumber = linphone_account_normalize_phone_number(account, phoneNumber);
if (!normalizedPhoneNumber) {
// get invalid phone number, continue
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 setCreatedFromLdapOrProvisioning:TRUE];
[_ldapAndProvisioningContactAddressBookMap setObject:contact forKey:address];
linphone_address_unref(addr);
}
}
if (uri) ms_free(uri);
if (!addr) {
continue;
}
[_addresses addObject:address];
[_phoneOrAddr addObject:phoneNumber ? [NSString stringWithUTF8String:phoneNumber] : address];
[_addressesCached addObject:[NSString stringWithFormat:@"%d",linphone_search_result_get_capabilities(result)]];
}
bctbx_list_free(result_list);
[self.tableView reloadData];
_reloadMagicSearch = FALSE;
}
- (void) loadData {
[self reloadDataWithFilter:_searchBar.text];
}
- (void)reloadDataWithFilter:(NSString *)filter {
[_addresses removeAllObjects];
[_phoneOrAddr removeAllObjects];
[_addressesCached removeAllObjects];
[_ldapAndProvisioningContactAddressBookMap removeAllObjects];
[self.tableView reloadData];
_reloadMagicSearch = _reloadMagicSearch || [filter length]==0 || ![[MagicSearchSingleton.instance currentFilter] isEqualToString:filter];
[MagicSearchSingleton.instance setCurrentFilter:filter];
if (_reloadMagicSearch) {
[MagicSearchSingleton.instance searchForContactsWithDomain:_allFilter ? @"" : @"*" sourceFlags:LinphoneMagicSearchSourceAll clearCache:FALSE];
} else {
[self buildChatContactTable];
}
}
#pragma mark - TableView methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _addresses.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
return 60.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *kCellId = NSStringFromClass(UIChatCreateCell.class);
UIChatCreateCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil)
cell = [[UIChatCreateCell alloc] initWithIdentifier:kCellId];
NSString *key = [_addresses objectAtIndex:indexPath.row];
NSString *phoneOrAddr = [_phoneOrAddr objectAtIndex:indexPath.row];
Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:key use_prefix:[CallManager.instance applyInternationalPrefix]]];
if (!contact) {
contact = [_ldapAndProvisioningContactAddressBookMap objectForKey:key];
}
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];
if (!addr)
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 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.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;
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];
if (!addr) {
LOGE(@"Chat room could not be created on server, because null address.");
[ChatConversationInfoView displayCreationError];
} else {
linphone_address_unref(addr);
}
return;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSInteger index = 0;
if(cell.selectedImage.hidden) {
if(![_contactsGroup containsObject:cell.addressLabel.text]) {
[_contactsGroup addObject:cell.addressLabel.text];
[_collectionView registerClass:UIChatCreateCollectionViewCell.class forCellWithReuseIdentifier:cell.addressLabel.text];
}
} else if([_contactsGroup containsObject:cell.addressLabel.text]) {
index = (NSInteger)[_contactsGroup indexOfObject:cell.addressLabel.text];
[_contactsGroup removeObject:cell.addressLabel.text];
if(index == _contactsGroup.count)
index = index-1;
}
cell.selectedImage.hidden = !cell.selectedImage.hidden;
_controllerNextButton.enabled = (_contactsGroup.count > 0) || _isForEditing;
if (_contactsGroup.count > 1 || (_contactsGroup.count == 1 && cell.selectedImage.hidden)) {
[UIView animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[tableView setFrame:CGRectMake(tableView.frame.origin.x,
_collectionView.frame.origin.y + _collectionView.frame.size.height,
tableView.frame.size.width,
tableView.frame.size.height)];
}
completion:nil];
} else if (_contactsGroup.count == 1 && !cell.selectedImage.hidden) {
[UIView animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[tableView setFrame:CGRectMake(tableView.frame.origin.x,
_collectionView.frame.origin.y + _collectionView.frame.size.height,
tableView.frame.size.width,
tableView.frame.size.height - _collectionView.frame.size.height)];
}
completion:nil];
} else {
[UIView animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[tableView setFrame:CGRectMake(tableView.frame.origin.x,
_searchBar.frame.origin.y + _searchBar.frame.size.height,
tableView.frame.size.width,
tableView.frame.size.height + _collectionView.frame.size.height)];
}
completion:nil];
}
[_collectionView reloadData];
if (!cell.selectedImage.hidden) {
index = _contactsGroup.count - 1;
}
dispatch_async(dispatch_get_main_queue(), ^{
if(index > 0) {
NSIndexPath *path = [NSIndexPath indexPathForItem:index inSection:0];
[_collectionView scrollToItemAtIndexPath:path
atScrollPosition:(UICollectionViewScrollPositionCenteredHorizontally | UICollectionViewScrollPositionCenteredVertically)
animated:YES];
}
});
}
#pragma mark - Searchbar delegates
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
searchBar.showsCancelButton = (searchText.length > 0);
[self reloadDataWithFilter:searchText];
if ([searchText isEqualToString:@""]) {
[_searchBar resignFirstResponder];
}
}
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(nonnull NSString *)text {
return TRUE;
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:FALSE animated:TRUE];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:(searchBar.text.length > 0) animated:TRUE];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
@end

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ChatConversationCreateView_h
#define ChatConversationCreateView_h
#import <UIKit/UIKit.h>
#import "ChatConversationCreateTableView.h"
#import "ChatConversationCreateCollectionViewController.h"
#import "UICompositeView.h"
@interface ChatConversationCreateView : UIViewController <UICompositeViewDelegate, UIGestureRecognizerDelegate, UICollectionViewDataSource>
@property(strong, nonatomic) IBOutlet ChatConversationCreateTableView *tableController;
@property(strong, nonatomic) IBOutlet ChatConversationCreateCollectionViewController *collectionController;
@property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@property (weak, nonatomic) IBOutlet UIButton *backButton;
@property (weak, nonatomic) IBOutlet UIButton *nextButton;
@property (weak, nonatomic) IBOutlet UIButton *allButton;
@property (weak, nonatomic) IBOutlet UIButton *linphoneButton;
@property (weak, nonatomic) IBOutlet UIImageView *selectedButtonImage;
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property (weak, nonatomic) IBOutlet UIView *chiffreOptionView;
@property (weak, nonatomic) IBOutlet UIView *switchView;
@property (weak, nonatomic) IBOutlet UIImageView *chiffreImage;
@property (weak, nonatomic) IBOutlet UIButton *chiffreButton;
@property (weak, nonatomic) IBOutlet UIView *topBar;
@property(nonatomic) Boolean isForEditing;
@property(nonatomic) Boolean isGroupChat;
@property(nonatomic) Boolean isEncrypted;
@property(nonatomic) Boolean isForVoipConference;
@property(nonatomic) Boolean isForOngoingVoipConference;
@property (weak, nonatomic) IBOutlet UILabel *voipTitle;
- (IBAction)onBackClick:(id)sender;
- (IBAction)onNextClick:(id)sender;
- (IBAction)onChiffreClick:(id)sender;
-(void) unfragmentCompositeDescription;
-(void) fragmentCompositeDescription;
@end
#endif /* ChatConversationCreateView_h */

View file

@ -0,0 +1,338 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "ChatConversationCreateView.h"
#import "PhoneMainView.h"
#import "UIChatCreateCollectionViewCell.h"
#import "linphoneapp-Swift.h"
@implementation ChatConversationCreateView
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:TabBarView.class
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:NO
fragmentWith:ChatsListView.class];
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
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]
initWithTarget:self
action:@selector(dismissKeyboards)];
tap.delegate = self;
[self.view addGestureRecognizer:tap];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize;
_collectionController.collectionView = _collectionView;
_collectionController = (ChatConversationCreateCollectionViewController *)[[UICollectionViewController alloc] initWithCollectionViewLayout:layout];
_collectionView.dataSource = self;
[_collectionView setCollectionViewLayout:layout];
_tableController.collectionView = _collectionView;
_tableController.controllerNextButton = _nextButton;
_isForEditing = FALSE;
_voipTitle.text = VoipTexts.call_action_participants_list;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self viewUpdateEvent:nil];
if (IPAD)
[NSNotificationCenter.defaultCenter addObserver:self
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"]) {
self.linphoneButton.hidden = TRUE;
self.selectedButtonImage.hidden = TRUE;
CGRect frame = _allButton.frame;
frame.origin.x = _linphoneButton.frame.origin.x;
_allButton.frame = frame;
}
if ([LinphoneManager.instance lpConfigBoolForKey:@"force_lime_chat_rooms"]) {
_chiffreOptionView.hidden = true;
_isEncrypted = true;
_tableController.isEncrypted = true;
_allButton.hidden = true;
_linphoneButton.hidden = true;
_selectedButtonImage.hidden = true;
}
if (_isForVoipConference) {
_switchView.hidden = true;
_chiffreOptionView.hidden = true;
_voipTitle.hidden = false;
if (_isForOngoingVoipConference) {
[_nextButton setImage:[UIImage imageNamed:@"valid_default"] forState:UIControlStateNormal];
} else {
[_nextButton setImage:[UIImage imageNamed:@"next_default"] forState:UIControlStateNormal];
}
} else {
_voipTitle.hidden = true;
[_nextButton setImage:[UIImage imageNamed:@"next_default"] forState:UIControlStateNormal];
}
[self displayModeChanged];
}
- (void)displayModeChanged{
[self.tableController.tableView reloadData];
if (_isForVoipConference) {
_topBar.backgroundColor = [VoipTheme.voipToolbarBackgroundColor get];
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 {
_topBar.backgroundColor = UIColor.secondarySystemBackgroundColor;
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 {
CGRect frame = _chiffreOptionView.frame;
if (_isGroupChat) {
_nextButton.hidden = FALSE;
_switchView.hidden = TRUE;
frame.origin.x = (self.view.frame.size.width - _chiffreOptionView.frame.size.width)/2;
} else {
_nextButton.hidden = TRUE;
_switchView.hidden = FALSE;
frame.origin.x = self.view.frame.size.width * 0.192;
}
_chiffreOptionView.frame = frame;
_isEncrypted = [LinphoneManager.instance lpConfigBoolForKey:@"force_lime_chat_rooms"]; // false by default
CGRect buttonFrame = _chiffreButton.frame;
if (!_isEncrypted) {
buttonFrame.origin.x = 2;
[_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_grey.png"]];
_chiffreButton.frame = buttonFrame;
}
_waitView.hidden = YES;
_backButton.hidden = IPAD && !(_isForVoipConference||_isForOngoingVoipConference);
if(_tableController.contactsGroup.count == 0) {
if (!_isForEditing)
_nextButton.enabled = FALSE;
_tableController.tableView.frame = CGRectMake(_tableController.tableView.frame.origin.x,
_tableController.searchBar.frame.origin.y + _tableController.searchBar.frame.size.height,
_tableController.tableView.frame.size.width,
_tableController.tableView.frame.size.height + _collectionView.frame.size.height);
} else {
_tableController.tableView.frame = CGRectMake(_tableController.tableView.frame.origin.x,
_collectionView.frame.origin.y + _collectionView.frame.size.height,
_tableController.tableView.frame.size.width,
_tableController.tableView.frame.size.height);
}
[_collectionView reloadData];
_tableController.isForEditing = _isForEditing;
_tableController.isGroupChat = _isGroupChat;
_tableController.isEncrypted = _isEncrypted;
[self changeView:ContactsLinphone];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[NSNotificationCenter.defaultCenter removeObserver:self];
}
#pragma mark - Chat room functions
- (void)createChatRoom {
NSString *addr = _tableController.contactsGroup[0];
LinphoneAddress *remoteAddress = linphone_address_new(addr.UTF8String);
[PhoneMainView.instance getOrCreateOneToOneChatRoom:remoteAddress waitView:_waitView isEncrypted:_isEncrypted];
linphone_address_unref(remoteAddress);
}
#pragma mark - Buttons signals
- (IBAction)onBackClick:(id)sender {
[_tableController.contactsGroup removeAllObjects];
if (_isForVoipConference) {
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];
else
[PhoneMainView.instance popToView:ChatsListView.compositeViewDescription];
}
}
- (IBAction)onNextClick:(id)sender {
if (_isForVoipConference) {
if (_isForOngoingVoipConference) {
[PhoneMainView.instance popToView:VIEW(ConferenceCallView).compositeViewDescription];
[ConferenceViewModelBridge updateParticipantsListWithAddresses:_tableController.contactsGroup];
} else {
[PhoneMainView.instance changeCurrentView:VIEW(ConferenceSchedulingSummaryView).compositeViewDescription];
[VIEW(ConferenceSchedulingSummaryView) setParticipantsWithAddresses:_tableController.contactsGroup];
}
} else {
ChatConversationInfoView *view = VIEW(ChatConversationInfoView);
view.contacts = _tableController.contactsGroup;
view.create = !_isForEditing;
view.encrypted = _isEncrypted;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
}
- (IBAction)onChiffreClick:(id)sender {
CGRect frame = _chiffreButton.frame;
_isEncrypted = !_isEncrypted;
_tableController.isEncrypted = _isEncrypted;
if (_isEncrypted) {
// encrypted
frame.origin.x = 20;
[_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_green.png"]];
} else {
// no encrypted
frame.origin.x = 2;
[_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_grey.png"]];
}
_chiffreButton.frame = frame;
[_tableController.tableView reloadData];
}
- (void)dismissKeyboards {
if ([self.tableController.searchBar isFirstResponder])
[self.tableController.searchBar resignFirstResponder];
}
#pragma mark - Contacts filter
typedef enum { ContactsAll, ContactsLinphone, ContactsMAX } ContactsCategory;
- (void)changeView:(ContactsCategory)view {
CGRect frame = _selectedButtonImage.frame;
if (view == ContactsAll && !_allButton.selected) {
frame.origin.x = _allButton.frame.origin.x;
_allButton.selected = TRUE;
_linphoneButton.selected = FALSE;
_tableController.allFilter = TRUE;
_tableController.reloadMagicSearch = TRUE;
[_tableController loadData];
} else if (view == ContactsLinphone && !_linphoneButton.selected) {
frame.origin.x = _linphoneButton.frame.origin.x;
_linphoneButton.selected = TRUE;
_allButton.selected = FALSE;
_tableController.allFilter = FALSE;
_tableController.reloadMagicSearch = TRUE;
[_tableController loadData];
}
_selectedButtonImage.frame = frame;
if ([LinphoneManager.instance lpConfigBoolForKey:@"hide_linphone_contacts" inSection:@"app"]) {
_allButton.selected = FALSE;
}
}
- (IBAction)onAllClick:(id)event {
[self changeView:ContactsAll];
}
- (IBAction)onLinphoneClick:(id)event {
[self changeView:ContactsLinphone];
}
#pragma mark - GestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
return NO;
}
#pragma mark - UICollectionViewDataSource & Delegate
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _tableController.contactsGroup.count;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (UIChatCreateCollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSString *uri = _tableController.contactsGroup[indexPath.item];
UIChatCreateCollectionViewCell *cell = (UIChatCreateCollectionViewCell *)[_collectionView dequeueReusableCellWithReuseIdentifier:uri forIndexPath:indexPath];
cell.controller = self;
cell.uri = uri;
LinphoneAddress *addr = NULL;
LinphoneAccount *account = linphone_core_get_default_account(LC);
if (account && linphone_account_is_phone_number(account, uri.UTF8String)) {
char *phone = linphone_account_normalize_phone_number(account, uri.UTF8String);
addr = linphone_account_normalize_sip_uri(account, phone);
ms_free(phone);
} else
addr = linphone_address_new(uri.UTF8String);
[cell.nameLabel setText:[FastAddressBook displayNameForAddress:addr]];
linphone_address_unref(addr);
return cell;
}
@end

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ChatConversationImdnView_h
#define ChatConversationImdnView_h
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
#import "UIRoundBorderedButton.h"
#import "UIChatBubbleTextCell.h"
@interface ChatConversationImdnView : UIViewController <UICompositeViewDelegate, UITableViewDelegate, UITableViewDataSource>
{
@private
NSString *messageText;
}
@property(nonatomic) LinphoneEventLog *event;
@property(nonatomic) bctbx_list_t *displayedList;
@property(nonatomic) bctbx_list_t *receivedList;
@property(nonatomic) bctbx_list_t *notReceivedList;
@property(nonatomic) bctbx_list_t *errorList;
@property(nonatomic) UIChatBubbleTextCell *cell;
@property(nonatomic) NSTimer *ephemeralDisplayTimer;
@property (weak, nonatomic) IBOutlet UIView *msgView;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
- (IBAction)onBackClick:(id)sender;
- (void)updateImdnList;
@end
#endif /* ChatConversationImdnView_h */

View file

@ -0,0 +1,320 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <Foundation/Foundation.h>
#import "ChatConversationImdnView.h"
#import "PhoneMainView.h"
#import "UIChatBubbleTextCell.h"
#import "UIChatBubblePhotoCell.h"
#import "UIChatConversationImdnTableViewCell.h"
@implementation ChatConversationImdnView
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:TabBarView.class
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:NO
fragmentWith:ChatsListView.class];
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
return self.class.compositeViewDescription;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_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;
[_cell update];
_cell.popupMenuAllowed = false;
for (UIView *v in [_msgView subviews]) {
[v removeFromSuperview];
}
[_msgView addSubview:_cell];
_tableView.delegate = self;
_tableView.dataSource = self;
[self updateImdnList];
[self fitContent];
[self startEphemeralDisplayTimer];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(ephemeralDeleted:)
name:kLinphoneEphemeralMessageDeletedInRoom
object:nil];
}
-(void) viewWillDisappear:(BOOL)animated {
[self stopEphemeralDisplayTimer];
[NSNotificationCenter.defaultCenter removeObserver:self];
[super viewWillDisappear:animated];
}
- (void)updateImdnList {
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)];
[_tableView setFrame:CGRectMake(_tableView.frame.origin.x,
_msgView.frame.origin.y + _msgView.frame.size.height + 10,
_tableView.frame.size.width,
self.view.frame.size.height - (_msgView.frame.origin.y + _msgView.frame.size.height))];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self fitContent];
}
#pragma mark - TableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger numberOfSection = 0;
if (_displayedList) numberOfSection++;
if (_receivedList) numberOfSection++;
if (_notReceivedList) numberOfSection++;
if (_errorList) numberOfSection++;
return numberOfSection;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 23.0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
return 44.0;
}
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
label.numberOfLines = 1;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 23)];
UIImage *image = NULL;
if (section == 0) {
if (_displayedList) {
label.text = NSLocalizedString(@"Read", nil);
label.textColor = [UIColor colorWithRed:(24 / 255.0) green:(167 / 255.0) blue:(175 / 255.0) alpha:1.0];
image = [UIImage imageNamed:@"chat_read"];
} else if (_receivedList) {
label.text = NSLocalizedString(@"Delivered", nil);
label.textColor = [UIColor grayColor];
image = [UIImage imageNamed:@"chat_delivered"];
} else if (_notReceivedList) {
label.text = NSLocalizedString(@"Sent", nil);
label.textColor = [UIColor grayColor];
} else if (_errorList) {
label.text = NSLocalizedString(@"Error", nil);
label.textColor = [UIColor redColor];
image = [UIImage imageNamed:@"chat_error"];
}
} else if (section == 1) {
if (_displayedList && _receivedList) {
label.text = NSLocalizedString(@"Delivered", nil);
label.textColor = [UIColor grayColor];
image = [UIImage imageNamed:@"chat_delivered"];
} else if (_notReceivedList) {
label.text = NSLocalizedString(@"Sent", nil);
label.textColor = [UIColor grayColor];
} else if (_errorList) {
label.text = NSLocalizedString(@"Error", nil);
label.textColor = [UIColor redColor];
image = [UIImage imageNamed:@"chat_error"];
}
} else if (section == 2) {
if (_displayedList && _receivedList && _notReceivedList) {
label.text = NSLocalizedString(@"Sent", nil);
label.textColor = [UIColor grayColor];
} else if (_errorList) {
label.text = NSLocalizedString(@"Error", nil);
label.textColor = [UIColor redColor];
image = [UIImage imageNamed:@"chat_error"];
}
} else if (section == 3) {
label.text = NSLocalizedString(@"Error", nil);
label.textColor = [UIColor redColor];
image = [UIImage imageNamed:@"chat_error"];
}
[view addSubview:label];
[label sizeToFit];
[label setCenter:view.center];
if (image) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[view addSubview:imageView];
[imageView setFrame:CGRectMake(label.frame.origin.x + label.frame.size.width + 5, 2, 19, 19)];
}
if (@available(iOS 13, *)) {
[view setBackgroundColor:[UIColor secondarySystemBackgroundColor]];
} else {
[view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_G.png"]]];
}
return view;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
if (_displayedList)
return bctbx_list_size(_displayedList);
else if (_receivedList)
return bctbx_list_size(_receivedList);
else if (_notReceivedList)
return bctbx_list_size(_notReceivedList);
else if (_errorList)
return bctbx_list_size(_errorList);
} else if (section == 1) {
if (_displayedList &&_receivedList)
return bctbx_list_size(_receivedList);
else if (_notReceivedList)
return bctbx_list_size(_notReceivedList);
else if (_errorList)
return bctbx_list_size(_errorList);
} else if (section == 2) {
if (_displayedList && _receivedList && _notReceivedList)
return bctbx_list_size(_notReceivedList);
else if (_errorList)
return bctbx_list_size(_errorList);
} else if (section == 3)
return bctbx_list_size(_errorList);
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
bctbx_list_t *list = NULL;
if (indexPath.section == 0) {
if (_displayedList)
list = _displayedList;
else if (_receivedList)
list = _receivedList;
else if (_notReceivedList)
list = _notReceivedList;
else if (_errorList)
list = _errorList;
} else if (indexPath.section == 1) {
if (_displayedList &&_receivedList)
list = _receivedList;
else if (_notReceivedList)
list = _notReceivedList;
else if (_errorList)
list = _errorList;
} else if (indexPath.section == 2) {
if (_displayedList && _receivedList && _notReceivedList)
list = _notReceivedList;
else if (_errorList)
list = _errorList;
} else if (indexPath.section == 3)
list = _errorList;
if (!list)
return nil;
NSString *kCellId = NSStringFromClass(UIChatConversationImdnTableViewCell.class);
UIChatConversationImdnTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[UIChatConversationImdnTableViewCell alloc] initWithIdentifier:kCellId];
}
LinphoneParticipantImdnState *state = bctbx_list_nth_data(list, (int)indexPath.row);
const LinphoneParticipant *participant = linphone_participant_imdn_state_get_participant(state);
time_t time = linphone_participant_imdn_state_get_state_change_time(state);
const LinphoneAddress *addr = linphone_participant_get_address(participant);
cell.displayName.text = [FastAddressBook displayNameForAddress:addr];
cell.avatar.image = [FastAddressBook imageForAddress:addr];
cell.dateLabel.text = [LinphoneUtils timeToString:time withFormat:LinphoneDateChatBubble];
cell.userInteractionEnabled = false;
return cell;
}
- (IBAction)onBackClick:(id)sender {
[PhoneMainView.instance popCurrentView];
}
#pragma mark ephemeral messages
-(void) startEphemeralDisplayTimer {
_ephemeralDisplayTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(updateEphemeralTimes)
userInfo:nil
repeats:YES];
}
-(void) updateEphemeralTimes {
NSDateComponentsFormatter *f= [[NSDateComponentsFormatter alloc] init];
f.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
f.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
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;
f.allowedUnits = (duration > 86400 ? kCFCalendarUnitDay : 0)|(duration > 3600 ? kCFCalendarUnitHour : 0)|kCFCalendarUnitMinute|kCFCalendarUnitSecond;
_cell.ephemeralTime.text = [f stringFromTimeInterval:duration];
_cell.ephemeralTime.hidden = NO;
_cell.ephemeralIcon.hidden = NO;
}
}
-(void) stopEphemeralDisplayTimer {
[_ephemeralDisplayTimer invalidate];
}
- (void)ephemeralDeleted:(NSNotification *)notif {
[PhoneMainView.instance popToView:ChatConversationView.compositeViewDescription];
}
@end

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
#import "UIRoundBorderedButton.h"
@interface ChatConversationInfoView : UIViewController <UICompositeViewDelegate, UIGestureRecognizerDelegate, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource>
@property(nonatomic) BOOL create;
@property(nonatomic) BOOL imAdmin;
@property(nonatomic) BOOL encrypted;
@property(nonatomic, strong) NSMutableArray *contacts;
@property(nonatomic, strong) NSMutableArray *admins;
@property(nonatomic, strong) NSMutableArray *oldContacts;
@property(nonatomic, strong) NSMutableArray *oldAdmins;
@property(nonatomic) NSString *oldSubject;
@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;
@property (weak, nonatomic) IBOutlet UIIconButton *addButton;
@property (weak, nonatomic) IBOutlet UITextField *nameLabel;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property (weak, nonatomic) IBOutlet UIView *participantsBar;
+ (void)displayCreationError;
- (IBAction)onNextClick:(id)sender;
- (IBAction)onBackClick:(id)sender;
- (IBAction)onQuitClick:(id)sender;
@end

View file

@ -0,0 +1,431 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <Foundation/Foundation.h>
#import "ChatConversationInfoView.h"
#import "PhoneMainView.h"
#import "UIChatConversationInfoTableViewCell.h"
#import "linphone/core.h"
@implementation ChatConversationInfoView
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:TabBarView.class
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:NO
fragmentWith:ChatsListView.class];
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
return self.class.compositeViewDescription;
}
+ (void)displayCreationError {
static UIAlertController *errorView = nil;
// avoid having multiple popups
[PhoneMainView.instance dismissViewControllerAnimated:YES completion:nil];
errorView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Chat room creation error", nil)
message:NSLocalizedString(@"Chat room could not be created on server", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errorView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errorView animated:YES completion:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(dismissKeyboards)];
tap.delegate = self;
[self.view addGestureRecognizer:tap];
UITapGestureRecognizer *particpantsBarTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(onAddClick:)];
particpantsBarTap.delegate = self;
[_participantsBar addGestureRecognizer:particpantsBarTap];
_nameLabel.delegate = self;
_tableView.dataSource = self;
_tableView.delegate = self;
_admins = [[NSMutableArray alloc] init];
_oldAdmins = [[NSMutableArray alloc] init];
_oldContacts = [[NSMutableArray alloc] init];
_room = NULL;
_chatRoomCbs = NULL;
_peerAddress = NULL;
_localAddress = NULL;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_waitView.hidden = YES;
[self configure];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onLinphoneCoreReady:)
name:kLinphoneGlobalStateUpdate
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[NSNotificationCenter.defaultCenter removeObserver:self];
if (!_room || !_chatRoomCbs)
return;
linphone_chat_room_remove_callbacks(_room, _chatRoomCbs);
_chatRoomCbs = NULL;
}
- (void)configure {
if (_create)
_room = NULL;
_nameLabel.text = _room && linphone_chat_room_get_subject(_room)
? [NSString stringWithUTF8String:linphone_chat_room_get_subject(_room)]
: @"";
_nextButton.enabled = _nameLabel.text.length > 0 && _contacts.count > 0;
LinphoneParticipant *me = _room && !linphone_chat_room_is_read_only(_room)
? linphone_chat_room_get_me(_room)
: NULL;
_imAdmin = me
? linphone_participant_is_admin(me)
: false;
_quitButton.hidden = _create || (me == NULL);
_nameLabel.enabled = _create || _imAdmin;
_addButton.hidden = !_create && !_imAdmin;
_nextButton.hidden = !_create && !_imAdmin;
CGFloat height = _quitButton.hidden
? self.view.frame.size.height - _tableView.frame.origin.y
: _quitButton.frame.origin.y - _tableView.frame.origin.y - 10;
[_tableView setFrame:CGRectMake(
_tableView.frame.origin.x,
_tableView.frame.origin.y,
_tableView.frame.size.width,
height
)];
if (_room) {
_chatRoomCbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(_chatRoomCbs, main_view_chat_room_state_changed);
linphone_chat_room_cbs_set_subject_changed(_chatRoomCbs, chat_room_subject_changed);
linphone_chat_room_cbs_set_participant_added(_chatRoomCbs, chat_room_participant_added);
linphone_chat_room_cbs_set_participant_removed(_chatRoomCbs, chat_room_participant_removed);
linphone_chat_room_cbs_set_participant_admin_status_changed(_chatRoomCbs, chat_room_participant_admin_status_changed);
linphone_chat_room_cbs_set_user_data(_chatRoomCbs, (__bridge void*)self);
linphone_chat_room_add_callbacks(_room, _chatRoomCbs);
}
[_tableView reloadData];
}
#pragma mark - next functions
- (void)onLinphoneCoreReady:(NSNotification *)notif {
if ((LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn) {
if (!_create && _peerAddress && _localAddress) {
LinphoneAddress *peerAddr = linphone_core_create_address([LinphoneManager getLc], _peerAddress);
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];
}
}
}
- (void)onCreate {
bctbx_list_t *addresses = NULL;
for (NSString *addr in _contacts) {
LinphoneAddress *linphoneAddress = linphone_address_new(addr.UTF8String);
if (!linphoneAddress)
continue;
if (!addresses) {
addresses = bctbx_list_new((void *)linphoneAddress);
continue;
}
addresses = bctbx_list_append(addresses, (void *)linphoneAddress);
}
[PhoneMainView.instance createChatRoom:_nameLabel.text.UTF8String addresses:addresses andWaitView:_waitView isEncrypted:_encrypted isGroup:TRUE];
bctbx_list_free_with_data(addresses, (void (*)(void *))linphone_address_unref);
}
- (void)onValidate {
ChatConversationView *view = VIEW(ChatConversationView);
// Change subject if necessary
if (![_oldSubject isEqualToString:_nameLabel.text])
linphone_chat_room_set_subject(_room, _nameLabel.text.UTF8String);
// Add participants if necessary
bctbx_list_t *addedPartipants = NULL;
for (NSString *uri in _contacts) {
if ([_oldContacts containsObject:uri])
continue;
LinphoneAddress *addr = linphone_address_new(uri.UTF8String);
linphone_address_clean(addr);//keep only username@domain
if (addedPartipants)
addedPartipants = bctbx_list_append(addedPartipants, addr);
else
addedPartipants = bctbx_list_new(addr);
}
if (addedPartipants) {
linphone_chat_room_add_participants(_room, addedPartipants);
bctbx_list_free_with_data(addedPartipants, (void (*)(void *))linphone_address_unref);
}
// Remove participants if necessary
bctbx_list_t *removedPartipants = NULL;
for (NSString *uri in _oldContacts) {
if ([_contacts containsObject:uri])
continue;
LinphoneAddress *addr = linphone_address_new(uri.UTF8String);
LinphoneParticipant *participant = linphone_participant_ref(linphone_chat_room_find_participant(_room, addr));
if (!participant)
continue;
if (removedPartipants)
removedPartipants = bctbx_list_append(removedPartipants, participant);
else
removedPartipants = bctbx_list_new(participant);
linphone_address_unref(addr);
}
if (removedPartipants) {
linphone_chat_room_remove_participants(_room, removedPartipants);
bctbx_list_free_with_data(removedPartipants, (void (*)(void *))linphone_participant_unref);
}
// add admins if necessary
for (NSString *admin in _admins) {
if ([_oldAdmins containsObject:admin])
continue;
LinphoneAddress *addr = linphone_address_new(admin.UTF8String);
LinphoneParticipant *participant = linphone_chat_room_find_participant(_room, addr);
if (!participant)
continue;
linphone_chat_room_set_participant_admin_status(_room, participant, true);
linphone_address_unref(addr);
}
// remove admins if necessary
for (NSString *admin in _oldAdmins) {
if ([_admins containsObject:admin])
continue;
LinphoneAddress *addr = linphone_address_new(admin.UTF8String);
LinphoneParticipant *participant = linphone_chat_room_find_participant(_room, addr);
if (!participant)
continue;
linphone_chat_room_set_participant_admin_status(_room, participant, false);
linphone_address_unref(addr);
}
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
#pragma mark - Buttons responders
- (IBAction)onNextClick:(id)sender {
if(_create)
[self onCreate];
else
[self onValidate];
}
- (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);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
}
- (IBAction)onQuitClick:(id)sender {
NSString *msg =
[NSString stringWithFormat:NSLocalizedString(@"Do you want to leave this conversation?", nil)];
[UIConfirmationDialog ShowWithMessage:msg
cancelMessage:nil
confirmMessage:NSLocalizedString(@"LEAVE", nil)
onCancelClick:^() {}
onConfirmationClick:^() {
linphone_chat_room_leave(_room);
}];
}
- (IBAction)onAddClick:(id)sender {
if (_create || _imAdmin) {
ChatConversationCreateView *view = VIEW(ChatConversationCreateView);
[view fragmentCompositeDescription];
view.tableController.notFirstTime = TRUE;
view.isForEditing = !_create;
view.isGroupChat = TRUE;
view.tableController.contactsGroup = [_contacts mutableCopy];
view.isForVoipConference = FALSE;
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
}
#pragma mark - TableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _contacts.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *kCellId = NSStringFromClass(UIChatConversationInfoTableViewCell.class);
UIChatConversationInfoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[UIChatConversationInfoTableViewCell alloc] initWithIdentifier:kCellId];
}
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.controllerView = self;
if(![_admins containsObject:cell.uri]) {
cell.adminLabel.enabled = FALSE;
cell.adminImage.image = [UIImage imageNamed:@"check_unselected.png"];
}
cell.adminButton.hidden = _create || (!_imAdmin && !cell.adminLabel.enabled) || ![_oldContacts containsObject:cell.uri];
cell.adminButton.userInteractionEnabled = _imAdmin;
cell.removeButton.hidden = !_create && !_imAdmin;
if (addr)
linphone_address_unref(addr);
return cell;
}
#pragma mark - searchBar delegate
- (void)dismissKeyboards {
if ([_nameLabel isFirstResponder]) {
[_nameLabel resignFirstResponder];
}
}
#pragma mark - UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
_nextButton.enabled = (!((string.length == 0 || string == nil || [string isEqual:@""]) && (textField.text.length == 1))
&& _contacts.count > 0);
return TRUE;
}
#pragma mark - chat room callbacks
- (void)myAdminStatusChanged:(BOOL)admin {
NSString *message = admin
? NSLocalizedString(@"You are now an admin of the chat room", nil)
: NSLocalizedString(@"You are no longer an admin of the chat room", nil);
static UIAlertController *alertView = nil;
// avoid having multiple popups
[PhoneMainView.instance dismissViewControllerAnimated:YES completion:nil];
alertView = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"%@", message]
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alertView addAction:defaultAction];
[PhoneMainView.instance presentViewController:alertView animated:YES completion:nil];
}
void chat_room_subject_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
ChatConversationInfoView *view = (__bridge ChatConversationInfoView *)linphone_chat_room_cbs_get_user_data(linphone_chat_room_get_current_callbacks(cr));
view.nameLabel.text = [NSString stringWithUTF8String:linphone_event_log_get_subject(event_log)];
}
void chat_room_participant_added(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
ChatConversationInfoView *view = (__bridge ChatConversationInfoView *)linphone_chat_room_cbs_get_user_data(linphone_chat_room_get_current_callbacks(cr));
char *str = linphone_address_as_string(linphone_event_log_get_participant_address(event_log));
NSString *participantAddress = [NSString stringWithUTF8String:str];
ms_free(str);
[view.oldContacts addObject:participantAddress];
[view.contacts addObject:participantAddress];
[view.tableView reloadData];
}
void chat_room_participant_removed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
ChatConversationInfoView *view = (__bridge ChatConversationInfoView *)linphone_chat_room_cbs_get_user_data(linphone_chat_room_get_current_callbacks(cr));
char *str = linphone_address_as_string(linphone_event_log_get_participant_address(event_log));
NSString *participantAddress = [NSString stringWithUTF8String:str];
ms_free(str);
[view.oldContacts removeObject:participantAddress];
[view.contacts removeObject:participantAddress];
[view.tableView reloadData];
}
void chat_room_participant_admin_status_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
ChatConversationInfoView *view = (__bridge ChatConversationInfoView *)linphone_chat_room_cbs_get_user_data(linphone_chat_room_get_current_callbacks(cr));
char *str = linphone_address_as_string(linphone_event_log_get_participant_address(event_log));
NSString *participantAddress = [NSString stringWithUTF8String:str];
ms_free(str);
LinphoneParticipant *me = linphone_chat_room_get_me(cr);
if (me && linphone_address_equal(linphone_participant_get_address(me), linphone_event_log_get_participant_address(event_log))) {
[view myAdminStatusChanged:(linphone_event_log_get_type(event_log) == LinphoneEventLogTypeConferenceParticipantSetAdmin)];
[view viewWillAppear:TRUE];
return;
}
if (linphone_event_log_get_type(event_log) == LinphoneEventLogTypeConferenceParticipantSetAdmin) {
[view.admins addObject:participantAddress];
[view.oldAdmins addObject:participantAddress];
} else { // linphone_event_log_get_type(event_log) == LinphoneEventLogTypeConferenceParticipantUnsetAdmin
[view.admins removeObject:participantAddress];
[view.oldAdmins removeObject:participantAddress];
}
[view.tableView reloadData];
}
@end

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#include "linphone/linphonecore.h"
#import "linphone/api/c-event-log.h"
#import "linphone/api/c-chat-room.h"
#import "UICheckBoxTableView.h"
@interface FileContext : NSObject
@property NSMutableArray <NSString *> *typesArray;
@property NSMutableArray <NSData *> *datasArray;
@property NSMutableArray <UIImage *> *previewsArray;
@property NSMutableArray <NSString *> *namesArray;
@property NSMutableArray <NSUUID *> *uuidsArray;
- (void)clear;
- (NSUInteger)count;
- (void)addObject:(NSData *)data name:(NSString *)name type:(NSString *)type;
@end
@protocol ChatConversationDelegate <NSObject>
- (BOOL)resendMultiFiles:(FileContext *)newFileContext message:(NSString *)message rootMessage:(LinphoneChatMessage *)rootMessage;
- (BOOL)resendFile:(NSData *)data withName:(NSString *)name type:(NSString *)type key:(NSString *)key message:(NSString *)message rootMessage:(LinphoneChatMessage *)rootMessage;
- (BOOL)startFileUpload:(NSData *)data withName:(NSString *)name rootMessage:(LinphoneChatMessage *)rootMessage;
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url rootMessage:(LinphoneChatMessage *)rootMessage;
- (void)tableViewIsScrolling;
@end
@interface ChatConversationTableView : UICheckBoxTableView {
@private
NSMutableArray *eventList;
NSMutableArray *totalEventList;
}
@property(nonatomic) LinphoneChatRoom *chatRoom;
@property(nonatomic) NSInteger currentIndex;
@property(nonatomic, strong) id<ChatConversationDelegate> chatRoomDelegate;
@property NSMutableDictionary<NSString *, UIImage *> *imagesInChatroom;
@property(nonatomic) NSTimer *ephemeralDisplayTimer;
@property (nullable, nonatomic) UIButton *floatingScrollButton;
@property (nullable, nonatomic) UILabel *scrollBadge;
- (void)addEventEntry:(LinphoneEventLog *)event;
- (void)scrollToBottom:(BOOL)animated;
- (void)scrollToLastUnread:(BOOL)animated;
- (void)updateEventEntry:(LinphoneEventLog *)event;
- (void)refreshData;
- (void)reloadData;
- (void) dismissMessagesPopups;
- (void) scrollToMessage:(LinphoneChatMessage *)message;
- (int) indexOfMesssage:(LinphoneChatMessage *)message;
- (void *)buildMessageCell:(LinphoneEventLog *) event;
@end

View file

@ -0,0 +1,533 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "LinphoneManager.h"
#import "ChatConversationTableView.h"
#import "ChatConversationImdnView.h"
#import "UIChatBubblePhotoCell.h"
#import "UIChatNotifiedEventCell.h"
#import "PhoneMainView.h"
#import "linphoneapp-Swift.h"
@implementation ChatConversationTableView
#pragma mark - Lifecycle Functions
- (void)dealloc {
[self clearEventList];
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.tableView.accessibilityIdentifier = @"ChatRoom list";
_imagesInChatroom = [NSMutableDictionary dictionary];
_currentIndex = 0;
[self startEphemeralDisplayTimer];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(ephemeralDeleted:)
name:kLinphoneEphemeralMessageDeletedInRoom
object:nil];
}
-(void) viewWillDisappear:(BOOL)animated {
[self dismissMessagesPopups];
[self stopEphemeralDisplayTimer];
[NSNotificationCenter.defaultCenter removeObserver:self];
[super viewWillDisappear:animated];
[_floatingScrollButton setHidden:TRUE];
}
#pragma mark -
- (void)clearEventList {
for (NSValue *value in totalEventList) {
LinphoneEventLog *event = value.pointerValue;
linphone_event_log_unref(event);
}
[eventList removeAllObjects];
[totalEventList removeAllObjects];
}
-(bool) eventTypeIsOfInterestForOneToOneRoom:(LinphoneEventLogType)type {
return
type == LinphoneEventLogTypeConferenceChatMessage ||
type == LinphoneEventLogTypeConferenceEphemeralMessageEnabled ||
type == LinphoneEventLogTypeConferenceEphemeralMessageDisabled ||
type == LinphoneEventLogTypeConferenceEphemeralMessageLifetimeChanged;
}
- (void)updateData {
[self clearEventList];
if (!_chatRoom)
return;
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;
size_t listSize = bctbx_list_size(chatRoomEvents);
totalEventList = [[NSMutableArray alloc] initWithCapacity:listSize];
eventList = [[NSMutableArray alloc] initWithCapacity:MIN(listSize, BASIC_EVENT_LIST)];
BOOL autoDownload = (linphone_core_get_max_size_for_auto_download_incoming_files(LC) > -1);
while (chatRoomEvents) {
LinphoneEventLog *event = (LinphoneEventLog *)chatRoomEvents->data;
if (oneToOne && ![self eventTypeIsOfInterestForOneToOneRoom:linphone_event_log_get_type(event)]) {
chatRoomEvents = chatRoomEvents->next;
} else {
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
if (chat && !linphone_chat_message_is_read(chat)) {
if (unread_count == 0) {
// [eventList addObject:[NSString stringWithString:@"Ceci est un test wesh wesh"]];
}
}
// if auto_download is available and file transfer in progress, not add event now
if (!(autoDownload && chat && linphone_chat_message_is_file_transfer_in_progress(chat))) {
[totalEventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]];
if (listSize <= BASIC_EVENT_LIST) {
[eventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]];
}
}
chatRoomEvents = chatRoomEvents->next;
listSize -= 1;
}
}
bctbx_list_free_with_data(head, (bctbx_list_free_func)linphone_event_log_unref);
}
- (void)refreshData {
if (totalEventList.count <= eventList.count) {
_currentIndex = 0;
return;
}
NSUInteger num = MIN(totalEventList.count-eventList.count, BASIC_EVENT_LIST);
_currentIndex = num - 1;
while (num) {
NSInteger index = totalEventList.count - eventList.count - 1;
[eventList insertObject:[totalEventList objectAtIndex:index] atIndex:0];
index -= 1;
num -= 1;
}
}
- (void)reloadData {
[self updateData];
[self.tableView reloadData];
[self scrollToLastUnread:false];
}
- (void)addEventEntry:(LinphoneEventLog *)event {
[eventList 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 endUpdates];
}
- (void)updateEventEntry:(LinphoneEventLog *)event {
NSInteger index = [eventList indexOfObject:[NSValue valueWithPointer:event]];
if (index < 0) {
LOGW(@"event entry doesn't exist");
return;
}
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]]
withRowAnimation:FALSE]; // just reload
return;
}
- (void)scrollToBottom:(BOOL)animated {
//[self.tableView reloadData];
size_t count = eventList.count;
if (!count)
return;
//[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
[ChatConversationView markAsRead:_chatRoom];
}
- (void)scrollToLastUnread:(BOOL)animated {
if (eventList.count == 0 || _chatRoom == nil)
return;
int index = -1;
size_t count = eventList.count;
// Find first unread & set all entry read
for (int i = (int)count - 1; i > 0; --i) {
LinphoneEventLog *event = [[eventList objectAtIndex:i] pointerValue];
if (!(linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage))
break;
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
int read = linphone_chat_message_is_read(chat);
LinphoneChatMessageState state = linphone_chat_message_get_state(chat);
if (read == 0 &&
!(state == LinphoneChatMessageStateFileTransferError || state == LinphoneChatMessageStateNotDelivered)) {
if (index == -1) {
index = i;
break;
}
}
}
if (index == -1 && count > 0)
index = (int)count - 1;
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
[ChatConversationView markAsRead:_chatRoom];
// Scroll to unread
if (index < 0)
return;
[self.tableView.layer removeAllAnimations];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:animated];
}
- (void) scrollToMessage:(LinphoneChatMessage *)message {
int index = [self indexOfMesssage:message];
if (index < 0)
return;
[self.tableView.layer removeAllAnimations];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:true];
}
-(int) indexOfMesssage:(LinphoneChatMessage *)message {
if (eventList.count == 0 || _chatRoom == nil)
return -1;
const char *msgId = linphone_chat_message_get_message_id(message);
int index = -1;
size_t count = eventList.count;
for (int i = (int)count - 1; i > 0; --i) {
LinphoneEventLog *event = [[eventList objectAtIndex:i] pointerValue];
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
if (!chat)
continue;
if (!strcmp(msgId, linphone_chat_message_get_message_id(chat))) {
index = i;
break;
}
}
return index;
}
#pragma mark - Property Functions
- (void)setChatRoom:(LinphoneChatRoom *)room {
_chatRoom = room;
[self reloadData];
[self updateEphemeralTimes];
}
static const int MAX_AGGLOMERATED_TIME=300;
static const int BASIC_EVENT_LIST=15;
- (BOOL)isFirstIndexInTableView:(NSIndexPath *)indexPath chat:(LinphoneChatMessage *)chat {
LinphoneEventLog *previousEvent = nil;
NSInteger indexOfPreviousEvent = indexPath.row - 1;
if (indexOfPreviousEvent > -1) {
previousEvent = [[eventList objectAtIndex:indexOfPreviousEvent] pointerValue];
if (linphone_event_log_get_type(previousEvent) != LinphoneEventLogTypeConferenceChatMessage) {
return TRUE;
}
}
if (!previousEvent)
return TRUE;
LinphoneChatMessage *previousChat = linphone_event_log_get_chat_message(previousEvent);
if (!linphone_address_equal(linphone_chat_message_get_from_address(previousChat), linphone_chat_message_get_from_address(chat))) {
return TRUE;
}
// the maximum interval between 2 agglomerated chats at 5mn
if ((linphone_chat_message_get_time(chat)-linphone_chat_message_get_time(previousChat)) > MAX_AGGLOMERATED_TIME) {
return TRUE;
}
return FALSE;
}
- (BOOL)isLastIndexInTableView:(NSIndexPath *)indexPath chat:(LinphoneChatMessage *)chat {
LinphoneEventLog *nextEvent = nil;
NSInteger indexOfNextEvent = indexPath.row + 1;
while (!nextEvent && indexOfNextEvent < [eventList count]) {
LinphoneEventLog *tmp = [[eventList objectAtIndex:indexOfNextEvent] pointerValue];
if (linphone_event_log_get_type(tmp) == LinphoneEventLogTypeConferenceChatMessage) {
nextEvent = tmp;
}
++indexOfNextEvent;
}
if (!nextEvent)
return TRUE;
LinphoneChatMessage *nextChat = linphone_event_log_get_chat_message(nextEvent);
if (!linphone_address_equal(linphone_chat_message_get_from_address(nextChat), linphone_chat_message_get_from_address(chat))) {
return TRUE;
}
return FALSE;
}
#pragma mark - UITableViewDataSource Functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return eventList.count;
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath {
if (!_chatRoom && [[cell reuseIdentifier] isEqualToString:@"UIChatBubblePhotoCell"]) {
[(UIChatBubbleTextCell *)cell clearEncryptedFiles];
}
if ([cell isKindOfClass:[UIChatBubbleTextCell class]] ||[cell isKindOfClass:[UIChatBubblePhotoCell class]])
[(UIChatBubbleTextCell *)cell dismissPopup];
}
-(void) dismissMessagesPopups {
for (UITableViewCell *cell in self.tableView.visibleCells) {
if (![[cell reuseIdentifier] isEqualToString:NSStringFromClass(UIChatNotifiedEventCell.class)])
[(UIChatBubbleTextCell *)cell dismissPopup];
}
}
-(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);
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;
cell.tableController = self;
cell.popupMenuAllowed = true;
return cell;
} else {
kCellId = NSStringFromClass(UIChatNotifiedEventCell.class);
UIChatNotifiedEventCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (!cell)
cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId];
[cell setEvent:event];
[super accessoryForCell:cell atPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
}
#pragma mark - UITableViewDelegate Functions
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[_chatRoomDelegate tableViewIsScrolling];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
[ChatConversationView markAsRead:_chatRoom];
}
}
static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage) {
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
//If the message is followed by another one that is not from the same address, we add a little space under it
CGFloat height = 0;
if ([self isLastIndexInTableView:indexPath chat:chat])
height += tableView.frame.size.height * MESSAGE_SPACING_PERCENTAGE / 100;
if (![self isFirstIndexInTableView:indexPath chat:chat])
height -= 20;
return [UIChatBubbleTextCell ViewHeightForMessage:chat withWidth:self.view.frame.size.width].height + height;
}
return [UIChatNotifiedEventCell height];
}
- (void) tableView:(UITableView *)tableView deleteRowAtIndex:(NSIndexPath *)indexPath {
[tableView beginUpdates];
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
linphone_event_log_delete_from_database(event);
NSInteger index = indexPath.row + _currentIndex + (totalEventList.count - eventList.count);
if (index < totalEventList.count)
[totalEventList removeObjectAtIndex:index];
[eventList removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationBottom];
[tableView endUpdates];
[self loadData];
}
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView
leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
if (linphone_event_log_get_type(event) != LinphoneEventLogTypeConferenceChatMessage) {
return [UISwipeActionsConfiguration configurationWithActions:@[]];
}
UIContextualAction *replyAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
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];
[self scrollToBottom:TRUE];
}];
UISwipeActionsConfiguration *swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[replyAction]];
swipeActionConfig.performsFirstActionWithFullSwipe = YES;
return swipeActionConfig;
}
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView
trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
UIContextualAction *delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
title:NSLocalizedString(@"Delete", nil)
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[self tableView:tableView deleteRowAtIndex:indexPath];
}];
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)) {
ChatConversationImdnView *view = VIEW(ChatConversationImdnView);
view.event = event;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}];
UISwipeActionsConfiguration *swipeActionConfig;
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage &&
!(linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesOneToOne)) {
swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[delete, imdnAction]];
} else {
swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[delete]];
}
swipeActionConfig.performsFirstActionWithFullSwipe = YES;
return swipeActionConfig;
}
- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover {
[super removeSelectionUsing:^(NSIndexPath *indexPath) {
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
if (linphone_event_log_get_chat_message(event)) {
linphone_chat_room_delete_message(_chatRoom, linphone_event_log_get_chat_message(event));
} else {
linphone_event_log_delete_from_database(event);
}
NSInteger index = indexPath.row + _currentIndex + (totalEventList.count - eventList.count);
if (index < totalEventList.count)
[totalEventList removeObjectAtIndex:index];
[eventList removeObjectAtIndex:indexPath.row];
}];
}
#pragma mark ephemeral messages
-(void) startEphemeralDisplayTimer {
_ephemeralDisplayTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(updateEphemeralTimes)
userInfo:nil
repeats:YES];
}
-(void) updateEphemeralTimes {
NSDateComponentsFormatter *f= [[NSDateComponentsFormatter alloc] init];
f.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
f.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
for (NSValue *v in eventList) {
LinphoneEventLog *event = [v pointerValue];
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage) {
LinphoneChatMessage *msg = linphone_event_log_get_chat_message(event);
if (linphone_chat_message_is_ephemeral(msg)) {
UIChatBubbleTextCell *cell = (UIChatBubbleTextCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:[eventList indexOfObject:v] inSection:0]];
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;
f.allowedUnits = (duration > 86400 ? kCFCalendarUnitDay : 0)|(duration > 3600 ? kCFCalendarUnitHour : 0)|kCFCalendarUnitMinute|kCFCalendarUnitSecond;
cell.ephemeralTime.text = [f stringFromTimeInterval:duration];
cell.ephemeralTime.hidden = NO;
cell.ephemeralIcon.hidden = NO;
}
}
}
}
-(void) stopEphemeralDisplayTimer {
[_ephemeralDisplayTimer invalidate];
}
- (void)ephemeralDeleted:(NSNotification *)notif {
LinphoneChatRoom *r =[[notif.userInfo objectForKey:@"room"] pointerValue];
if (r ==_chatRoom)
[self reloadData];
}
@end

View file

@ -0,0 +1,167 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import <QuickLook/QLPreviewItem.h>
#import <QuickLook/QLPreviewController.h>
#import "UIToggleButton.h"
#import "UICompositeView.h"
#import "ChatConversationTableView.h"
#import "ImagePickerView.h"
#import "OrderedDictionary.h"
#import "UIRoundedImageView.h"
#import "UIBackToCallButton.h"
#import "Utils/HPGrowingTextView/HPGrowingTextView.h"
#import "UIImageViewDeletable.h"
#import "UIConfirmationDialog.h"
#import "UIInterfaceStyleButton.h"
#import "UIChatReplyBubbleView.h"
#include "linphone/linphonecore.h"
//Quicklook Preview Item
@interface PreviewItem : NSObject <QLPreviewItem>
@property(readonly, nonatomic) NSURL *previewItemURL;
@property(readonly, nonatomic) NSString *previewItemTitle;
@end
//QuickLook Datasource for rending PDF docs
@interface FileDataSource : NSObject <QLPreviewControllerDataSource>
@property NSMutableArray<NSURL*> *files;
@end
@interface ChatConversationView
: TPMultiLayoutViewController <HPGrowingTextViewDelegate, UICompositeViewDelegate, ImagePickerDelegate, ChatConversationDelegate,
UIDocumentInteractionControllerDelegate, UISearchBarDelegate, UIImageViewDeletableDelegate,QLPreviewControllerDelegate, UICollectionViewDataSource,UICollectionViewDelegate,UIDocumentMenuDelegate,UIDocumentPickerDelegate,UITableViewDataSource, UITableViewDelegate> {
OrderedDictionary *imageQualities;
BOOL scrollOnGrowingEnabled;
BOOL composingVisible;
UIConfirmationDialog *securityDialog;
UIRefreshControl *refreshControl;
BOOL isOneToOne;
BOOL isEncrypted;
}
@property(nonatomic) LinphoneChatRoom *chatRoom;
@property(nonatomic) LinphoneChatRoomCbs *chatRoomCbs;
@property(nonatomic) Boolean markAsRead;
@property(nonatomic) const char *peerAddress;
@property(nonatomic) const char *localAddress;
@property (strong, nonatomic) FileDataSource *FileDataSource;
@property(weak, nonatomic) IBOutlet UIButton *backButton;
@property(nonatomic, strong) IBOutlet ChatConversationTableView *tableController;
@property(weak, nonatomic) IBOutlet HPGrowingTextView *messageField;
@property(weak, nonatomic) IBOutlet UIView *topBar;
@property(nonatomic, strong) IBOutlet UIButton *sendButton;
@property(nonatomic, strong) IBOutlet UILabel *addressLabel;
@property(nonatomic, strong) IBOutlet UIView *chatView;
@property(nonatomic, strong) IBOutlet UIView *messageView;
@property(nonatomic, strong) IBOutlet UITapGestureRecognizer *listTapGestureRecognizer;
@property(nonatomic, strong) IBOutlet UISwipeGestureRecognizer *listSwipeGestureRecognizer;
@property(strong, nonatomic) IBOutlet UILabel *composeLabel;
@property(strong, nonatomic) IBOutlet UIView *composeIndicatorView;
@property(nonatomic, strong) IBOutlet UIButton *pictureButton;
@property(weak, nonatomic) IBOutlet UIButton *callButton;
@property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton;
@property (weak, nonatomic) IBOutlet UILabel *particpantsLabel;
@property NSMutableArray <NSNumber *> *qualitySettingsArray;
@property (weak, nonatomic) IBOutlet UICollectionView *imagesCollectionView;
@property (weak, nonatomic) IBOutlet UIView *imagesView;
@property (weak, nonatomic) IBOutlet UIButton *encryptedButton;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *toggleSelectionButton;
@property FileContext *fileContext;
@property (weak, nonatomic) IBOutlet UITableView *popupMenu;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *toggleMenuButton;
@property (weak, nonatomic) IBOutlet UIImageView *ephemeralndicator;
// Voice recording
@property (strong, nonatomic) IBOutlet UIView *vrView;
@property (weak, nonatomic) IBOutlet UIView *vrInnerView;
@property (weak, nonatomic) IBOutlet UIButton *vrDeleteButton;
@property (weak, nonatomic) IBOutlet UIButton *vrPlayButton;
@property (weak, nonatomic) IBOutlet UIImageView *vrWave;
@property (weak, nonatomic) IBOutlet UIView *vrWaveMask;
@property (weak, nonatomic) IBOutlet UIView *vrWaveMaskPlayer;
@property (weak, nonatomic) IBOutlet UILabel *vrDurationLabel;
@property NSTimer *vrRecordTimer;
@property NSTimer *vrPlayerTimer;
@property (weak, nonatomic) IBOutlet UIButton *toggleRecord;
@property BOOL isVoiceRecording;
@property BOOL isPendingVoiceRecord;
@property BOOL isPlayingVoiceRecording;
@property LinphoneRecorder *voiceRecorder;
@property LinphonePlayer *sharedVoicePlayer;
@property BOOL showVoiceRecorderView;
@property BOOL preservePendingActions;
@property BOOL *sharingMedia;
// Reply
@property (weak, nonatomic) IBOutlet UIView *replyView;
@property BOOL showReplyView;
@property UIChatReplyBubbleView *replyBubble;
// Forward
@property LinphoneChatMessage *pendingForwardMessage;
+ (void)markAsRead:(LinphoneChatRoom *)chatRoom;
+ (void)autoDownload:(LinphoneChatMessage *)message;
+(NSString *)getKeyFromFileType:(NSString *)fileType fileName:(NSString *)name;
+ (NSURL *)getFileUrl:(NSString *)name;
+ (void)writeFileInImagesDirectory:(NSData *)data name:(NSString *)name;
+ (NSData *)getFileData:(NSString *)name;
+ (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType;
+(UIImage *)getBasicImage;
+(UIImage*)drawText:(NSString*)text image:(UIImage *)image textSize:(CGFloat)textSize;
+(BOOL) isBasicChatRoom:(LinphoneChatRoom *)room;
- (void)configureForRoom:(BOOL)editing;
- (IBAction)onBackClick:(id)event;
- (IBAction)onEditClick:(id)event;
- (IBAction)onMessageChange:(id)sender;
- (IBAction)onSendClick:(id)event;
- (IBAction)onPictureClick:(id)event;
- (IBAction)onListTap:(id)sender;
- (IBAction)onCallClick:(id)sender;
- (IBAction)onDeleteClick:(id)sender;
- (IBAction)onEditionChangeClick:(id)sender;
- (IBAction)onEncryptedDevicesClick:(id)sender;
- (void)update;
- (void)openFileWithURL:(NSURL *)url;
- (void)openFileWithURLs:(NSMutableArray<NSURL *>*)urls index:(NSInteger)currentIndex;
- (void)clearMessageView;
- (void)configureMessageField;
- (void)showFileDownloadError;
- (NSURL *)getICloudFileUrl:(NSString *)name;
- (void)removeCallBacks;
-(void) startSharedPlayer:(const char *)path;
-(void) stopSharedPlayer;
-(BOOL) sharedPlayedIsPlaying:(const char *)path;
-(void) initiateReplyViewForMessage:(LinphoneChatMessage *)message;
-(void) stopVoiceRecording;
@end

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#include "linphone/linphonecore.h"
#include "UICheckBoxTableView.h"
@interface ChatsListTableView : UICheckBoxTableView
@property (nonatomic) NSInteger nbOfChatRoomToDelete;
@property (nonatomic) bctbx_list_t *chatRooms;
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property bctbx_list_t *data;
- (void)loadData;
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom;
@end

View file

@ -0,0 +1,283 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "ChatsListTableView.h"
#import "UIChatCell.h"
#import "FileTransferDelegate.h"
#import "linphone/linphonecore.h"
#import "PhoneMainView.h"
#import "Utils.h"
#import "SVProgressHUD.h"
@implementation ChatsListTableView
#pragma mark - Lifecycle Functions
- (instancetype)init {
self = super.init;
if (self) {
_data = nil;
_nbOfChatRoomToDelete = 0;
_waitView.hidden = TRUE;
}
return self;
}
- (void)dealloc {
bctbx_list_free(_data);
}
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.tableView.accessibilityIdentifier = @"Chat list";
[self loadData];
_chatRooms = NULL;
}
- (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 {
while (_chatRooms) {
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)_chatRooms->data;
if (!chatRoom)
continue;
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_current_callbacks(chatRoom);
if (cbs) {// If the view is getting changed while a chatroom deletion is in progress, the callbacks may already have been deleted despite the chatroom still being there, causing a potential crash.
linphone_chat_room_remove_callbacks(chatRoom, cbs);
}
_chatRooms = _chatRooms->next;
}
}
- (void)layoutSubviews {
[self.tableView layoutSubviews];
CGSize contentSize = self.tableView.contentSize;
contentSize.width = self.tableView.bounds.size.width;
self.tableView.contentSize = contentSize;
}
#pragma mark -
static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRoom *elem) {
time_t new = linphone_chat_room_get_last_update_time(to_insert);
time_t old = linphone_chat_room_get_last_update_time(elem);
if (new < old)
return 1;
else if (new > old)
return -1;
return 0;
}
- (MSList *)sortChatRooms {
MSList *sorted = nil;
const MSList *unsorted = linphone_core_get_chat_rooms(LC);
const MSList *iter = unsorted;
while (iter) {
// store last message in user data
LinphoneChatRoom *chat_room = iter->data;
sorted = bctbx_list_insert_sorted(sorted, chat_room, (bctbx_compare_func)sorted_history_comparison);
iter = iter->next;
}
return sorted;
}
- (void)loadData {
if (_data) bctbx_list_free(_data);
_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
if (idx != -1) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
} else if ([LinphoneManager.instance lpConfigBoolForKey:@"create_chat" withDefault:FALSE]) {
// if create chat, show the empty chat
[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)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
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return bctbx_list_size(_data);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"UIChatCell";
UIChatCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil)
cell = [[UIChatCell alloc] initWithIdentifier:kCellId];
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
return cell;
}
[cell setChatRoom:(LinphoneChatRoom *)bctbx_list_nth_data(_data, (int)[indexPath row])];
[super accessoryForCell:cell atPath:indexPath];
BOOL forwardMode = VIEW(ChatConversationView).pendingForwardMessage != nil;
cell.forwardIcon.hidden = !forwardMode;
if (forwardMode) {
cell.ephemeral.hidden = true;
cell.imdmIcon.hidden = true;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
return 86.0;
}
#pragma mark - UITableViewDelegate Functions
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
if ([self isEditing])
return;
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)bctbx_list_nth_data(_data, (int)[indexPath row]);
[PhoneMainView.instance goToChatRoom:chatRoom];
}
void deletion_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_current_callbacks(cr);
ChatsListTableView *view =cbs ? ((__bridge ChatsListTableView *)linphone_chat_room_cbs_get_user_data(cbs) ?: NULL) : NULL;
if (!view)
return;
if (newState == LinphoneChatRoomStateDeleted || newState == LinphoneChatRoomStateTerminationFailed) {
linphone_chat_room_remove_callbacks(cr, cbs);
view.chatRooms = bctbx_list_remove(view.chatRooms, cr);
view.nbOfChatRoomToDelete--;
}
if (view.nbOfChatRoomToDelete == 0) {
// will force a call to [self loadData]
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:view];
view.waitView.hidden = TRUE;
[SVProgressHUD dismiss];
}
}
- (void) deleteChatRooms {
_waitView.hidden = FALSE;
[SVProgressHUD show];
bctbx_list_t *chatRooms = bctbx_list_copy(_chatRooms);
while (chatRooms) {
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)chatRooms->data;
if (!chatRoom)
continue;
_nbOfChatRoomToDelete++;
LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, deletion_chat_room_state_changed);
linphone_chat_room_cbs_set_user_data(cbs, (__bridge void*)self);
linphone_chat_room_add_callbacks(chatRoom, cbs);
FileTransferDelegate *ftdToDelete = nil;
for (FileTransferDelegate *ftd in [LinphoneManager.instance fileTransferDelegates]) {
if (linphone_chat_message_get_chat_room(ftd.message) == chatRoom) {
ftdToDelete = ftd;
break;
}
}
[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;
}
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)bctbx_list_nth_data(_data, (int)[indexPath row]);
NSString *msg = (LinphoneChatRoomCapabilitiesOneToOne & linphone_chat_room_get_capabilities(chatRoom))
? [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete this conversation?", nil)]
: [NSString stringWithFormat:NSLocalizedString(@"Do you want to leave and delete this conversation?", nil)];
[UIConfirmationDialog ShowWithMessage:msg
cancelMessage:nil
confirmMessage:nil
onCancelClick:^() {}
onConfirmationClick:^() {
_chatRooms = bctbx_list_new((void *)chatRoom);
[self deleteChatRooms];
}];
}
}
- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover {
_chatRooms = NULL;
// we must iterate through selected items in reverse order
[self.selectedItems sortUsingComparator:^(NSIndexPath *obj1, NSIndexPath *obj2) {
return [obj2 compare:obj1];
}];
NSArray *copy = [[NSArray alloc] initWithArray:self.selectedItems];
for (NSIndexPath *indexPath in copy) {
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)bctbx_list_nth_data(_data, (int)[indexPath row]);
_chatRooms = bctbx_list_append(_chatRooms, chatRoom);
}
[self deleteChatRooms];
[self.selectedItems removeAllObjects];
[self setEditing:NO animated:YES];
}
@end

48
Classes/ChatsListView.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import "UIToggleButton.h"
#import "ChatsListTableView.h"
#import "UICompositeView.h"
#import "UIBackToCallButton.h"
@interface ChatsListView : UIViewController <UICompositeViewDelegate> {
}
@property(nonatomic, strong) IBOutlet ChatsListTableView *tableController;
@property(weak, nonatomic) IBOutlet UIButton *addButton;
@property (weak, nonatomic) IBOutlet UIButton *addGroupChatButton;
@property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton;
@property (weak, nonatomic) IBOutlet UIView *waitView;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *toggleSelectionButton;
@property (weak, nonatomic) IBOutlet UILabel *forwardTitle;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *cancelForwardButton;
- (IBAction)onAddGroupChatClick:(id)event;
- (IBAction)onAddClick:(id)event;
- (IBAction)onEditionChangeClick:(id)sender;
- (IBAction)onDeleteClick:(id)sender;
-(void) mediaSharing;
@end

215
Classes/ChatsListView.m Normal file
View file

@ -0,0 +1,215 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "ChatsListView.h"
#import "PhoneMainView.h"
#import "ChatConversationCreateView.h"
@implementation ChatsListView
#pragma mark - ViewController Functions
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(textReceivedEvent:)
name:kLinphoneMessageReceived
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
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];
LinphoneAccount *defaultAccount = linphone_core_get_default_account(LC);
_addGroupChatButton.hidden = !(defaultAccount && linphone_account_params_get_conference_factory_uri(linphone_account_get_params(defaultAccount)));
[_toggleSelectionButton setImage:[UIImage imageNamed:@"select_all_default.png"] forState:UIControlStateSelected];
// For testing crashlytics
/*UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(20, 50, 100, 30);
[button setTitle:@"Crash" forState:UIControlStateNormal];
[button addTarget:self action:@selector(crashButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];*/
[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(ChatConversationView).sharingMedia = TRUE;
if(VIEW(ChatConversationView).sharingMedia == nil){
forwardMode = VIEW(ChatConversationView).pendingForwardMessage != nil;
}else{
forwardMode = VIEW(ChatConversationView).sharingMedia != nil;
}
_tableController.editButton.hidden = forwardMode;
if(VIEW(ChatConversationView).sharingMedia == nil){
_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];
[self.tableController loadData];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[NSNotificationCenter.defaultCenter removeObserver:self];
self.view = NULL;
}
#pragma mark - Event Functions
- (void)textReceivedEvent:(NSNotification *)notif {
[_tableController loadData];
}
- (void)callUpdateEvent:(NSNotification *)notif {
[_backToCallButton update];
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:TabBarView.class
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:YES
fragmentWith:ChatConversationCreateView.class];
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
return self.class.compositeViewDescription;
}
#pragma mark - Action Functions
- (void)newChatCreate:(BOOL)isGroup {
ChatConversationCreateView *view = VIEW(ChatConversationCreateView);
[view fragmentCompositeDescription];
view.isForEditing = false;
view.isGroupChat = isGroup;
view.tableController.notFirstTime = FALSE;
view.isForVoipConference = FALSE;
[view.tableController.contactsGroup removeAllObjects];
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
- (IBAction)onAddGroupChatClick:(id)event {
[self newChatCreate:TRUE];
if (IPAD)
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil];
}
- (IBAction)onAddClick:(id)event {
[self newChatCreate:FALSE];
if (IPAD)
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil];
}
- (IBAction)onEditionChangeClick:(id)sender {
_addButton.hidden = _addGroupChatButton.hidden = self.tableController.isEditing;
[_backToCallButton update];
}
- (IBAction)onDeleteClick:(id)sender {
BOOL group = false;
NSArray *copy = [[NSArray alloc] initWithArray:_tableController.selectedItems];
for (NSIndexPath *indexPath in copy) {
LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)bctbx_list_nth_data(_tableController.data, (int)[indexPath row]);
if (LinphoneChatRoomCapabilitiesConference & linphone_chat_room_get_capabilities(chatRoom)) {
group = true;
break;
}
}
NSString *msg = group
? [NSString stringWithFormat:NSLocalizedString(@"Do you want to leave and delete the selected conversations?", nil)]
: [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete the selected conversations?", nil)];
[UIConfirmationDialog ShowWithMessage:msg
cancelMessage:nil
confirmMessage:nil
onCancelClick:^() {
[self onEditionChangeClick:nil];
}
onConfirmationClick:^() {
[_tableController removeSelectionUsing:nil];
[self onEditionChangeClick:nil];
}];
}
- (IBAction)crashButtonTapped:(id)sender {
assert(NO);
}
- (IBAction)onCancelForwardClicked:(id)sender {
VIEW(ChatConversationView).sharingMedia = nil;
VIEW(ChatConversationView).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

63
Classes/Contact.h Normal file
View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <AddressBook/AddressBook.h>
#import <Contacts/Contacts.h>
#import <Foundation/Foundation.h>
#include <linphone/linphonecore.h>
@interface Contact : NSObject
//@property(nonatomic, readonly) ABRecordRef person;
@property(nonatomic, readonly) CNContact *person;
@property(nonatomic, readonly) LinphoneFriend *friend;
@property(nonatomic, retain) NSString *identifier;
@property(nonatomic, retain) NSString *firstName;
@property(nonatomic, retain) NSString *lastName;
@property(nonatomic, retain) NSString *displayName;
@property(nonatomic, strong) NSMutableArray *sipAddresses;
@property(nonatomic, strong) NSMutableArray *emails;
@property(nonatomic, strong) NSMutableArray *phones;
@property BOOL createdFromLdapOrProvisioning;
@property BOOL added;
- (void)setAvatar:(UIImage *)avatar;
- (UIImage *)avatar;
- (NSString *)displayName;
- (instancetype)initWithCNContact:(CNContact *)contact;
- (instancetype)initWithFriend:(LinphoneFriend *) friend;
- (void)reloadFriend;
- (void)clearFriend;
- (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index;
- (BOOL)setEmail:(NSString *)email atIndex:(NSInteger)index;
- (BOOL)setPhoneNumber:(NSString *)phone atIndex:(NSInteger)index;
- (BOOL)addSipAddress:(NSString *)sip;
- (BOOL)addEmail:(NSString *)email;
- (BOOL)addPhoneNumber:(NSString *)phone;
- (BOOL)removeSipAddressAtIndex:(NSInteger)index;
- (BOOL)removePhoneNumberAtIndex:(NSInteger)index;
- (BOOL)removeEmailAtIndex:(NSInteger)index;
- (NSMutableArray*)getSipAddressesWithoutDuplicatePhoneNumbers;
@end

512
Classes/Contact.m Normal file
View file

@ -0,0 +1,512 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "Contact.h"
#import "ContactsListView.h"
@implementation Contact
- (instancetype)initWithCNContact:(CNContact *)acncontact {
return [self initWithPerson:acncontact andFriend:NULL];
}
- (instancetype)initWithFriend:(LinphoneFriend *)afriend {
return [self initWithPerson:NULL andFriend:afriend];
}
- (instancetype)initWithPerson:(CNContact *)acncontact
andFriend:(LinphoneFriend *)afriend {
self = [super init];
_person = acncontact;
_friend = afriend ? linphone_friend_ref(afriend) : NULL;
_added = FALSE;
_createdFromLdapOrProvisioning = FALSE;
_phones = [[NSMutableArray alloc] init];
_sipAddresses = [[NSMutableArray alloc] init];
_emails = [[NSMutableArray alloc] init];
if (_person) {
_identifier = _person.identifier;
_firstName = _person.givenName;
_lastName = _person.familyName;
_displayName = [NSString stringWithFormat:@"%@ %@", _firstName, _lastName];
for (CNLabeledValue<CNPhoneNumber *> *phoneNumber in _person.phoneNumbers) {
[_phones addObject:phoneNumber.value.stringValue];
}
if ([_person respondsToSelector:NSSelectorFromString( CNInstantMessageAddressUsernameKey)] || [_person respondsToSelector:NSSelectorFromString(CNContactInstantMessageAddressesKey)]) {
if (_person.instantMessageAddresses != NULL) {
for (CNLabeledValue<CNInstantMessageAddress *> *sipAddr in _person.instantMessageAddresses) {
if ([FastAddressBook isSipAddress:sipAddr]) {
NSString *username = sipAddr.value.username;
[_sipAddresses addObject:username];
}
}
}
}
for (CNLabeledValue<NSString *> *email in _person.emailAddresses) {
[_emails addObject:email.value];
}
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_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_2(LC, sipAddr.UTF8String, true);
if (addr) {
linphone_address_set_display_name(addr, [self displayName].UTF8String);
linphone_friend_add_address(_friend, addr);
linphone_address_destroy(addr);
}
}
for (NSString *phone in _phones) {
linphone_friend_add_phone_number(_friend, phone.UTF8String);
}
if (_friend) {
linphone_friend_enable_subscribes(_friend, FALSE);
linphone_friend_set_inc_subscribe_policy(_friend, LinphoneSPDeny);
linphone_core_add_friend(LC, _friend);
}
}else linphone_friend_ref(_friend);
} else if (_friend) {
[self loadFriend];
} else {
LOGE(@"Contact cannot be initialized");
return nil;
}
/* LOGI(@"Contact %@ %@ initialized with %d phones, %d sip, %d emails",
self.firstName ?: @"", self.lastName ?: @"", self.phones.count,
self.sipAddresses.count, self.emails.count);
*/
return self;
}
- (void)dealloc {
if (_friend) {
linphone_friend_unref(_friend);
}
_person = nil;
_friend = NULL;
}
#pragma mark - Getters
- (UIImage *)avatar {
@try {
if (_person)
return [UIImage imageWithData:_person.imageData];
} @catch (NSException *e) {
LOGE(@"CNContact imageData CNPropertyNotFetchedException : %@", e);
}
return nil;
}
- (NSString *)displayName {
if (_friend) {
const char *friend_name = linphone_friend_get_name(_friend);
if (friend_name)
return [NSString stringWithUTF8String:friend_name];
}
if (_person) {
NSString *lFirstName = _person.givenName;
NSString *lLocalizedFirstName = [FastAddressBook localizedLabel:lFirstName];
NSString *compositeName = _person.nickname;
NSString *lLastName = _person.familyName;
NSString *lLocalizedLastName = [FastAddressBook localizedLabel:lLastName];
NSString *lOrganization = _person.organizationName;
NSString *lLocalizedOrganization = [FastAddressBook localizedLabel:lOrganization];
if (compositeName && ![compositeName isEqualToString:@""])
return compositeName;
if (lLocalizedFirstName || lLocalizedLastName)
return [NSString stringWithFormat:@"%@ %@", lLocalizedFirstName, lLocalizedLastName];
return (NSString *)lLocalizedOrganization;
}
BOOL firstName = _firstName && ![_firstName isEqualToString:@""];
BOOL lastName = _lastName && ![_lastName isEqualToString:@""];
if (lastName || firstName) {
NSMutableString *str = NULL;
if (firstName) {
str = [_firstName copy];
if (lastName)
[str appendFormat:@" %@", _lastName];
return str;
}
str = [_lastName copy];
return str;
}
return NSLocalizedString(@"Unknown", nil);
}
#pragma mark - Setters
- (void)setAvatar:(UIImage *)avatar {
if (!_person) {
LOGW(@"%s: Cannot do it when using LinphoneFriend, skipping", __FUNCTION__);
return;
}
NSData *imageAvatar = UIImageJPEGRepresentation(avatar, 0.9f);
[_person setValue:imageAvatar forKey:CNContactImageDataKey];
}
- (void)setFirstName:(NSString *)firstName {
BOOL ret = FALSE;
if ([firstName isEqualToString:_firstName])
return;
if (_friend)
ret = linphone_friend_set_name(_friend, [NSString stringWithFormat:@"%@ %@", firstName,_person.familyName].UTF8String);
if (_person) {
[_person setValue:firstName forKey:CNContactGivenNameKey];
[_person setValue:[NSString stringWithFormat:@"%@ %@", firstName, _person.familyName] forKey:CNContactNicknameKey];
ret = TRUE;
}
if (ret) {
_firstName = firstName;
_displayName = [NSString stringWithFormat:@"%@ %@", firstName, _person.familyName];
}
}
- (void)setLastName:(NSString *)lastName {
BOOL ret = FALSE;
if ([lastName isEqualToString:_lastName])
return;
if (_friend)
ret = linphone_friend_set_name(_friend, [NSString stringWithFormat:@"%@ %@", _person.givenName, lastName].UTF8String);
if (_person) {
[_person setValue:lastName forKey:CNContactFamilyNameKey];
[_person setValue:[NSString stringWithFormat:@"%@ %@", _person.givenName, lastName] forKey:CNContactNicknameKey];
ret = TRUE;
}
if (ret) {
_lastName = lastName;
_displayName = [NSString stringWithFormat:@"%@ %@", _person.givenName, lastName];
}
}
- (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index {
if (!_person || [sip isEqualToString:@" "]) {
LOGW(@"%s: Cannot do it when using LinphoneFriend, skipping", __FUNCTION__);
return FALSE;
}
NSString *normSip = [sip hasPrefix:@" "] ? [sip substringFromIndex:1] : sip;
normSip = [normSip hasPrefix:@"sip:"] ? [normSip substringFromIndex:4] : normSip;
CNInstantMessageAddress *cNSipMsgAddr = [[CNInstantMessageAddress alloc] initWithUsername:normSip service:@"SIP"];
CNLabeledValue *sipAddress = [CNLabeledValue labeledValueWithLabel:NULL value:cNSipMsgAddr];
NSMutableArray<CNLabeledValue<CNInstantMessageAddress *> *> *tmpSipAddresses = [_person.instantMessageAddresses mutableCopy];
if ((index + 1) > [_person.instantMessageAddresses count])
[tmpSipAddresses addObject:sipAddress];
else
[tmpSipAddresses replaceObjectAtIndex:index withObject:sipAddress];
[_person setValue:tmpSipAddresses forKey:CNContactInstantMessageAddressesKey];
_sipAddresses[index] = normSip;
return TRUE;
}
- (BOOL)setPhoneNumber:(NSString *)phone atIndex:(NSInteger)index {
if (!_person) {
LOGW(@"%s: Cannot do it when using LinphoneFriend, skipping", __FUNCTION__);
return FALSE;
}
CNLabeledValue *mobileNumber = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile value:[CNPhoneNumber phoneNumberWithStringValue:phone]];
NSMutableArray<CNLabeledValue<CNPhoneNumber *> *> *tmpPhoneNumbers = [_person.phoneNumbers mutableCopy];
if ((index + 1) > [_person.phoneNumbers count])
[tmpPhoneNumbers addObject:mobileNumber];
else
[tmpPhoneNumbers replaceObjectAtIndex:index withObject:mobileNumber];
[_person setValue:tmpPhoneNumbers forKey:CNContactPhoneNumbersKey];
_phones[index] = phone;
return TRUE;
}
- (BOOL)setEmail:(NSString *)email atIndex:(NSInteger)index {
if (!_person) {
LOGW(@"%s: Cannot do it when using LinphoneFriend, skipping", __FUNCTION__);
return FALSE;
}
CNLabeledValue *emailAddress = [CNLabeledValue labeledValueWithLabel:NULL value:email];
NSMutableArray<CNLabeledValue<NSString *> *> *tmpEmailAddress = [_person.emailAddresses mutableCopy];
if ((index + 1) > [_person.emailAddresses count])
[tmpEmailAddress addObject:emailAddress];
else
[tmpEmailAddress replaceObjectAtIndex:index withObject:emailAddress];
[_person setValue:tmpEmailAddress forKey:CNContactEmailAddressesKey];
_emails[index] = email;
return TRUE;
}
- (BOOL)addSipAddress:(NSString *)sip {
BOOL ret = TRUE;
NSString *normSip = NULL;
if (sip == NULL || [sip isEqualToString:@""])
return FALSE;
if (![sip isEqualToString:@" "]) {
if (_person) {
normSip = [sip containsString:@"@"] ? [sip componentsSeparatedByString:@"@"][0] : sip;
CNInstantMessageAddress *cNSipMsgAddr;
cNSipMsgAddr = [[CNInstantMessageAddress alloc] initWithUsername:normSip service:@"SIP"]; //service:[normSip componentsSeparatedByString:@"@"][1]];
CNLabeledValue *sipAddress = [CNLabeledValue labeledValueWithLabel:NULL value:cNSipMsgAddr];
NSMutableArray<CNLabeledValue<CNInstantMessageAddress *> *> *tmpSipAddresses = [_person.instantMessageAddresses mutableCopy];
[tmpSipAddresses addObject:sipAddress];
[_person setValue:tmpSipAddresses forKey:CNContactInstantMessageAddressesKey];
ret = TRUE;
} else {
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, sip.UTF8String, true) ?: linphone_address_new(sip.UTF8String);
if (!addr)
return FALSE;
linphone_friend_add_address(_friend, addr);
linphone_address_destroy(addr);
// ensure that it was added by checking list size
ret = (bctbx_list_size(linphone_friend_get_addresses(_friend)) == _sipAddresses.count + 1);
}
}
if (ret) {
if ([sip hasPrefix:@" "])
[_sipAddresses addObject:[sip substringFromIndex:1]];
else
[_sipAddresses addObject:sip];
}
return ret;
}
- (BOOL)addPhoneNumber:(NSString *)phone {
BOOL ret = TRUE;
if (phone == NULL || [phone isEqualToString:@""])
return FALSE;
if (![phone isEqualToString:@" "]){
if (_person) {
CNLabeledValue *mobileNumber = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile
value:[CNPhoneNumber phoneNumberWithStringValue:phone]];
NSMutableArray<CNLabeledValue<CNPhoneNumber *> *>*tmpPhoneNumbers = [_person.phoneNumbers mutableCopy];
[tmpPhoneNumbers addObject:mobileNumber];
[_person setValue:tmpPhoneNumbers forKey:CNContactPhoneNumbersKey];
ret = TRUE;
} else {
char *cphone = ms_strdup(phone.UTF8String);
if (!cphone)
return FALSE;
linphone_friend_add_phone_number(_friend, cphone);
phone = [NSString stringWithUTF8String:cphone];
ms_free(cphone);
// ensure that it was added by checking list size
ret = (bctbx_list_size(linphone_friend_get_phone_numbers( _friend)) == _phones.count + 1);
}
}
if (ret)
[_phones addObject:phone];
return ret;
}
- (BOOL)addEmail:(NSString *)email {
if (email == NULL || [email isEqualToString:@""])
return FALSE;
if (![email isEqualToString:@" "]) {
if (!_person) {
LOGW(@"%s: Cannot do it when using LinphoneFriend, skipping", __FUNCTION__);
return FALSE;
}
CNLabeledValue *emailAddress = [CNLabeledValue labeledValueWithLabel:NULL value:email];
NSMutableArray<CNLabeledValue<NSString *> *> *tmpEmailAddress = [_person.emailAddresses mutableCopy];
[tmpEmailAddress addObject:emailAddress];
[_person setValue:tmpEmailAddress forKey:CNContactEmailAddressesKey];
}
[_emails addObject:email];
return TRUE;
}
- (BOOL)removeSipAddressAtIndex:(NSInteger)index {
BOOL ret = FALSE;
if (_person) {
NSMutableArray<CNLabeledValue<CNInstantMessageAddress *> *>*tmpSipAddress = [_person.instantMessageAddresses mutableCopy];
if ([tmpSipAddress count] > index) {
[tmpSipAddress removeObjectAtIndex:index];
[_person setValue:tmpSipAddress forKey:CNContactInstantMessageAddressesKey];
}
ret = TRUE;
} else {
LinphoneAddress *addr = linphone_core_interpret_url_2(LC, ((NSString *)_sipAddresses[index]).UTF8String, true);
if (!addr)
return FALSE;
linphone_friend_remove_address(_friend, addr);
linphone_address_destroy(addr);
// ensure that it was destroyed by checking list size
ret = (bctbx_list_size(linphone_friend_get_addresses(_friend)) + 1 == _sipAddresses.count);
}
if (ret)
[_sipAddresses removeObjectAtIndex:index];
return ret;
}
- (BOOL)removePhoneNumberAtIndex:(NSInteger)index {
BOOL ret = FALSE;
if (_person && _person.phoneNumbers.count > 0) {
NSMutableArray<CNLabeledValue<CNPhoneNumber *> *> *tmpPhoneNumbers = [_person.phoneNumbers mutableCopy];
if ([tmpPhoneNumbers count] > index) {
[tmpPhoneNumbers removeObjectAtIndex:index];
[_person setValue:tmpPhoneNumbers forKey:CNContactPhoneNumbersKey];
}
ret = TRUE;
} else {
const char *phone = ((NSString *)_phones[index]).UTF8String;
linphone_friend_remove_phone_number(_friend, phone);
// ensure that it was destroyed by checking list size
ret = (bctbx_list_size(linphone_friend_get_phone_numbers(_friend)) + 1 == _phones.count);
}
if (ret)
[_phones removeObjectAtIndex:index];
return ret;
}
- (BOOL)removeEmailAtIndex:(NSInteger)index {
if (!_person || _person.phoneNumbers.count == 0) {
LOGW(@"%s: Cannot do it when using LinphoneFriend, skipping", __FUNCTION__);
return FALSE;
}
NSMutableArray<CNLabeledValue<NSString *> *> *tmpEmailAddresses = [_person.emailAddresses mutableCopy];
if ([tmpEmailAddresses count] > index) {
[tmpEmailAddresses removeObjectAtIndex:index];
[_person setValue:tmpEmailAddresses forKey:CNContactEmailAddressesKey];
}
[_emails removeObjectAtIndex:index];
return TRUE;
}
#pragma mark - LinphoneFriend utils
- (void)loadFriend {
// First and Last name
_firstName = [NSString stringWithUTF8String:linphone_friend_get_name(_friend) ?: ""];
_lastName = nil;
// Phone numbers
_phones = [[NSMutableArray alloc] init];
MSList *numbers = linphone_friend_get_phone_numbers(_friend);
while (numbers) {
NSString *phone = [NSString stringWithUTF8String:numbers->data];
[_phones addObject:phone];
numbers = numbers->next;
}
// SIP (IM)
_sipAddresses = [[NSMutableArray alloc] init];
const MSList *sips = linphone_friend_get_addresses(_friend);
while (sips) {
LinphoneAddress *addr = sips->data;
char *uri = linphone_address_as_string_uri_only(addr);
NSString *sipaddr = [NSString stringWithUTF8String:uri];
[_sipAddresses addObject:sipaddr];
ms_free(uri);
sips = sips->next;
}
// Email - no support for LinphoneFriend
_emails = [[NSMutableArray alloc] init];
}
- (void)reloadFriend {
const char *key = [NSString stringWithFormat:@"ab%@", _person.identifier].UTF8String;
// 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_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_2(LC, sipAddr.UTF8String, true);
if (addr) {
linphone_address_set_display_name(addr, [self displayName].UTF8String);
linphone_friend_add_address(_friend, addr);
linphone_address_destroy(addr);
}
}
for (NSString *phone in _phones) {
linphone_friend_add_phone_number(_friend, phone.UTF8String);
}
if (_friend) {
linphone_friend_enable_subscribes(_friend, FALSE);
linphone_friend_set_inc_subscribe_policy(_friend, LinphoneSPDeny);
linphone_core_add_friend(LC, _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

@ -0,0 +1,47 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import "Contact.h"
#import "LinphoneUI/UIToggleButton.h"
typedef enum _ContactSections {
ContactSections_None = 0, // first section is empty because we cannot set header for first section
ContactSections_FirstName,
ContactSections_LastName,
ContactSections_Sip,
ContactSections_Number,
ContactSections_Email,
ContactSections_MAX
} ContactSections;
@interface ContactDetailsTableView : UITableViewController <UITextFieldDelegate>
@property(strong, nonatomic) Contact *contact;
@property(weak, nonatomic) IBOutlet UIToggleButton *editButton;
- (void)addPhoneField:(NSString *)number;
- (void)addSipField:(NSString *)address;
- (void)addEmailField:(NSString *)address;
- (void)setContact:(Contact *)contact;
@property (weak, nonatomic) UIView *waitView;
@end

View file

@ -0,0 +1,454 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "ContactDetailsTableView.h"
#import "PhoneMainView.h"
#import "UIContactDetailsCell.h"
#import "Utils.h"
#import "OrderedDictionary.h"
@implementation ContactDetailsTableView
#pragma mark - Property Functions
- (NSMutableArray *)getSectionData:(NSInteger)section {
if (section == ContactSections_Number) {
return _contact.phones;
} else if (section == ContactSections_Sip) {
return _contact.sipAddresses;
} else if (section == ContactSections_Email) {
if ([LinphoneManager.instance
lpConfigBoolForKey:@"show_contacts_emails_preference"] ==
true) {
return _contact.emails;
}
}
return nil;
}
- (void)removeEmptyEntry:(UITableView *)tableview section:(NSInteger)section animated:(BOOL)animated {
NSMutableArray *sectionDict = [self getSectionData:section];
for (NSInteger i = sectionDict.count - 1; i >= 0; i--) {
NSString *value = sectionDict[i];
if (value.length == 0) {
[self removeEntry:tableview indexPath:[NSIndexPath indexPathForRow:i inSection:section] animated:animated];
}
}
}
- (void)removeEntry:(UITableView *)tableview indexPath:(NSIndexPath *)path animated:(BOOL)animated {
bool rmed = YES;
if (path.section == ContactSections_Number) {
rmed = [_contact removePhoneNumberAtIndex:path.row];
} else if (path.section == ContactSections_Sip) {
rmed = [_contact removeSipAddressAtIndex:path.row];
} else if (path.section == ContactSections_Email) {
rmed = [_contact removeEmailAtIndex:path.row];
} else {
rmed = NO;
}
if (rmed) {
[tableview deleteRowsAtIndexPaths:@[ path ]
withRowAnimation:animated ? UITableViewRowAnimationFade : UITableViewRowAnimationNone];
} else {
LOGW(@"Cannot remove entry at path %@, skipping", path);
}
}
- (void)addEntry:(UITableView *)tableview section:(NSInteger)section animated:(BOOL)animated value:(NSString *)value {
bool added = FALSE;
if (section == ContactSections_Number) {
if ([_contact.phones count] == [_contact.person.phoneNumbers count])
added = [_contact addPhoneNumber:value];
} else if (section == ContactSections_Sip) {
if ([_contact.sipAddresses count] == [self countSipAddressFromCNContact:_contact.person]) //[_contact.person.instantMessageAddresses count])
added = [_contact addSipAddress:value];
} else if (section == ContactSections_Email) {
if ([_contact.emails count] ==
[_contact.person.emailAddresses count])
added = [_contact addEmail:value];
}
if (added) {
NSUInteger count = [self getSectionData:section].count;
[tableview
insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:count - 1
inSection:section] ]
withRowAnimation:animated ? UITableViewRowAnimationFade
: UITableViewRowAnimationNone];
} else {
LOGW(@"Cannot add entry '%@' in section %d, skipping", value,
section);
}
}
-(NSInteger)countSipAddressFromCNContact:(CNContact*) mCNContact{
NSInteger count = 0;
if (mCNContact.instantMessageAddresses != NULL) {
for (CNLabeledValue<CNInstantMessageAddress *> *sipAddr in mCNContact.instantMessageAddresses) {
if ([FastAddressBook isSipAddress:sipAddr])
count++;
}
}
return count;
}
- (void)setContact:(Contact *)acontact {
// if (acontact == _contact)
// return;
_contact = acontact;
[self loadData];
}
- (void)addPhoneField:(NSString *)number {
ContactSections i = 0;
while (i != ContactSections_MAX && i != ContactSections_Number)
++i;
[self addEntry:[self tableView] section:i animated:FALSE value:number];
}
- (void)addSipField:(NSString *)address {
ContactSections i = 0;
while (i != ContactSections_MAX && i != ContactSections_Sip)
++i;
[self addEntry:[self tableView] section:i animated:FALSE value:address];
}
- (void)addEmailField:(NSString *)address {
ContactSections i = 0;
while (i != ContactSections_MAX && i != ContactSections_Email)
++i;
[self addEntry:[self tableView] section:i animated:FALSE value:address];
}
- (BOOL)isValid {
BOOL hasName = (_contact.firstName.length + _contact.lastName.length > 0);
BOOL hasAddr =
(_contact.phones.count + _contact.sipAddresses.count) > 0;
return hasName && hasAddr;
}
#pragma mark - UITableViewDataSource Functions
- (void)loadData {
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return ContactSections_MAX;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == ContactSections_FirstName || section == ContactSections_LastName) {
/*first and last name only when editting */
return (self.tableView.isEditing) ? 1 : 0;
} else if (section == ContactSections_Sip) {
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;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellId = @"UIContactDetailsCell";
UIContactDetailsCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[UIContactDetailsCell alloc] initWithIdentifier:kCellId];
cell.waitView = _waitView;
[cell.editTextfield setDelegate:self];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.indexPath = indexPath;
[cell hideDeleteButton:NO];
[cell.editTextfield setKeyboardType:UIKeyboardTypeDefault];
NSString *value = @"";
if (indexPath.section == ContactSections_FirstName) {
value = _contact.firstName;
[cell hideDeleteButton:YES];
} else if (indexPath.section == ContactSections_LastName) {
value = _contact.lastName;
[cell hideDeleteButton:YES];
} else if ([indexPath section] == ContactSections_Number) {
value = _contact.phones[indexPath.row];
[cell.editTextfield setKeyboardType:UIKeyboardTypePhonePad];
} else if ([indexPath section] == ContactSections_Sip) {
value = _contact.sipAddresses[indexPath.row];
LinphoneAddress *addr = NULL;
if ([LinphoneManager.instance
lpConfigBoolForKey:@"contact_display_username_only"] &&
(addr = linphone_core_interpret_url_2(LC, [value UTF8String], YES))) {
value =
[NSString stringWithCString:linphone_address_get_username(addr)
encoding:[NSString defaultCStringEncoding]];
linphone_address_destroy(addr);
}
[cell.editTextfield setKeyboardType:UIKeyboardTypeASCIICapable];
} else if ([indexPath section] == ContactSections_Email) {
value = _contact.emails[indexPath.row];
[cell.editTextfield setKeyboardType:UIKeyboardTypeEmailAddress];
}
if ([value hasPrefix:@" "])
value = [value substringFromIndex:1];
[cell setAddress:value];
cell.contentView.userInteractionEnabled = false;
return cell;
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
[LinphoneUtils findAndResignFirstResponder:[self tableView]];
if (editingStyle == UITableViewCellEditingStyleInsert) {
[tableView beginUpdates];
[self addEntry:tableView
section:[indexPath section]
animated:TRUE
value:@" "];
[tableView endUpdates];
} else if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
[self removeEntry:tableView indexPath:indexPath animated:TRUE];
[tableView endUpdates];
}
}
#pragma mark - UITableViewDelegate Functions
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
BOOL showEmails = [LinphoneManager.instance lpConfigBoolForKey:@"show_contacts_emails_preference"];
if (editing) {
// add phone/SIP/email entries so that the user can add new data
for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) {
if (section == ContactSections_Number || section == ContactSections_Sip ||
(showEmails && section == ContactSections_Email)) {
[self addEntry:self.tableView section:section animated:animated value:@""];
}
}
_editButton.enabled = [self isValid];
} else {
[LinphoneUtils findAndResignFirstResponder:[self tableView]];
// remove empty phone numbers
for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) {
// remove phony entries that were not filled by the user
if (section == ContactSections_Number || section == ContactSections_Sip ||
(showEmails && section == ContactSections_Email)) {
[self removeEmptyEntry:self.tableView section:section animated:NO];
}
}
_editButton.enabled = YES;
}
// order is imported here: empty rows must be deleted before table change editing mode
[super setEditing:editing animated:animated];
[self loadData];
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *text = nil;
BOOL canAddEntry = self.tableView.isEditing;
NSString *addEntryName = nil;
if (section == ContactSections_FirstName && self.tableView.isEditing) {
text = NSLocalizedString(@"First name", nil);
canAddEntry = NO;
} else if (section == ContactSections_LastName && self.tableView.isEditing) {
text = NSLocalizedString(@"Last name", 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.createdFromLdapOrProvisioning) {
text = NSLocalizedString(@"SIP addresses", nil);
addEntryName = NSLocalizedString(@"Add new SIP address", nil);
} else if (section == ContactSections_Email &&
[LinphoneManager.instance lpConfigBoolForKey:@"show_contacts_emails_preference"]) {
text = NSLocalizedString(@"Email addresses", nil);
addEntryName = NSLocalizedString(@"Add new email", nil);
}
}
if (!text) {
return nil;
}
CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, 30);
UIView *tempView = [[UIView alloc] initWithFrame:frame];
if (@available(iOS 13, *)) {
tempView.backgroundColor = [UIColor systemBackgroundColor];
} else {
tempView.backgroundColor = [UIColor whiteColor];
}
UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame];
tempLabel.backgroundColor = [UIColor clearColor];
tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_E.png"]];
tempLabel.text = text.uppercaseString;
tempLabel.textAlignment = NSTextAlignmentCenter;
tempLabel.font = [UIFont systemFontOfSize:15];
tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[tempView addSubview:tempLabel];
if (canAddEntry) {
frame.origin.x = (tableView.frame.size.width - 30 /*image size*/) / 2 - 5 /*right offset*/;
UIIconButton *tempAddButton = [[UIIconButton alloc] initWithFrame:frame];
[tempAddButton setImage:[UIImage imageNamed:@"add_field_default.png"] forState:UIControlStateNormal];
[tempAddButton setImage:[UIImage imageNamed:@"add_field_over.png"] forState:UIControlStateHighlighted];
[tempAddButton setImage:[UIImage imageNamed:@"add_field_over.png"] forState:UIControlStateSelected];
[tempAddButton addTarget:self action:@selector(onAddClick:) forControlEvents:UIControlEventTouchUpInside];
tempAddButton.tag = section;
tempAddButton.accessibilityLabel = addEntryName;
tempAddButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[tempView addSubview:tempAddButton];
}
return tempView;
}
- (void)onAddClick:(id)sender {
NSInteger section = ((UIButton *)sender).tag;
UITableView *tableView = VIEW(ContactDetailsView).tableController.tableView;
NSInteger count = [self.tableView numberOfRowsInSection:section];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:count inSection:section];
[tableView.dataSource tableView:tableView
commitEditingStyle:UITableViewCellEditingStyleInsert
forRowAtIndexPath:indexPath];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView.isEditing) {
return 44;
} else {
return 88;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 1e-5;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == 0 ||
(!self.tableView.isEditing && (section == ContactSections_FirstName || section == ContactSections_LastName))) {
return 1e-5;
}
return [self tableView:tableView viewForHeaderInSection:section].frame.size.height;
}
#pragma mark - UITextFieldDelegate Functions
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)textFieldUpdated:(UITextField *)textField {
UIView *view = [textField superview];
while (view != nil && ![view isKindOfClass:[UIContactDetailsCell class]])
view = [view superview];
if (view != nil) {
UIContactDetailsCell *cell = (UIContactDetailsCell *)view;
// we cannot use indexPathForCell method here because if the cell is not visible anymore,
// it will return nil..
NSIndexPath *path = [self.tableView indexPathForCell:cell]; // [self.tableView indexPathForCell:cell];
ContactSections sect = (ContactSections)[path section];
NSString *value = [textField text];
switch (sect) {
case ContactSections_FirstName:
_contact.firstName = value;
break;
case ContactSections_LastName:
_contact.lastName = value;
break;
case ContactSections_Sip:
[_contact setSipAddress:value atIndex:path.row];
value = _contact.sipAddresses[path.row]; // in case of reformatting
break;
case ContactSections_Email:
[_contact setEmail:value atIndex:path.row];
value = _contact.emails[path.row]; // in case of reformatting
break;
case ContactSections_Number:
[_contact setPhoneNumber:value atIndex:path.row];
value =
_contact.phones[path.row]; // in case of
// reformatting
break;
case ContactSections_MAX:
case ContactSections_None:
break;
}
cell.editTextfield.text = value;
_editButton.enabled = [self isValid];
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[self textFieldUpdated:textField];
// TODO reload current contact
}
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
#if 0
// every time we modify contact entry, we must check if we can enable "edit" button
UIView *view = [textField superview];
while (view != nil && ![view isKindOfClass:[UIContactDetailsCell class]])
view = [view superview];
UIContactDetailsCell *cell = (UIContactDetailsCell *)view;
// we cannot use indexPathForCell method here because if the cell is not visible anymore,
// it will return nil..
NSIndexPath *path = cell.indexPath;
_editButton.enabled = NO;
for (ContactSections s = ContactSections_Sip; !_editButton.enabled && s <= ContactSections_Number; s++) {
for (int i = 0; !_editButton.enabled && i < [self tableView:self.tableView numberOfRowsInSection:s]; i++) {
NSIndexPath *cellpath = [NSIndexPath indexPathForRow:i inSection:s];
if ([cellpath isEqual:path]) {
_editButton.enabled = (textField.text.length > 0);
} else {
UIContactDetailsCell *cell =
(UIContactDetailsCell *)[self tableView:self.tableView cellForRowAtIndexPath:cellpath];
_editButton.enabled = (cell.editTextfield.text.length > 0);
}
}
}
#else
[self textFieldUpdated:textField];
#endif
return YES;
}
@end

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
#import "UIToggleButton.h"
#import "ContactDetailsTableView.h"
#import "UIRoundedImageView.h"
#import "ImagePickerView.h"
@interface ContactDetailsView : TPMultiLayoutViewController <UICompositeViewDelegate, ImagePickerDelegate> {
BOOL inhibUpdate;
}
@property(nonatomic, assign, setter=setContact:) Contact *contact;
@property(nonatomic) Contact *tmpContact;
@property(nonatomic, strong) IBOutlet ContactDetailsTableView *tableController;
@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 UILabel *nameLabel;
@property(weak, nonatomic) IBOutlet UIToggleButton *deleteButton;
@property(weak, nonatomic) IBOutlet UIScrollView *contentView;
@property(weak, nonatomic) IBOutlet UILabel *emptyLabel;
@property BOOL isAdding;
@property (weak, nonatomic) IBOutlet UIView *waitView;
- (IBAction)onBackClick:(id)event;
- (IBAction)onCancelClick:(id)event;
- (IBAction)onEditClick:(id)event;
- (IBAction)onDeleteClick:(id)sender;
- (IBAction)onAvatarClick:(id)sender;
- (void)updateBackOrCancelButton;
- (void)newContact;
- (void)newContact:(NSString *)address;
- (void)editContact:(Contact *)contact;
- (void)editContact:(Contact *)contact address:(NSString *)address;
- (void)setContact:(Contact *)contact;
- (void)resetContact;
@end

View file

@ -0,0 +1,638 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "ContactDetailsView.h"
#import "PhoneMainView.h"
#import "UIContactDetailsCell.h"
@implementation ContactDetailsView
#pragma mark - Lifecycle Functions
- (id)init {
self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]];
if (self != nil) {
inhibUpdate = FALSE;
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:CNContactStoreDidChangeNotification
object:nil];
}
return self;
}
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
}
#pragma mark -
- (void)onAddressBookUpdate:(NSNotification *)k {
if (!inhibUpdate && ![_tableController isEditing] &&
(PhoneMainView.instance.currentView == self.compositeViewDescription) &&
(_nameLabel.text == PhoneMainView.instance.currentName)) {
[self resetData];
}
}
- (void)resetData {
if (self.isEditing) {
[self setEditing:FALSE];
}
LOGI(@"Reset data to contact %p", _contact);
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
[_tableController setContact:_contact];
_emptyLabel.hidden = YES;
_avatarImage.hidden = !_emptyLabel.hidden;
_deleteButton.hidden = !_emptyLabel.hidden;
_editButton.hidden = !_emptyLabel.hidden;
}
- (void)removeContact {
inhibUpdate = TRUE;
[[LinphoneManager.instance fastAddressBook] deleteContact:_contact];
inhibUpdate = FALSE;
if (IPAD) {
ContactsListView *view = VIEW(ContactsListView);
if (![view .tableController selectFirstRow]) {
[self setContact:nil];
}
}
[PhoneMainView.instance popCurrentView];
}
- (void)saveData {
if (_contact == NULL) {
[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_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 {
if (self.isEditing) {
[self setEditing:FALSE];
}
_contact = acontact;
_emptyLabel.hidden = (_contact != NULL);
_avatarImage.hidden = !_emptyLabel.hidden;
_deleteButton.hidden = !_emptyLabel.hidden || [_contact createdFromLdapOrProvisioning];
_editButton.hidden = !_emptyLabel.hidden || [_contact createdFromLdapOrProvisioning];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
[ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact];
[_tableController setContact:_contact];
if (reload) {
[self setEditing:TRUE animated:FALSE];
}
}
- (void)modifyTmpContact:(Contact *)acontact {
if (_tmpContact) {
_tmpContact = nil;
}
if (!acontact) {
return;
}
@synchronized(LinphoneManager.instance.fastAddressBook) {
_tmpContact = [[Contact alloc]
initWithCNContact:[LinphoneManager.instance.fastAddressBook
getCNContactFromContact:acontact]];
}
}
- (void)addCurrentContactContactField:(NSString *)address {
LinphoneAddress *linphoneAddress = linphone_core_interpret_url_2(LC, address.UTF8String, true);
NSString *username =
linphoneAddress ? [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)] : address;
if (([username rangeOfString:@"@"].length > 0) &&
([LinphoneManager.instance lpConfigBoolForKey:@"show_contacts_emails_preference"] == true)) {
[_tableController addEmailField:username];
} else if ((linphone_account_is_phone_number(NULL, [username UTF8String])) &&
([LinphoneManager.instance lpConfigBoolForKey:@"save_new_contacts_as_phone_number"] == true)) {
[_tableController addPhoneField:username];
} else {
[_tableController addSipField:address];
}
if (linphoneAddress) {
linphone_address_destroy(linphoneAddress);
}
[self setEditing:TRUE];
[[_tableController tableView] reloadData];
}
- (void)newContact {
_isAdding = TRUE;
CNContact *contact = [[CNContact alloc] init];
[self selectContact:[[Contact alloc] initWithCNContact:contact]
andReload:YES];
}
- (void)newContact:(NSString *)address {
CNContact *contact = [[CNContact alloc] init];
Contact *mContact = [[Contact alloc] initWithCNContact:contact];
[self selectContact:mContact andReload:NO];
[self addCurrentContactContactField:address];
// force to restart server subscription to add new contact into the list
[LinphoneManager.instance becomeActive];
}
- (void)editContact:(Contact *)acontact {
[self modifyTmpContact:acontact];
[self selectContact:acontact andReload:YES];
}
- (void)editContact:(Contact *)acontact address:(NSString *)address {
[self modifyTmpContact:acontact];
[self selectContact:acontact andReload:NO];
[self addCurrentContactContactField:address];
}
- (void)setContact:(Contact *)acontact {
[self selectContact:acontact andReload:NO];
}
- (void)resetContact {
if (self.tmpContact) {
_contact.firstName = _tmpContact.firstName.copy;
_contact.lastName = _tmpContact.lastName.copy;
while (_contact.sipAddresses.count > 0) {
[_contact removeSipAddressAtIndex:0];
}
NSInteger nbSipAd = 0;
while (_tmpContact.sipAddresses.count > nbSipAd) {
[_contact addSipAddress:_tmpContact.sipAddresses[nbSipAd]];
nbSipAd++;
}
while (_contact.phones.count > 0) {
[_contact removePhoneNumberAtIndex:0];
}
NSInteger nbPhone = 0;
while (_tmpContact.phones.count > nbPhone) {
[_contact addPhoneNumber:_tmpContact.phones[nbPhone]];
nbPhone++;
}
while (_contact.emails.count > 0) {
[_contact removeEmailAtIndex:0];
}
NSInteger nbEmail = 0;
while (_tmpContact.emails.count > nbEmail) {
[_contact addEmail:_tmpContact.emails[nbEmail]];
nbEmail++;
}
self.tmpContact = NULL;
[self saveData];
}
}
#pragma mark - ViewController Functions
- (void)updateBackOrCancelButton {
if (self.tableController.isEditing) {
_backButton.hidden = TRUE;
_cancelButton.hidden = FALSE;
} else {
if (!IPAD) {
_backButton.hidden = FALSE;
}
_cancelButton.hidden = TRUE;
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// if we use fragments, remove back button
if (IPAD) {
_backButton.hidden = YES;
_backButton.alpha = 0;
}
[self setContact:NULL];
_tableController.tableView.accessibilityIdentifier = @"Contact table";
[_editButton setImage:[UIImage imageNamed:@"valid_disabled.png"]
forState:(UIControlStateDisabled | UIControlStateSelected)];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissKeyboards)];
[self.view addGestureRecognizer:tap];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_waitView.hidden = YES;
_editButton.hidden = ([ContactSelection getSelectionMode] != ContactSelectionModeEdit &&
[ContactSelection getSelectionMode] != ContactSelectionModeNone);
[_tableController.tableView addObserver:self forKeyPath:@"contentSize" options:0 context:NULL];
_tableController.waitView = _waitView;
if (!IPAD && !self.tableController.isEditing)
self.tmpContact = NULL;
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(deviceOrientationDidChange:)
name: UIDeviceOrientationDidChangeNotification
object: nil];
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
for (NSInteger j = 0; j < [self.tableController.tableView numberOfSections]; ++j) {
for (NSInteger i = 0; i < [self.tableController.tableView numberOfRowsInSection:j]; ++i) {
[(UIContactDetailsCell *)[self.tableController.tableView
cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] shouldHideLinphoneImageOfAddress];
}
}
[_editButton setImage:[UIImage imageNamed:@"valid_default.png"] forState:UIControlStateSelected];
[self updateBackOrCancelButton];
[self recomputeTableViewSize:FALSE];
}
- (void)deviceOrientationDidChange:(NSNotification*)notif {
if (IPAD) {
if (self.contact == NULL || (self.contact.firstName == NULL && self.contact.lastName == NULL)) {
if (! self.tableController.isEditing) {
_editButton.hidden = TRUE;
_deleteButton.hidden = TRUE;
_avatarImage.hidden = TRUE;
_emptyLabel.hidden = FALSE;
}
}
}
if (self.contact != NULL && self.contact.createdFromLdapOrProvisioning) {
_editButton.hidden = TRUE;
_deleteButton.hidden = TRUE;
}
_nameLabel.hidden = self.tableController.isEditing;
[self updateBackOrCancelButton];
[self recomputeTableViewSize:self.tableController.isEditing];
}
- (void)viewWillDisappear:(BOOL)animated {
if (_tableController && _tableController.tableView && [_tableController.tableView observationInfo]) {
[_tableController.tableView removeObserver:self forKeyPath:@"contentSize"];
}
[super viewWillDisappear:animated];
PhoneMainView.instance.currentName = NULL;
if (!_tableController.isEditing) {
[self resetContact];
}
BOOL rm = TRUE;
for (NSString *sip in _contact.sipAddresses) {
if (![sip isEqualToString:@""]) {
rm = FALSE;
break;
}
}
if (rm) {
for (NSString *phone in _contact.phones) {
if (![phone isEqualToString:@""]) {
rm = FALSE;
break;
}
}
}
if (rm) {
[LinphoneManager.instance.fastAddressBook deleteContact:_contact];
}
}
#pragma mark - UICompositeViewDelegate Functions
static UICompositeViewDescription *compositeDescription = nil;
+ (UICompositeViewDescription *)compositeViewDescription {
if (compositeDescription == nil) {
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
statusBar:StatusBarView.class
tabBar:TabBarView.class
sideMenu:SideMenuView.class
fullscreen:false
isLeftFragment:NO
fragmentWith:ContactsListView.class];
}
return compositeDescription;
}
- (UICompositeViewDescription *)compositeViewDescription {
return self.class.compositeViewDescription;
}
#pragma mark -
- (void)setEditing:(BOOL)editing {
[self setEditing:editing animated:NO];
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (editing) {
_editButton.hidden = FALSE;
_deleteButton.hidden = FALSE;
_avatarImage.hidden = FALSE;
} else {
_editButton.hidden = TRUE;
_deleteButton.hidden = TRUE;
_avatarImage.hidden = TRUE;
}
if (animated) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
}
[_tableController setEditing:editing animated:animated];
if (editing) {
[_editButton setOn];
} else {
[_editButton setOff];
}
_cancelButton.hidden = !editing;
_backButton.hidden = editing;
_nameLabel.hidden = editing;
[ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact];
[self recomputeTableViewSize:editing];
if (animated) {
[UIView commitAnimations];
}
}
- (void)recomputeTableViewSize:(BOOL)editing {
CGRect frame = _tableController.tableView.frame;
if ([self viewIsCurrentlyPortrait] && !editing) {
frame.origin.y = _nameLabel.frame.origin.y + _nameLabel.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;
[self recomputeContentViewSize];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
CGRect frame = _tableController.tableView.frame;
frame.size = _tableController.tableView.contentSize;
_tableController.tableView.frame = frame;
[self recomputeContentViewSize];
}
- (void)recomputeContentViewSize {
_contentView.contentSize =
CGSizeMake(_tableController.tableView.frame.size.width + _tableController.tableView.frame.origin.x,
_tableController.tableView.frame.size.height + _tableController.tableView.frame.origin.y);
}
#pragma mark - Action Functions
- (IBAction)onCancelClick:(id)event {
[self dismissKeyboards];
if (!_isAdding) {
_contact.firstName = _tmpContact.firstName.copy;
_contact.lastName = _tmpContact.lastName.copy;
_contact.avatar = _tmpContact.avatar.copy;
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
while (_contact.sipAddresses.count > 0) {
[_contact removeSipAddressAtIndex:0];
}
NSInteger nbSipAd = 0;
if (_tmpContact.sipAddresses) {
while (_tmpContact.sipAddresses.count > nbSipAd) {
[_contact addSipAddress:_tmpContact.sipAddresses[nbSipAd]];
nbSipAd++;
}
}
while (_contact.phones.count > 0) {
if (_contact.phones[0] != NULL && ![_contact.phones[0] isEqualToString:@" "]) {
[_contact removePhoneNumberAtIndex:0];
} else {
// remove empty index
[_contact.phones removeObjectAtIndex:0];
}
}
NSInteger nbPhone = 0;
if (_tmpContact.phones != NULL) {
while (_tmpContact.phones.count > nbPhone) {
[_contact addPhoneNumber:_tmpContact.phones[nbPhone]];
nbPhone++;
}
}
while (_contact.emails.count > 0) {
[_contact removeEmailAtIndex:0];
}
NSInteger nbEmail = 0;
if (_tmpContact.emails != NULL) {
while (_tmpContact.emails.count > nbEmail) {
[_contact addEmail:_tmpContact.emails[nbEmail]];
nbEmail++;
}
}
// [self saveData];
} else {
[LinphoneManager.instance.fastAddressBook deleteContact:_contact];
}
[self setEditing:FALSE];
if (IPAD) {
_emptyLabel.hidden = !_isAdding;
_avatarImage.hidden = !_emptyLabel.hidden;
_deleteButton.hidden = !_emptyLabel.hidden;
_editButton.hidden = !_emptyLabel.hidden;
} else {
if (_isAdding) {
[PhoneMainView.instance popCurrentView];
} else {
_avatarImage.hidden = FALSE;
_deleteButton.hidden = FALSE;
_editButton.hidden = FALSE;
}
}
self.tmpContact = NULL;
if (_isAdding) {
[PhoneMainView.instance
popToView:ContactsListView.compositeViewDescription];
_isAdding = FALSE;
}
}
- (IBAction)onBackClick:(id)event {
if ([ContactSelection getSelectionMode] == ContactSelectionModeEdit) {
[ContactSelection setSelectionMode:ContactSelectionModeNone];
}
NSString* previous = [PhoneMainView.instance getPreviousViewName];
if ([previous isEqualToString:@"HistoryDetailsView"]) {
HistoryDetailsView *view = VIEW(HistoryDetailsView);
[PhoneMainView.instance popToView:view.compositeViewDescription];
} else {
ContactsListView *view = VIEW(ContactsListView);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
}
- (IBAction)onEditClick:(id)event {
if (_tableController.isEditing) {
[LinphoneManager.instance setContactsUpdated:TRUE];
[self setEditing:FALSE];
if(![self hasDuplicateContactOf:_contact]){
[self saveData];
_isAdding = FALSE;
self.tmpContact = NULL;
_avatarImage.hidden = FALSE;
_deleteButton.hidden = FALSE;
_editButton.hidden = FALSE;
}else{
LOGE(@"====>>>> Duplicated Contacts detected !!!");
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Contact error", nil) message:NSLocalizedString(@"Contact duplicate", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil] show];
}
} else {
[self modifyTmpContact:_contact];
[self setEditing:TRUE];
}
}
- (IBAction)onDeleteClick:(id)sender {
NSString *msg = NSLocalizedString(@"Do you want to delete selected contact?\nIt will also be deleted from your phone's address book.", nil);
[UIConfirmationDialog ShowWithMessage:msg
cancelMessage:nil
confirmMessage:nil
onCancelClick:nil
onConfirmationClick:^() {
if (_tableController.isEditing) {
[self onCancelClick:sender];
}
[self removeContact];
[self dismissKeyboards];
}];
}
- (IBAction)onAvatarClick:(id)sender {
[LinphoneUtils findAndResignFirstResponder:self.view];
if (_tableController.isEditing) {
[ImagePickerView SelectImageFromDevice:self atPosition:_avatarImage inView:self.view withDocumentMenuDelegate:nil];
}
}
- (void)dismissKeyboards {
NSArray *cells = [self.tableController.tableView visibleCells];
for (UIContactDetailsCell *cell in cells) {
UIView * txt = cell.editTextfield;
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}
- (BOOL) hasDuplicateContactOf:(Contact*) contactToCheck{
CNContactStore *store = [[CNContactStore alloc] init];
NSArray *keysToFetch = @[
CNContactEmailAddressesKey, CNContactPhoneNumbersKey,
CNContactInstantMessageAddressesKey, CNInstantMessageAddressUsernameKey,
CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPostalAddressesKey,
CNContactIdentifierKey, CNContactImageDataKey, CNContactNicknameKey
];
CNMutableContact *mCNContact =
[[store unifiedContactWithIdentifier:contactToCheck.identifier keysToFetch:keysToFetch error:nil] mutableCopy];
if(mCNContact == NULL){
for(NSString *address in contactToCheck.sipAddresses){
NSString *name = [FastAddressBook normalizeSipURI:address use_prefix:TRUE];
if([LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:name]){
return TRUE;
}
}
return FALSE;
}else{
return FALSE;
}
}
#pragma mark - Image picker delegate
- (void)imagePickerDelegateImage:(UIImage *)image info:(NSDictionary *)info {
// When getting image from the camera, it may be 90° rotated due to orientation
// (image.imageOrientation = UIImageOrientationRight). Just rotate it to be face up.
if (image.imageOrientation != UIImageOrientationUp) {
UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
// Dismiss popover on iPad
if (IPAD) {
[VIEW(ImagePickerView).popoverController dismissPopoverAnimated:TRUE];
}
[_contact setAvatar:image];
[_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES];
}
- (void)imagePickerDelegateVideo:(NSURL*)url info:(NSDictionary *)info {
return;
}
@end

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import "UICheckBoxTableView.h"
#import "OrderedDictionary.h"
@interface ContactsListTableView : UICheckBoxTableView {
@private
OrderedDictionary *addressBookMap;
}
@property(atomic) BOOL reloadMagicSearch;
- (void)loadData;
- (void)loadDataWithFilter:(NSString *)filter;
- (void)removeAllContacts;
@end

View file

@ -0,0 +1,343 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import "linphoneapp-Swift.h"
#import "ContactsListTableView.h"
#import "UIContactCell.h"
#import "LinphoneManager.h"
#import "PhoneMainView.h"
#import "Utils.h"
@implementation ContactsListTableView
#pragma mark - Lifecycle Functions
- (void)initContactsTableViewController {
addressBookMap = [[OrderedDictionary alloc] init];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onAddressBookUpdate:)
name:CNContactStoreDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onMagicSearchFinished:)
name:kLinphoneMagicSearchFinished
object:nil];
}
- (void)onAddressBookUpdate:(NSNotification *)k {
if ((![MagicSearchSingleton.instance isSearchOngoing] && (PhoneMainView.instance.currentView == ContactsListView.compositeViewDescription)) || (IPAD && PhoneMainView.instance.currentView == ContactDetailsView.compositeViewDescription)) {
[self loadData];
}
}
- (void)onMagicSearchFinished:(NSNotification *)k {
[self buildContactTable];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (IPAD) {
if (![self selectFirstRow]) {
ContactDetailsView *view = VIEW(ContactDetailsView);
[view setContact:nil];
}
}
}
- (id)init {
self = [super init];
if (self) {
[self initContactsTableViewController];
}
_reloadMagicSearch = TRUE;
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initContactsTableViewController];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self removeAllContacts];
}
- (void)removeAllContacts {
for (NSInteger j = 0; j < [self.tableView numberOfSections]; ++j) {
for (NSInteger i = 0; i < [self.tableView numberOfRowsInSection:j]; ++i) {
[[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setContact:nil];
}
}
}
#pragma mark -
static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) {
if (!fuzzy_word || !sentence) {
return fuzzy_word == sentence;
}
const char *c = fuzzy_word;
const char *within_sentence = sentence;
for (; c != NULL && *c != '\0' && within_sentence != NULL; ++c) {
within_sentence = strchr(within_sentence, *c);
// Could not find c character in sentence. Abort.
if (within_sentence == NULL) {
break;
}
// since strchr returns the index of the matched char, move forward
within_sentence++;
}
// If the whole fuzzy was found, returns 0. Otherwise returns number of characters left.
return (int)(within_sentence != NULL ? 0 : fuzzy_word + strlen(fuzzy_word) - c);
}
- (NSString *)displayNameForContact:(Contact *)person {
NSString *name = person.displayName;
if (name != nil && [name length] > 0 && ![name isEqualToString:NSLocalizedString(@"Unknown", nil)]) {
// Sort contacts by first letter. We need to translate the name to ASCII first, because of UTF-8
// issues. For instance expected order would be: Alberta(A tilde) before ASylvano.
NSData *name2ASCIIdata = [name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *name2ASCII = [[NSString alloc] initWithData:name2ASCIIdata encoding:NSASCIIStringEncoding];
return name2ASCII;
}
return NSLocalizedString(@"Unknown", nil);
}
- (void)buildContactTable {
@synchronized(addressBookMap) {
//Set all contacts from ContactCell to nil
for (NSInteger j = 0; j < [self.tableView numberOfSections]; ++j)
{
for (NSInteger i = 0; i < [self.tableView numberOfRowsInSection:j]; ++i)
{
[[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setContact:nil];
}
}
// Reset Address book
[addressBookMap removeAllObjects];
NSMutableArray *subAr = [NSMutableArray new];
[addressBookMap insertObject:subAr forKey:@"" selector:@selector(caseInsensitiveCompare:)];
//
NSArray *searchResults = [MagicSearchSingleton.instance getLastSearchContacts];
for (Contact *contact in searchResults) {
NSMutableString *name = [[NSMutableString alloc] initWithString: [self displayNameForContact:contact]];
if (name != nil) {
NSString *firstChar = [[name substringToIndex:1] uppercaseString];
// Put in correct subAr
if ([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') {
firstChar = @"#";
}
NSMutableArray *subAr = [addressBookMap objectForKey:firstChar];
if (subAr == nil) {
subAr = [[NSMutableArray alloc] init];
[addressBookMap insertObject:subAr forKey:firstChar selector:@selector(caseInsensitiveCompare:)];
}
NSUInteger idx = [subAr indexOfObject:contact inSortedRange:(NSRange){0, subAr.count} options:NSBinarySearchingInsertionIndex usingComparator:^NSComparisonResult( Contact *_Nonnull obj1, Contact *_Nonnull obj2) {
return [[self displayNameForContact:obj1] compare:[self displayNameForContact:obj2] options:NSCaseInsensitiveSearch];
}];
if (![subAr containsObject:contact]) {
[subAr insertObject:contact atIndex:idx];
}
}
}
[super loadData];
}
// since we refresh the tableview, we must perform this on main
// thread
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (IPAD) {
if (!([self totalNumberOfItems] > 0)) {
ContactDetailsView *view = VIEW(ContactDetailsView);
[view setContact:nil];
}
}
});
_reloadMagicSearch = FALSE;
}
- (void)loadData {
if (_reloadMagicSearch) {
NSString *domain = @"";
if ([ContactSelection getSipFilterEnabled]) {
LinphoneAccount *defaultAccount = linphone_core_get_default_account(LC);
if (defaultAccount) {
domain = [NSString stringWithUTF8String:linphone_account_params_get_domain(linphone_account_get_params(defaultAccount))];
}
}
int sourceFlags = LinphoneMagicSearchSourceFriends | LinphoneMagicSearchSourceLdapServers;
[MagicSearchSingleton.instance searchForContactsWithDomain:domain sourceFlags:sourceFlags clearCache:[LinphoneManager.instance getContactsUpdated]];
[LinphoneManager.instance setContactsUpdated:FALSE];
} else {
[self buildContactTable];
}
}
- (void)loadDataWithFilter: (NSString *)filter {
LOGI(@"Load search contact list");
_reloadMagicSearch = _reloadMagicSearch || [filter length]==0 || ![[MagicSearchSingleton.instance currentFilter] isEqualToString:filter];
[MagicSearchSingleton.instance setCurrentFilter:filter];
[self loadData];
}
#pragma mark - UITableViewDataSource Functions
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [addressBookMap allKeys];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [addressBookMap count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [(OrderedDictionary *)[addressBookMap objectForKey:[addressBookMap keyAtIndex:section]] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *kCellId = NSStringFromClass(UIContactCell.class);
UIContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
if (cell == nil) {
cell = [[UIContactCell alloc] initWithIdentifier:kCellId];
}
NSMutableArray *subAr = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]];
Contact *contact = subAr[indexPath.row];
// Cached avatar
UIImage *image = [FastAddressBook imageForContact:contact];
[cell.avatarImage setImage:image bordered:NO withRoundedRadius:YES];
[cell setContact:contact];
[super accessoryForCell:cell atPath:indexPath];
cell.contentView.userInteractionEnabled = false;
return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, tableView.sectionHeaderHeight);
UIView *tempView = [[UIView alloc] initWithFrame:frame];
if (@available(iOS 13, *)) {
tempView.backgroundColor = [UIColor systemBackgroundColor];
} else {
tempView.backgroundColor = [UIColor whiteColor];
}
UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame];
tempLabel.backgroundColor = [UIColor clearColor];
tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]];
tempLabel.text = [addressBookMap keyAtIndex:section];
tempLabel.textAlignment = NSTextAlignmentCenter;
tempLabel.font = [UIFont boldSystemFontOfSize:17];
tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[tempView addSubview:tempLabel];
return tempView;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
if (![self isEditing]) {
NSMutableArray *subAr = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]];
Contact *contact = subAr[indexPath.row];
// Go to Contact details view
ContactDetailsView *view = VIEW(ContactDetailsView);
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
if (([ContactSelection getSelectionMode] != ContactSelectionModeEdit) || !([ContactSelection getAddAddress])) {
[view setContact:contact];
} else {
if (IPAD) {
[view resetContact];
view.isAdding = FALSE;
}
[view editContact:contact address:[ContactSelection getAddAddress]];
}
}
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[NSNotificationCenter.defaultCenter removeObserver:self];
NSString *msg = NSLocalizedString(@"Do you want to delete selected contact?\nIt will also be deleted from your phone's address book.", nil);
[UIConfirmationDialog ShowWithMessage:msg
cancelMessage:nil
confirmMessage:nil
onCancelClick:nil
onConfirmationClick:^() {
[tableView beginUpdates];
NSString *firstChar = [addressBookMap keyAtIndex:[indexPath section]];
NSMutableArray *subAr = [addressBookMap objectForKey:firstChar];
Contact *contact = subAr[indexPath.row];
[subAr removeObjectAtIndex:indexPath.row];
if (subAr.count == 0) {
[addressBookMap removeObjectForKey:firstChar];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section]
withRowAnimation:UITableViewRowAnimationFade];
}
UIContactCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setContact:NULL];
[[LinphoneManager.instance fastAddressBook] deleteContact:contact];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
[self loadData];
}];
}
}
- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover {
[super removeSelectionUsing:^(NSIndexPath *indexPath) {
[NSNotificationCenter.defaultCenter removeObserver:self];
NSString *firstChar = [addressBookMap keyAtIndex:[indexPath section]];
NSMutableArray *subAr = [addressBookMap objectForKey:firstChar];
Contact *contact = subAr[indexPath.row];
[subAr removeObjectAtIndex:indexPath.row];
if (subAr.count == 0) {
[addressBookMap removeObjectForKey:firstChar];
}
UIContactCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setContact:NULL];
[[LinphoneManager.instance fastAddressBook] deleteContact:contact];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(onAddressBookUpdate:)
name:kLinphoneAddressBookUpdate
object:nil];
}];
}
@end

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
#import "ContactsListTableView.h"
#import "UIInterfaceStyleButton.h"
typedef enum _ContactSelectionMode { ContactSelectionModeNone, ContactSelectionModeEdit } ContactSelectionMode;
@interface ContactSelection : NSObject <UISearchBarDelegate> {
}
+ (void)setSelectionMode:(ContactSelectionMode)selectionMode;
+ (ContactSelectionMode)getSelectionMode;
+ (void)setAddAddress:(NSString *)address;
+ (NSString *)getAddAddress;
/*!
* Filters contacts by SIP domain.
* @param enabled Wether SIP domain filter is enabled
*/
+ (void)enableSipFilter:(BOOL)enabled;
/*!
* Wether SIP domain filter is enabled
* @return the filter used, or nil if none.
*/
+ (BOOL)getSipFilterEnabled;
@end
@interface ContactsListView : UIViewController <UICompositeViewDelegate, UISearchBarDelegate, UIGestureRecognizerDelegate>
@property(strong, nonatomic) IBOutlet ContactsListTableView *tableController;
@property(strong, nonatomic) IBOutlet UIView *topBar;
@property(nonatomic, strong) IBOutlet UIButton *allButton;
@property(nonatomic, strong) IBOutlet UIButton *linphoneButton;
@property(nonatomic, strong) IBOutlet UIButton *addButton;
@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;
- (IBAction)onAddContactClick:(id)event;
- (IBAction)onDeleteClick:(id)sender;
- (IBAction)onEditionChangeClick:(id)sender;
@end

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