diff --git a/.gitignore b/.gitignore index 06f2cadc9f..7d8c64ff00 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ build/* # Exclude user-specific XCode 3 and 4 files xcuserdata - +*.xccheckout diff --git a/Podfile.lock b/Podfile.lock index 5d32aeda3f..a89667b3d2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -32,7 +32,7 @@ PODS: - CocoaLumberjack/Core - DJWActionSheet (1.0.4) - HKDFKit (0.0.3) - - JSQMessagesViewController (6.0-beta6): + - JSQMessagesViewController (6.0.0): - JSQSystemSoundPlayer (~> 2.0.0) - JSQSystemSoundPlayer (2.0.0) - libPhoneNumber-iOS (0.7.3) @@ -83,7 +83,7 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: JSQMessagesViewController: - :commit: 21d877492e948f27fde4115573a809798cc78210 + :commit: 597670e44663c9fa70b6a2deec2b19147c763048 :git: https://github.com/dtsbourg/JSQMessagesViewController SocketRocket: :commit: d0585af165 @@ -96,7 +96,7 @@ SPEC CHECKSUMS: CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817 DJWActionSheet: d88b302d7c29523e1e9fb9b62cfac46f59bb90d9 HKDFKit: 5998cf1bbb611e7ecc6bd3eaaef8c7a7da7be949 - JSQMessagesViewController: 960a09d11978bea52d1a676e97980838f8d98652 + JSQMessagesViewController: 49f449221a8f1da43403e6468ae2015fa0114a9e JSQSystemSoundPlayer: c98443b1cbb3b45db09d0d3d6c2355cf78294981 libPhoneNumber-iOS: 98fc07d70c8fdb5e6a8e3442c37e97353065c20e Mantle: d7c5ac734579ec751c58fecbf56189853056c58c diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 7835dd0128..297d9df8d3 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -286,127 +286,40 @@ B60C16651988999D00E97A6C /* VersionMigrations.m in Sources */ = {isa = PBXBuildFile; fileRef = B60C16641988999D00E97A6C /* VersionMigrations.m */; }; B60EDE041A05A01700D73516 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B60EDE031A05A01700D73516 /* AudioToolbox.framework */; }; B633C5801A1D190B0059AC12 /* archive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C4FE1A1D190B0059AC12 /* archive@2x.png */; }; - B633C5811A1D190B0059AC12 /* archive_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C4FF1A1D190B0059AC12 /* archive_icon.png */; }; - B633C5821A1D190B0059AC12 /* archive_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5001A1D190B0059AC12 /* archive_icon@2x.png */; }; B633C5831A1D190B0059AC12 /* backspace.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5011A1D190B0059AC12 /* backspace.png */; }; B633C5841A1D190B0059AC12 /* backspace@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5021A1D190B0059AC12 /* backspace@2x.png */; }; B633C5851A1D190B0059AC12 /* blue-archive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5031A1D190B0059AC12 /* blue-archive@2x.png */; }; B633C5861A1D190B0059AC12 /* call@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5041A1D190B0059AC12 /* call@2x.png */; }; B633C5871A1D190B0059AC12 /* call_dark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5051A1D190B0059AC12 /* call_dark@2x.png */; }; - B633C5881A1D190B0059AC12 /* checkbox_checkmark.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5061A1D190B0059AC12 /* checkbox_checkmark.png */; }; - B633C5891A1D190B0059AC12 /* checkbox_checkmark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5071A1D190B0059AC12 /* checkbox_checkmark@2x.png */; }; - B633C58A1A1D190B0059AC12 /* checkbox_empty.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5081A1D190B0059AC12 /* checkbox_empty.png */; }; - B633C58B1A1D190B0059AC12 /* checkbox_empty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5091A1D190B0059AC12 /* checkbox_empty@2x.png */; }; B633C58C1A1D190B0059AC12 /* checkmark.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50A1A1D190B0059AC12 /* checkmark.png */; }; B633C58D1A1D190B0059AC12 /* contact_default_feed.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50B1A1D190B0059AC12 /* contact_default_feed.png */; }; - B633C58E1A1D190B0059AC12 /* contacts.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50C1A1D190B0059AC12 /* contacts.png */; }; B633C58F1A1D190B0059AC12 /* contacts@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50D1A1D190B0059AC12 /* contacts@2x.png */; }; - B633C5901A1D190B0059AC12 /* contacts_arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50E1A1D190B0059AC12 /* contacts_arrow.png */; }; - B633C5911A1D190B0059AC12 /* contacts_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50F1A1D190B0059AC12 /* contacts_arrow@2x.png */; }; B633C5921A1D190B0059AC12 /* contacts_tab@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5101A1D190B0059AC12 /* contacts_tab@2x.png */; }; B633C5961A1D190B0059AC12 /* DefaultContactImage.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5141A1D190B0059AC12 /* DefaultContactImage.png */; }; B633C5971A1D190B0059AC12 /* delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5151A1D190B0059AC12 /* delete@2x.png */; }; B633C5981A1D190B0059AC12 /* delete_history@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5161A1D190B0059AC12 /* delete_history@2x.png */; }; - B633C5991A1D190B0059AC12 /* dismiss_notification_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5171A1D190B0059AC12 /* dismiss_notification_icon.png */; }; - B633C59A1A1D190B0059AC12 /* dismiss_notification_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5181A1D190B0059AC12 /* dismiss_notification_icon@2x.png */; }; - B633C59B1A1D190B0059AC12 /* drop_down_arrow_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5191A1D190B0059AC12 /* drop_down_arrow_icon.png */; }; - B633C59C1A1D190B0059AC12 /* drop_down_arrow_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C51A1A1D190B0059AC12 /* drop_down_arrow_icon@2x.png */; }; B633C59D1A1D190B0059AC12 /* endcall@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C51B1A1D190B0059AC12 /* endcall@2x.png */; }; - B633C59E1A1D190B0059AC12 /* expanded_cell_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C51C1A1D190B0059AC12 /* expanded_cell_icon.png */; }; - B633C59F1A1D190B0059AC12 /* expanded_cell_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C51D1A1D190B0059AC12 /* expanded_cell_icon@2x.png */; }; - B633C5A01A1D190B0059AC12 /* favourite.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C51E1A1D190B0059AC12 /* favourite.png */; }; - B633C5A11A1D190B0059AC12 /* favourite_false_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C51F1A1D190B0059AC12 /* favourite_false_icon.png */; }; - B633C5A21A1D190B0059AC12 /* favourite_false_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5201A1D190B0059AC12 /* favourite_false_icon@2x.png */; }; - B633C5A31A1D190B0059AC12 /* favourite_true_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5211A1D190B0059AC12 /* favourite_true_icon.png */; }; - B633C5A41A1D190B0059AC12 /* favourite_true_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5221A1D190B0059AC12 /* favourite_true_icon@2x.png */; }; - B633C5A51A1D190B0059AC12 /* forward_button.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5231A1D190B0059AC12 /* forward_button.png */; }; - B633C5A61A1D190B0059AC12 /* forward_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5241A1D190B0059AC12 /* forward_button@2x.png */; }; - B633C5A71A1D190B0059AC12 /* home_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5251A1D190B0059AC12 /* home_icon.png */; }; - B633C5A81A1D190B0059AC12 /* icon_contacts.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5261A1D190B0059AC12 /* icon_contacts.png */; }; - B633C5A91A1D190B0059AC12 /* icon_favourites.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5271A1D190B0059AC12 /* icon_favourites.png */; }; - B633C5AA1A1D190B0059AC12 /* icon_keypad.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5281A1D190B0059AC12 /* icon_keypad.png */; }; - B633C5AB1A1D190B0059AC12 /* icon_recents.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5291A1D190B0059AC12 /* icon_recents.png */; }; - B633C5AC1A1D190B0059AC12 /* in_call_phone_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C52A1A1D190B0059AC12 /* in_call_phone_icon.png */; }; - B633C5AD1A1D190B0059AC12 /* in_call_phone_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C52B1A1D190B0059AC12 /* in_call_phone_icon@2x.png */; }; - B633C5AE1A1D190B0059AC12 /* in_call_phrase_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C52C1A1D190B0059AC12 /* in_call_phrase_icon.png */; }; - B633C5AF1A1D190B0059AC12 /* in_call_phrase_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C52D1A1D190B0059AC12 /* in_call_phrase_icon@2x.png */; }; - B633C5B01A1D190B0059AC12 /* incoming_call_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C52E1A1D190B0059AC12 /* incoming_call_icon.png */; }; - B633C5B11A1D190B0059AC12 /* incoming_call_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C52F1A1D190B0059AC12 /* incoming_call_icon@2x.png */; }; - B633C5B21A1D190B0059AC12 /* info@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5301A1D190B0059AC12 /* info@2x.png */; }; B633C5B41A1D190B0059AC12 /* keypad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5321A1D190B0059AC12 /* keypad@2x.png */; }; B633C5B51A1D190B0059AC12 /* lock@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5331A1D190B0059AC12 /* lock@2x.png */; }; B633C5B61A1D190B0059AC12 /* lock_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5341A1D190B0059AC12 /* lock_white@2x.png */; }; B633C5B71A1D190B0059AC12 /* logo_intro@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5351A1D190B0059AC12 /* logo_intro@2x.png */; }; - B633C5B91A1D190B0059AC12 /* menu_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5371A1D190B0059AC12 /* menu_icon.png */; }; - B633C5BA1A1D190B0059AC12 /* menu_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5381A1D190B0059AC12 /* menu_icon@2x.png */; }; B633C5BB1A1D190B0059AC12 /* message_bubble.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5391A1D190B0059AC12 /* message_bubble.png */; }; B633C5BC1A1D190B0059AC12 /* message_bubble@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C53A1A1D190B0059AC12 /* message_bubble@2x.png */; }; - B633C5BD1A1D190B0059AC12 /* message_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C53B1A1D190B0059AC12 /* message_icon.png */; }; B633C5BE1A1D190B0059AC12 /* missed.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C53C1A1D190B0059AC12 /* missed.png */; }; - B633C5BF1A1D190B0059AC12 /* mute_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C53D1A1D190B0059AC12 /* mute_icon.png */; }; - B633C5C01A1D190B0059AC12 /* mute_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C53E1A1D190B0059AC12 /* mute_icon@2x.png */; }; - B633C5C11A1D190B0059AC12 /* mute_icon_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C53F1A1D190B0059AC12 /* mute_icon_selected.png */; }; - B633C5C21A1D190B0059AC12 /* mute_icon_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5401A1D190B0059AC12 /* mute_icon_selected@2x.png */; }; B633C5C31A1D190B0059AC12 /* mute_off@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5411A1D190B0059AC12 /* mute_off@2x.png */; }; B633C5C41A1D190B0059AC12 /* mute_on@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5421A1D190B0059AC12 /* mute_on@2x.png */; }; - B633C5C51A1D190B0059AC12 /* notification_detail_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5431A1D190B0059AC12 /* notification_detail_icon.png */; }; - B633C5C61A1D190B0059AC12 /* notification_detail_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5441A1D190B0059AC12 /* notification_detail_icon@2x.png */; }; - B633C5C71A1D190B0059AC12 /* notification_mini_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5451A1D190B0059AC12 /* notification_mini_icon.png */; }; - B633C5C81A1D190B0059AC12 /* notification_mini_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5461A1D190B0059AC12 /* notification_mini_icon@2x.png */; }; - B633C5C91A1D190B0059AC12 /* outgoing_call_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5471A1D190B0059AC12 /* outgoing_call_icon.png */; }; - B633C5CA1A1D190B0059AC12 /* outgoing_call_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5481A1D190B0059AC12 /* outgoing_call_icon@2x.png */; }; - B633C5CB1A1D190B0059AC12 /* phone_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5491A1D190B0059AC12 /* phone_icon.png */; }; - B633C5CC1A1D190B0059AC12 /* phone_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C54A1A1D190B0059AC12 /* phone_icon@2x.png */; }; B633C5CD1A1D190B0059AC12 /* photo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C54B1A1D190B0059AC12 /* photo@2x.png */; }; B633C5CE1A1D190B0059AC12 /* quit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C54C1A1D190B0059AC12 /* quit@2x.png */; }; B633C5CF1A1D190B0059AC12 /* received.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C54D1A1D190B0059AC12 /* received.png */; }; B633C5D01A1D190B0059AC12 /* red-delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C54E1A1D190B0059AC12 /* red-delete@2x.png */; }; B633C5D11A1D190B0059AC12 /* reply.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C54F1A1D190B0059AC12 /* reply.png */; }; B633C5D21A1D190B0059AC12 /* savephoto@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5501A1D190B0059AC12 /* savephoto@2x.png */; }; - B633C5D31A1D190B0059AC12 /* search_cancel.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5511A1D190B0059AC12 /* search_cancel.png */; }; - B633C5D41A1D190B0059AC12 /* search_cancel@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5521A1D190B0059AC12 /* search_cancel@2x.png */; }; - B633C5D51A1D190B0059AC12 /* search_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5531A1D190B0059AC12 /* search_icon.png */; }; - B633C5D61A1D190B0059AC12 /* search_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5541A1D190B0059AC12 /* search_icon@2x.png */; }; - B633C5D71A1D190B0059AC12 /* send_code_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5551A1D190B0059AC12 /* send_code_icon.png */; }; - B633C5D81A1D190B0059AC12 /* send_code_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5561A1D190B0059AC12 /* send_code_icon@2x.png */; }; - B633C5D91A1D190B0059AC12 /* settings.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5571A1D190B0059AC12 /* settings.png */; }; B633C5DA1A1D190B0059AC12 /* settings_dark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5581A1D190B0059AC12 /* settings_dark@2x.png */; }; B633C5DB1A1D190B0059AC12 /* share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5591A1D190B0059AC12 /* share@2x.png */; }; B633C5DC1A1D190B0059AC12 /* shred@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C55A1A1D190B0059AC12 /* shred@2x.png */; }; B633C5DF1A1D190B0059AC12 /* signal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C55E1A1D190B0059AC12 /* signal@2x.png */; }; - B633C5E01A1D190B0059AC12 /* signals.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C55F1A1D190B0059AC12 /* signals.png */; }; - B633C5E11A1D190B0059AC12 /* speaker_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5601A1D190B0059AC12 /* speaker_icon.png */; }; - B633C5E21A1D190B0059AC12 /* speaker_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5611A1D190B0059AC12 /* speaker_icon@2x.png */; }; - B633C5E31A1D190B0059AC12 /* speaker_icon_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5621A1D190B0059AC12 /* speaker_icon_selected.png */; }; - B633C5E41A1D190B0059AC12 /* speaker_icon_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5631A1D190B0059AC12 /* speaker_icon_selected@2x.png */; }; B633C5E51A1D190B0059AC12 /* speaker_off@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5641A1D190B0059AC12 /* speaker_off@2x.png */; }; B633C5E61A1D190B0059AC12 /* speaker_on@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5651A1D190B0059AC12 /* speaker_on@2x.png */; }; - B633C5E71A1D190B0059AC12 /* spinner_connecting.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5661A1D190B0059AC12 /* spinner_connecting.png */; }; - B633C5E81A1D190B0059AC12 /* spinner_connecting@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5671A1D190B0059AC12 /* spinner_connecting@2x.png */; }; - B633C5E91A1D190B0059AC12 /* spinner_connecting_flash.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5681A1D190B0059AC12 /* spinner_connecting_flash.png */; }; - B633C5EA1A1D190B0059AC12 /* spinner_connecting_flash@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5691A1D190B0059AC12 /* spinner_connecting_flash@2x.png */; }; - B633C5EB1A1D190B0059AC12 /* spinner_error.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C56A1A1D190B0059AC12 /* spinner_error.png */; }; - B633C5EC1A1D190B0059AC12 /* spinner_error@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C56B1A1D190B0059AC12 /* spinner_error@2x.png */; }; - B633C5ED1A1D190B0059AC12 /* spinner_ringing.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C56C1A1D190B0059AC12 /* spinner_ringing.png */; }; - B633C5EE1A1D190B0059AC12 /* spinner_ringing@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C56D1A1D190B0059AC12 /* spinner_ringing@2x.png */; }; - B633C5EF1A1D190B0059AC12 /* tab_icon_contacts.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C56E1A1D190B0059AC12 /* tab_icon_contacts.png */; }; - B633C5F01A1D190B0059AC12 /* tab_icon_contacts@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C56F1A1D190B0059AC12 /* tab_icon_contacts@2x.png */; }; - B633C5F11A1D190B0059AC12 /* tab_icon_favourites.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5701A1D190B0059AC12 /* tab_icon_favourites.png */; }; - B633C5F21A1D190B0059AC12 /* tab_icon_favourites@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5711A1D190B0059AC12 /* tab_icon_favourites@2x.png */; }; - B633C5F31A1D190B0059AC12 /* tab_icon_inbox.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5721A1D190B0059AC12 /* tab_icon_inbox.png */; }; - B633C5F41A1D190B0059AC12 /* tab_icon_inbox@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5731A1D190B0059AC12 /* tab_icon_inbox@2x.png */; }; - B633C5F51A1D190B0059AC12 /* tab_icon_keypad.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5741A1D190B0059AC12 /* tab_icon_keypad.png */; }; - B633C5F61A1D190B0059AC12 /* tab_icon_keypad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5751A1D190B0059AC12 /* tab_icon_keypad@2x.png */; }; - B633C5F71A1D190B0059AC12 /* tab_icon_menu.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5761A1D190B0059AC12 /* tab_icon_menu.png */; }; - B633C5F81A1D190B0059AC12 /* tab_icon_menu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5771A1D190B0059AC12 /* tab_icon_menu@2x.png */; }; - B633C5F91A1D190B0059AC12 /* trash_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5781A1D190B0059AC12 /* trash_icon.png */; }; - B633C5FA1A1D190B0059AC12 /* trash_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5791A1D190B0059AC12 /* trash_icon@2x.png */; }; - B633C5FB1A1D190B0059AC12 /* volume_high.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C57A1A1D190B0059AC12 /* volume_high.png */; }; - B633C5FC1A1D190B0059AC12 /* volume_high@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C57B1A1D190B0059AC12 /* volume_high@2x.png */; }; - B633C5FD1A1D190B0059AC12 /* volume_low.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C57C1A1D190B0059AC12 /* volume_low.png */; }; - B633C5FE1A1D190B0059AC12 /* volume_low@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C57D1A1D190B0059AC12 /* volume_low@2x.png */; }; - B633C5FF1A1D190B0059AC12 /* whisper_notification_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C57E1A1D190B0059AC12 /* whisper_notification_icon.png */; }; - B633C6001A1D190B0059AC12 /* whisper_notification_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C57F1A1D190B0059AC12 /* whisper_notification_icon@2x.png */; }; B63761E319E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761E219E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.m */; }; B63761EC19E1FBE8005735D1 /* HttpRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761E519E1FBE8005735D1 /* HttpRequest.m */; }; B63761ED19E1FBE8005735D1 /* HttpRequestOrResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761E719E1FBE8005735D1 /* HttpRequestOrResponse.m */; }; @@ -447,7 +360,6 @@ B6B096631A1D25ED008BFAA6 /* TSPreKeyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095F11A1D25ED008BFAA6 /* TSPreKeyManager.m */; }; B6B096641A1D25ED008BFAA6 /* TSContactThread.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095F51A1D25ED008BFAA6 /* TSContactThread.m */; }; B6B096651A1D25ED008BFAA6 /* TSGroupThread.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095F71A1D25ED008BFAA6 /* TSGroupThread.m */; }; - B6B096661A1D25ED008BFAA6 /* TSContact.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095F91A1D25ED008BFAA6 /* TSContact.m */; }; B6B096671A1D25ED008BFAA6 /* TSGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095FB1A1D25ED008BFAA6 /* TSGroup.m */; }; B6B096681A1D25ED008BFAA6 /* TSRecipient.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095FD1A1D25ED008BFAA6 /* TSRecipient.m */; }; B6B096691A1D25ED008BFAA6 /* TSThread.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095FF1A1D25ED008BFAA6 /* TSThread.m */; }; @@ -570,6 +482,10 @@ E197B62718BBF63B00F073E5 /* SoundBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = E197B62618BBF63B00F073E5 /* SoundBoard.m */; }; E1CD329618BCFF9900B1A496 /* SoundInstance.m in Sources */ = {isa = PBXBuildFile; fileRef = E1CD329518BCFF9900B1A496 /* SoundInstance.m */; }; F995AC2FFD6D4442B012604A /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8313AE91B4954215858A5662 /* libPods.a */; }; + FC15B7BF1A1F80F200F59801 /* defaultConctact_light@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC15B7BE1A1F80F200F59801 /* defaultConctact_light@2x.png */; }; + FC1F90C01A22342B004F8253 /* group_photo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC1F90BF1A22342B004F8253 /* group_photo@2x.png */; }; + FC1F90C61A223991004F8253 /* settings_tab@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC1F90C41A223991004F8253 /* settings_tab@2x.png */; }; + FC1F90C71A223991004F8253 /* signals_tab@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC1F90C51A223991004F8253 /* signals_tab@2x.png */; }; FC31962A1A067D8F0094C78E /* MessageComposeTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC3196291A067D8F0094C78E /* MessageComposeTableViewController.m */; }; FC31962D1A06A2190094C78E /* FingerprintViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC31962C1A06A2190094C78E /* FingerprintViewController.m */; }; FC3196301A0814130094C78E /* SettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC31962F1A0814130094C78E /* SettingsTableViewController.m */; }; @@ -939,127 +855,40 @@ B60C16641988999D00E97A6C /* VersionMigrations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VersionMigrations.m; sourceTree = ""; }; B60EDE031A05A01700D73516 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; B633C4FE1A1D190B0059AC12 /* archive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "archive@2x.png"; sourceTree = ""; }; - B633C4FF1A1D190B0059AC12 /* archive_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = archive_icon.png; sourceTree = ""; }; - B633C5001A1D190B0059AC12 /* archive_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "archive_icon@2x.png"; sourceTree = ""; }; B633C5011A1D190B0059AC12 /* backspace.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = backspace.png; sourceTree = ""; }; B633C5021A1D190B0059AC12 /* backspace@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "backspace@2x.png"; sourceTree = ""; }; B633C5031A1D190B0059AC12 /* blue-archive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blue-archive@2x.png"; sourceTree = ""; }; B633C5041A1D190B0059AC12 /* call@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call@2x.png"; sourceTree = ""; }; B633C5051A1D190B0059AC12 /* call_dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_dark@2x.png"; sourceTree = ""; }; - B633C5061A1D190B0059AC12 /* checkbox_checkmark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkbox_checkmark.png; sourceTree = ""; }; - B633C5071A1D190B0059AC12 /* checkbox_checkmark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkbox_checkmark@2x.png"; sourceTree = ""; }; - B633C5081A1D190B0059AC12 /* checkbox_empty.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkbox_empty.png; sourceTree = ""; }; - B633C5091A1D190B0059AC12 /* checkbox_empty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkbox_empty@2x.png"; sourceTree = ""; }; B633C50A1A1D190B0059AC12 /* checkmark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkmark.png; sourceTree = ""; }; B633C50B1A1D190B0059AC12 /* contact_default_feed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contact_default_feed.png; sourceTree = ""; }; - B633C50C1A1D190B0059AC12 /* contacts.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts.png; sourceTree = ""; }; B633C50D1A1D190B0059AC12 /* contacts@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts@2x.png"; sourceTree = ""; }; - B633C50E1A1D190B0059AC12 /* contacts_arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts_arrow.png; sourceTree = ""; }; - B633C50F1A1D190B0059AC12 /* contacts_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_arrow@2x.png"; sourceTree = ""; }; B633C5101A1D190B0059AC12 /* contacts_tab@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_tab@2x.png"; sourceTree = ""; }; B633C5141A1D190B0059AC12 /* DefaultContactImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DefaultContactImage.png; sourceTree = ""; }; B633C5151A1D190B0059AC12 /* delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete@2x.png"; sourceTree = ""; }; B633C5161A1D190B0059AC12 /* delete_history@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete_history@2x.png"; sourceTree = ""; }; - B633C5171A1D190B0059AC12 /* dismiss_notification_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dismiss_notification_icon.png; sourceTree = ""; }; - B633C5181A1D190B0059AC12 /* dismiss_notification_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dismiss_notification_icon@2x.png"; sourceTree = ""; }; - B633C5191A1D190B0059AC12 /* drop_down_arrow_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = drop_down_arrow_icon.png; sourceTree = ""; }; - B633C51A1A1D190B0059AC12 /* drop_down_arrow_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "drop_down_arrow_icon@2x.png"; sourceTree = ""; }; B633C51B1A1D190B0059AC12 /* endcall@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "endcall@2x.png"; sourceTree = ""; }; - B633C51C1A1D190B0059AC12 /* expanded_cell_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = expanded_cell_icon.png; sourceTree = ""; }; - B633C51D1A1D190B0059AC12 /* expanded_cell_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "expanded_cell_icon@2x.png"; sourceTree = ""; }; - B633C51E1A1D190B0059AC12 /* favourite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = favourite.png; sourceTree = ""; }; - B633C51F1A1D190B0059AC12 /* favourite_false_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = favourite_false_icon.png; sourceTree = ""; }; - B633C5201A1D190B0059AC12 /* favourite_false_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "favourite_false_icon@2x.png"; sourceTree = ""; }; - B633C5211A1D190B0059AC12 /* favourite_true_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = favourite_true_icon.png; sourceTree = ""; }; - B633C5221A1D190B0059AC12 /* favourite_true_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "favourite_true_icon@2x.png"; sourceTree = ""; }; - B633C5231A1D190B0059AC12 /* forward_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = forward_button.png; sourceTree = ""; }; - B633C5241A1D190B0059AC12 /* forward_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "forward_button@2x.png"; sourceTree = ""; }; - B633C5251A1D190B0059AC12 /* home_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = home_icon.png; sourceTree = ""; }; - B633C5261A1D190B0059AC12 /* icon_contacts.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_contacts.png; sourceTree = ""; }; - B633C5271A1D190B0059AC12 /* icon_favourites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_favourites.png; sourceTree = ""; }; - B633C5281A1D190B0059AC12 /* icon_keypad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_keypad.png; sourceTree = ""; }; - B633C5291A1D190B0059AC12 /* icon_recents.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_recents.png; sourceTree = ""; }; - B633C52A1A1D190B0059AC12 /* in_call_phone_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = in_call_phone_icon.png; sourceTree = ""; }; - B633C52B1A1D190B0059AC12 /* in_call_phone_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "in_call_phone_icon@2x.png"; sourceTree = ""; }; - B633C52C1A1D190B0059AC12 /* in_call_phrase_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = in_call_phrase_icon.png; sourceTree = ""; }; - B633C52D1A1D190B0059AC12 /* in_call_phrase_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "in_call_phrase_icon@2x.png"; sourceTree = ""; }; - B633C52E1A1D190B0059AC12 /* incoming_call_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = incoming_call_icon.png; sourceTree = ""; }; - B633C52F1A1D190B0059AC12 /* incoming_call_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "incoming_call_icon@2x.png"; sourceTree = ""; }; - B633C5301A1D190B0059AC12 /* info@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info@2x.png"; sourceTree = ""; }; B633C5321A1D190B0059AC12 /* keypad@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keypad@2x.png"; sourceTree = ""; }; B633C5331A1D190B0059AC12 /* lock@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lock@2x.png"; sourceTree = ""; }; B633C5341A1D190B0059AC12 /* lock_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lock_white@2x.png"; sourceTree = ""; }; B633C5351A1D190B0059AC12 /* logo_intro@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo_intro@2x.png"; sourceTree = ""; }; - B633C5371A1D190B0059AC12 /* menu_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_icon.png; sourceTree = ""; }; - B633C5381A1D190B0059AC12 /* menu_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_icon@2x.png"; sourceTree = ""; }; B633C5391A1D190B0059AC12 /* message_bubble.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = message_bubble.png; sourceTree = ""; }; B633C53A1A1D190B0059AC12 /* message_bubble@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "message_bubble@2x.png"; sourceTree = ""; }; - B633C53B1A1D190B0059AC12 /* message_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = message_icon.png; sourceTree = ""; }; B633C53C1A1D190B0059AC12 /* missed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = missed.png; sourceTree = ""; }; - B633C53D1A1D190B0059AC12 /* mute_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mute_icon.png; sourceTree = ""; }; - B633C53E1A1D190B0059AC12 /* mute_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mute_icon@2x.png"; sourceTree = ""; }; - B633C53F1A1D190B0059AC12 /* mute_icon_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mute_icon_selected.png; sourceTree = ""; }; - B633C5401A1D190B0059AC12 /* mute_icon_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mute_icon_selected@2x.png"; sourceTree = ""; }; B633C5411A1D190B0059AC12 /* mute_off@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mute_off@2x.png"; sourceTree = ""; }; B633C5421A1D190B0059AC12 /* mute_on@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mute_on@2x.png"; sourceTree = ""; }; - B633C5431A1D190B0059AC12 /* notification_detail_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = notification_detail_icon.png; sourceTree = ""; }; - B633C5441A1D190B0059AC12 /* notification_detail_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "notification_detail_icon@2x.png"; sourceTree = ""; }; - B633C5451A1D190B0059AC12 /* notification_mini_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = notification_mini_icon.png; sourceTree = ""; }; - B633C5461A1D190B0059AC12 /* notification_mini_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "notification_mini_icon@2x.png"; sourceTree = ""; }; - B633C5471A1D190B0059AC12 /* outgoing_call_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = outgoing_call_icon.png; sourceTree = ""; }; - B633C5481A1D190B0059AC12 /* outgoing_call_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "outgoing_call_icon@2x.png"; sourceTree = ""; }; - B633C5491A1D190B0059AC12 /* phone_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = phone_icon.png; sourceTree = ""; }; - B633C54A1A1D190B0059AC12 /* phone_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "phone_icon@2x.png"; sourceTree = ""; }; B633C54B1A1D190B0059AC12 /* photo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "photo@2x.png"; sourceTree = ""; }; B633C54C1A1D190B0059AC12 /* quit@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quit@2x.png"; sourceTree = ""; }; B633C54D1A1D190B0059AC12 /* received.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = received.png; sourceTree = ""; }; B633C54E1A1D190B0059AC12 /* red-delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "red-delete@2x.png"; sourceTree = ""; }; B633C54F1A1D190B0059AC12 /* reply.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = reply.png; sourceTree = ""; }; B633C5501A1D190B0059AC12 /* savephoto@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "savephoto@2x.png"; sourceTree = ""; }; - B633C5511A1D190B0059AC12 /* search_cancel.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = search_cancel.png; sourceTree = ""; }; - B633C5521A1D190B0059AC12 /* search_cancel@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_cancel@2x.png"; sourceTree = ""; }; - B633C5531A1D190B0059AC12 /* search_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = search_icon.png; sourceTree = ""; }; - B633C5541A1D190B0059AC12 /* search_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon@2x.png"; sourceTree = ""; }; - B633C5551A1D190B0059AC12 /* send_code_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = send_code_icon.png; sourceTree = ""; }; - B633C5561A1D190B0059AC12 /* send_code_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "send_code_icon@2x.png"; sourceTree = ""; }; - B633C5571A1D190B0059AC12 /* settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = settings.png; sourceTree = ""; }; B633C5581A1D190B0059AC12 /* settings_dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings_dark@2x.png"; sourceTree = ""; }; B633C5591A1D190B0059AC12 /* share@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "share@2x.png"; sourceTree = ""; }; B633C55A1A1D190B0059AC12 /* shred@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shred@2x.png"; sourceTree = ""; }; B633C55E1A1D190B0059AC12 /* signal@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "signal@2x.png"; sourceTree = ""; }; - B633C55F1A1D190B0059AC12 /* signals.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = signals.png; sourceTree = ""; }; - B633C5601A1D190B0059AC12 /* speaker_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speaker_icon.png; sourceTree = ""; }; - B633C5611A1D190B0059AC12 /* speaker_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_icon@2x.png"; sourceTree = ""; }; - B633C5621A1D190B0059AC12 /* speaker_icon_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speaker_icon_selected.png; sourceTree = ""; }; - B633C5631A1D190B0059AC12 /* speaker_icon_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_icon_selected@2x.png"; sourceTree = ""; }; B633C5641A1D190B0059AC12 /* speaker_off@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_off@2x.png"; sourceTree = ""; }; B633C5651A1D190B0059AC12 /* speaker_on@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_on@2x.png"; sourceTree = ""; }; - B633C5661A1D190B0059AC12 /* spinner_connecting.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = spinner_connecting.png; sourceTree = ""; }; - B633C5671A1D190B0059AC12 /* spinner_connecting@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "spinner_connecting@2x.png"; sourceTree = ""; }; - B633C5681A1D190B0059AC12 /* spinner_connecting_flash.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = spinner_connecting_flash.png; sourceTree = ""; }; - B633C5691A1D190B0059AC12 /* spinner_connecting_flash@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "spinner_connecting_flash@2x.png"; sourceTree = ""; }; - B633C56A1A1D190B0059AC12 /* spinner_error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = spinner_error.png; sourceTree = ""; }; - B633C56B1A1D190B0059AC12 /* spinner_error@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "spinner_error@2x.png"; sourceTree = ""; }; - B633C56C1A1D190B0059AC12 /* spinner_ringing.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = spinner_ringing.png; sourceTree = ""; }; - B633C56D1A1D190B0059AC12 /* spinner_ringing@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "spinner_ringing@2x.png"; sourceTree = ""; }; - B633C56E1A1D190B0059AC12 /* tab_icon_contacts.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab_icon_contacts.png; sourceTree = ""; }; - B633C56F1A1D190B0059AC12 /* tab_icon_contacts@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_icon_contacts@2x.png"; sourceTree = ""; }; - B633C5701A1D190B0059AC12 /* tab_icon_favourites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab_icon_favourites.png; sourceTree = ""; }; - B633C5711A1D190B0059AC12 /* tab_icon_favourites@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_icon_favourites@2x.png"; sourceTree = ""; }; - B633C5721A1D190B0059AC12 /* tab_icon_inbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab_icon_inbox.png; sourceTree = ""; }; - B633C5731A1D190B0059AC12 /* tab_icon_inbox@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_icon_inbox@2x.png"; sourceTree = ""; }; - B633C5741A1D190B0059AC12 /* tab_icon_keypad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab_icon_keypad.png; sourceTree = ""; }; - B633C5751A1D190B0059AC12 /* tab_icon_keypad@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_icon_keypad@2x.png"; sourceTree = ""; }; - B633C5761A1D190B0059AC12 /* tab_icon_menu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab_icon_menu.png; sourceTree = ""; }; - B633C5771A1D190B0059AC12 /* tab_icon_menu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_icon_menu@2x.png"; sourceTree = ""; }; - B633C5781A1D190B0059AC12 /* trash_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = trash_icon.png; sourceTree = ""; }; - B633C5791A1D190B0059AC12 /* trash_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "trash_icon@2x.png"; sourceTree = ""; }; - B633C57A1A1D190B0059AC12 /* volume_high.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = volume_high.png; sourceTree = ""; }; - B633C57B1A1D190B0059AC12 /* volume_high@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "volume_high@2x.png"; sourceTree = ""; }; - B633C57C1A1D190B0059AC12 /* volume_low.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = volume_low.png; sourceTree = ""; }; - B633C57D1A1D190B0059AC12 /* volume_low@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "volume_low@2x.png"; sourceTree = ""; }; - B633C57E1A1D190B0059AC12 /* whisper_notification_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = whisper_notification_icon.png; sourceTree = ""; }; - B633C57F1A1D190B0059AC12 /* whisper_notification_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "whisper_notification_icon@2x.png"; sourceTree = ""; }; B63761E119E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AFHTTPSessionManager+SignalMethods.h"; sourceTree = ""; }; B63761E219E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AFHTTPSessionManager+SignalMethods.m"; sourceTree = ""; }; B63761E419E1FBE8005735D1 /* HttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpRequest.h; sourceTree = ""; }; @@ -1168,14 +997,12 @@ B6B095F51A1D25ED008BFAA6 /* TSContactThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSContactThread.m; sourceTree = ""; }; B6B095F61A1D25ED008BFAA6 /* TSGroupThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSGroupThread.h; sourceTree = ""; }; B6B095F71A1D25ED008BFAA6 /* TSGroupThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGroupThread.m; sourceTree = ""; }; - B6B095F81A1D25ED008BFAA6 /* TSContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSContact.h; sourceTree = ""; }; - B6B095F91A1D25ED008BFAA6 /* TSContact.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSContact.m; sourceTree = ""; }; B6B095FA1A1D25ED008BFAA6 /* TSGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSGroup.h; sourceTree = ""; }; B6B095FB1A1D25ED008BFAA6 /* TSGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGroup.m; sourceTree = ""; }; B6B095FC1A1D25ED008BFAA6 /* TSRecipient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSRecipient.h; sourceTree = ""; }; B6B095FD1A1D25ED008BFAA6 /* TSRecipient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSRecipient.m; sourceTree = ""; }; - B6B095FE1A1D25ED008BFAA6 /* TSThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSThread.h; sourceTree = ""; }; - B6B095FF1A1D25ED008BFAA6 /* TSThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSThread.m; sourceTree = ""; }; + B6B095FE1A1D25ED008BFAA6 /* TSThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSThread.h; path = ../TSThread.h; sourceTree = ""; }; + B6B095FF1A1D25ED008BFAA6 /* TSThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSThread.m; path = ../TSThread.m; sourceTree = ""; }; B6B096011A1D25ED008BFAA6 /* IncomingPushMessageSignal.pb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncomingPushMessageSignal.pb.h; sourceTree = ""; }; B6B096021A1D25ED008BFAA6 /* IncomingPushMessageSignal.pb.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IncomingPushMessageSignal.pb.m; sourceTree = ""; }; B6B096031A1D25ED008BFAA6 /* TSAttachement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAttachement.h; sourceTree = ""; }; @@ -1349,6 +1176,10 @@ E1C407C117F0C246007BEE65 /* whisperReal.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperReal.cer; sourceTree = ""; }; E1CD329418BCFF9900B1A496 /* SoundInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoundInstance.h; sourceTree = ""; }; E1CD329518BCFF9900B1A496 /* SoundInstance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SoundInstance.m; sourceTree = ""; }; + FC15B7BE1A1F80F200F59801 /* defaultConctact_light@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "defaultConctact_light@2x.png"; sourceTree = ""; }; + FC1F90BF1A22342B004F8253 /* group_photo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "group_photo@2x.png"; sourceTree = ""; }; + FC1F90C41A223991004F8253 /* settings_tab@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings_tab@2x.png"; sourceTree = ""; }; + FC1F90C51A223991004F8253 /* signals_tab@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "signals_tab@2x.png"; sourceTree = ""; }; FC3196281A067D8F0094C78E /* MessageComposeTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageComposeTableViewController.h; sourceTree = ""; }; FC3196291A067D8F0094C78E /* MessageComposeTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageComposeTableViewController.m; sourceTree = ""; }; FC31962B1A06A2190094C78E /* FingerprintViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewController.h; sourceTree = ""; }; @@ -1558,6 +1389,7 @@ 76EB040318170B33006006FC /* contact */ = { isa = PBXGroup; children = ( + 76EB04A818170B33006006FC /* number directory */, 76EB040418170B33006006FC /* Contact.h */, 76EB040518170B33006006FC /* Contact.m */, 76EB040818170B33006006FC /* ContactsManager.h */, @@ -1847,7 +1679,6 @@ 76EB04A518170B33006006FC /* InitiateSignal.proto */, 76EB04A618170B33006006FC /* InitiatorSessionDescriptor.h */, 76EB04A718170B33006006FC /* InitiatorSessionDescriptor.m */, - 76EB04A818170B33006006FC /* number directory */, 76EB04AD18170B33006006FC /* ResponderSessionDescriptor.h */, 76EB04AE18170B33006006FC /* ResponderSessionDescriptor.m */, 76EB04AF18170B33006006FC /* SignalUtil.h */, @@ -1864,7 +1695,8 @@ 76EB04AB18170B33006006FC /* PhoneNumberDirectoryFilterManager.h */, 76EB04AC18170B33006006FC /* PhoneNumberDirectoryFilterManager.m */, ); - path = "number directory"; + name = "number directory"; + path = "../phone/signaling/number directory"; sourceTree = ""; }; 76EB04B118170B33006006FC /* profiling */ = { @@ -2255,127 +2087,44 @@ isa = PBXGroup; children = ( B633C4FE1A1D190B0059AC12 /* archive@2x.png */, - B633C4FF1A1D190B0059AC12 /* archive_icon.png */, - B633C5001A1D190B0059AC12 /* archive_icon@2x.png */, B633C5011A1D190B0059AC12 /* backspace.png */, B633C5021A1D190B0059AC12 /* backspace@2x.png */, B633C5031A1D190B0059AC12 /* blue-archive@2x.png */, B633C5041A1D190B0059AC12 /* call@2x.png */, B633C5051A1D190B0059AC12 /* call_dark@2x.png */, - B633C5061A1D190B0059AC12 /* checkbox_checkmark.png */, - B633C5071A1D190B0059AC12 /* checkbox_checkmark@2x.png */, - B633C5081A1D190B0059AC12 /* checkbox_empty.png */, - B633C5091A1D190B0059AC12 /* checkbox_empty@2x.png */, B633C50A1A1D190B0059AC12 /* checkmark.png */, B633C50B1A1D190B0059AC12 /* contact_default_feed.png */, - B633C50C1A1D190B0059AC12 /* contacts.png */, B633C50D1A1D190B0059AC12 /* contacts@2x.png */, - B633C50E1A1D190B0059AC12 /* contacts_arrow.png */, - B633C50F1A1D190B0059AC12 /* contacts_arrow@2x.png */, B633C5101A1D190B0059AC12 /* contacts_tab@2x.png */, B633C5141A1D190B0059AC12 /* DefaultContactImage.png */, + FC15B7BE1A1F80F200F59801 /* defaultConctact_light@2x.png */, B633C5151A1D190B0059AC12 /* delete@2x.png */, B633C5161A1D190B0059AC12 /* delete_history@2x.png */, - B633C5171A1D190B0059AC12 /* dismiss_notification_icon.png */, - B633C5181A1D190B0059AC12 /* dismiss_notification_icon@2x.png */, - B633C5191A1D190B0059AC12 /* drop_down_arrow_icon.png */, - B633C51A1A1D190B0059AC12 /* drop_down_arrow_icon@2x.png */, B633C51B1A1D190B0059AC12 /* endcall@2x.png */, - B633C51C1A1D190B0059AC12 /* expanded_cell_icon.png */, - B633C51D1A1D190B0059AC12 /* expanded_cell_icon@2x.png */, - B633C51E1A1D190B0059AC12 /* favourite.png */, - B633C51F1A1D190B0059AC12 /* favourite_false_icon.png */, - B633C5201A1D190B0059AC12 /* favourite_false_icon@2x.png */, - B633C5211A1D190B0059AC12 /* favourite_true_icon.png */, - B633C5221A1D190B0059AC12 /* favourite_true_icon@2x.png */, - B633C5231A1D190B0059AC12 /* forward_button.png */, - B633C5241A1D190B0059AC12 /* forward_button@2x.png */, - B633C5251A1D190B0059AC12 /* home_icon.png */, - B633C5261A1D190B0059AC12 /* icon_contacts.png */, - B633C5271A1D190B0059AC12 /* icon_favourites.png */, - B633C5281A1D190B0059AC12 /* icon_keypad.png */, - B633C5291A1D190B0059AC12 /* icon_recents.png */, - B633C52A1A1D190B0059AC12 /* in_call_phone_icon.png */, - B633C52B1A1D190B0059AC12 /* in_call_phone_icon@2x.png */, - B633C52C1A1D190B0059AC12 /* in_call_phrase_icon.png */, - B633C52D1A1D190B0059AC12 /* in_call_phrase_icon@2x.png */, - B633C52E1A1D190B0059AC12 /* incoming_call_icon.png */, - B633C52F1A1D190B0059AC12 /* incoming_call_icon@2x.png */, - B633C5301A1D190B0059AC12 /* info@2x.png */, + FC1F90BF1A22342B004F8253 /* group_photo@2x.png */, B633C5321A1D190B0059AC12 /* keypad@2x.png */, B633C5331A1D190B0059AC12 /* lock@2x.png */, B633C5341A1D190B0059AC12 /* lock_white@2x.png */, B633C5351A1D190B0059AC12 /* logo_intro@2x.png */, - B633C5371A1D190B0059AC12 /* menu_icon.png */, - B633C5381A1D190B0059AC12 /* menu_icon@2x.png */, B633C5391A1D190B0059AC12 /* message_bubble.png */, B633C53A1A1D190B0059AC12 /* message_bubble@2x.png */, - B633C53B1A1D190B0059AC12 /* message_icon.png */, B633C53C1A1D190B0059AC12 /* missed.png */, - B633C53D1A1D190B0059AC12 /* mute_icon.png */, - B633C53E1A1D190B0059AC12 /* mute_icon@2x.png */, - B633C53F1A1D190B0059AC12 /* mute_icon_selected.png */, - B633C5401A1D190B0059AC12 /* mute_icon_selected@2x.png */, B633C5411A1D190B0059AC12 /* mute_off@2x.png */, B633C5421A1D190B0059AC12 /* mute_on@2x.png */, - B633C5431A1D190B0059AC12 /* notification_detail_icon.png */, - B633C5441A1D190B0059AC12 /* notification_detail_icon@2x.png */, - B633C5451A1D190B0059AC12 /* notification_mini_icon.png */, - B633C5461A1D190B0059AC12 /* notification_mini_icon@2x.png */, - B633C5471A1D190B0059AC12 /* outgoing_call_icon.png */, - B633C5481A1D190B0059AC12 /* outgoing_call_icon@2x.png */, - B633C5491A1D190B0059AC12 /* phone_icon.png */, - B633C54A1A1D190B0059AC12 /* phone_icon@2x.png */, B633C54B1A1D190B0059AC12 /* photo@2x.png */, B633C54C1A1D190B0059AC12 /* quit@2x.png */, B633C54D1A1D190B0059AC12 /* received.png */, B633C54E1A1D190B0059AC12 /* red-delete@2x.png */, B633C54F1A1D190B0059AC12 /* reply.png */, B633C5501A1D190B0059AC12 /* savephoto@2x.png */, - B633C5511A1D190B0059AC12 /* search_cancel.png */, - B633C5521A1D190B0059AC12 /* search_cancel@2x.png */, - B633C5531A1D190B0059AC12 /* search_icon.png */, - B633C5541A1D190B0059AC12 /* search_icon@2x.png */, - B633C5551A1D190B0059AC12 /* send_code_icon.png */, - B633C5561A1D190B0059AC12 /* send_code_icon@2x.png */, - B633C5571A1D190B0059AC12 /* settings.png */, B633C5581A1D190B0059AC12 /* settings_dark@2x.png */, + FC1F90C41A223991004F8253 /* settings_tab@2x.png */, B633C5591A1D190B0059AC12 /* share@2x.png */, B633C55A1A1D190B0059AC12 /* shred@2x.png */, B633C55E1A1D190B0059AC12 /* signal@2x.png */, - B633C55F1A1D190B0059AC12 /* signals.png */, - B633C5601A1D190B0059AC12 /* speaker_icon.png */, - B633C5611A1D190B0059AC12 /* speaker_icon@2x.png */, - B633C5621A1D190B0059AC12 /* speaker_icon_selected.png */, - B633C5631A1D190B0059AC12 /* speaker_icon_selected@2x.png */, + FC1F90C51A223991004F8253 /* signals_tab@2x.png */, B633C5641A1D190B0059AC12 /* speaker_off@2x.png */, B633C5651A1D190B0059AC12 /* speaker_on@2x.png */, - B633C5661A1D190B0059AC12 /* spinner_connecting.png */, - B633C5671A1D190B0059AC12 /* spinner_connecting@2x.png */, - B633C5681A1D190B0059AC12 /* spinner_connecting_flash.png */, - B633C5691A1D190B0059AC12 /* spinner_connecting_flash@2x.png */, - B633C56A1A1D190B0059AC12 /* spinner_error.png */, - B633C56B1A1D190B0059AC12 /* spinner_error@2x.png */, - B633C56C1A1D190B0059AC12 /* spinner_ringing.png */, - B633C56D1A1D190B0059AC12 /* spinner_ringing@2x.png */, - B633C56E1A1D190B0059AC12 /* tab_icon_contacts.png */, - B633C56F1A1D190B0059AC12 /* tab_icon_contacts@2x.png */, - B633C5701A1D190B0059AC12 /* tab_icon_favourites.png */, - B633C5711A1D190B0059AC12 /* tab_icon_favourites@2x.png */, - B633C5721A1D190B0059AC12 /* tab_icon_inbox.png */, - B633C5731A1D190B0059AC12 /* tab_icon_inbox@2x.png */, - B633C5741A1D190B0059AC12 /* tab_icon_keypad.png */, - B633C5751A1D190B0059AC12 /* tab_icon_keypad@2x.png */, - B633C5761A1D190B0059AC12 /* tab_icon_menu.png */, - B633C5771A1D190B0059AC12 /* tab_icon_menu@2x.png */, - B633C5781A1D190B0059AC12 /* trash_icon.png */, - B633C5791A1D190B0059AC12 /* trash_icon@2x.png */, - B633C57A1A1D190B0059AC12 /* volume_high.png */, - B633C57B1A1D190B0059AC12 /* volume_high@2x.png */, - B633C57C1A1D190B0059AC12 /* volume_low.png */, - B633C57D1A1D190B0059AC12 /* volume_low@2x.png */, - B633C57E1A1D190B0059AC12 /* whisper_notification_icon.png */, - B633C57F1A1D190B0059AC12 /* whisper_notification_icon@2x.png */, ); path = Images; sourceTree = ""; @@ -2855,14 +2604,10 @@ isa = PBXGroup; children = ( B6B095F31A1D25ED008BFAA6 /* Threads */, - B6B095F81A1D25ED008BFAA6 /* TSContact.h */, - B6B095F91A1D25ED008BFAA6 /* TSContact.m */, B6B095FA1A1D25ED008BFAA6 /* TSGroup.h */, B6B095FB1A1D25ED008BFAA6 /* TSGroup.m */, B6B095FC1A1D25ED008BFAA6 /* TSRecipient.h */, B6B095FD1A1D25ED008BFAA6 /* TSRecipient.m */, - B6B095FE1A1D25ED008BFAA6 /* TSThread.h */, - B6B095FF1A1D25ED008BFAA6 /* TSThread.m */, ); path = Contacts; sourceTree = ""; @@ -2874,6 +2619,8 @@ B6B095F51A1D25ED008BFAA6 /* TSContactThread.m */, B6B095F61A1D25ED008BFAA6 /* TSGroupThread.h */, B6B095F71A1D25ED008BFAA6 /* TSGroupThread.m */, + B6B095FE1A1D25ED008BFAA6 /* TSThread.h */, + B6B095FF1A1D25ED008BFAA6 /* TSThread.m */, ); path = Threads; sourceTree = ""; @@ -3353,7 +3100,7 @@ ORGANIZATIONNAME = "Open Whisper Systems"; TargetAttributes = { D221A088169C9E5E00537ABF = { - DevelopmentTeam = U68MSDN6DR; + DevelopmentTeam = DRXTS3ZU8M; SystemCapabilities = { com.apple.DataProtection = { enabled = 1; @@ -3467,154 +3214,71 @@ files = ( E148750018A06966002CC4F3 /* CallAudioManagerDemo.xib in Resources */, B633C5DC1A1D190B0059AC12 /* shred@2x.png in Resources */, - B633C5E91A1D190B0059AC12 /* spinner_connecting_flash.png in Resources */, B633C5E61A1D190B0059AC12 /* speaker_on@2x.png in Resources */, B633C5BB1A1D190B0059AC12 /* message_bubble.png in Resources */, B633C5B51A1D190B0059AC12 /* lock@2x.png in Resources */, - B633C58E1A1D190B0059AC12 /* contacts.png in Resources */, - B633C5A41A1D190B0059AC12 /* favourite_true_icon@2x.png in Resources */, + FC1F90C01A22342B004F8253 /* group_photo@2x.png in Resources */, E148750518A06966002CC4F3 /* CountryCodeViewController.xib in Resources */, B633C5C41A1D190B0059AC12 /* mute_on@2x.png in Resources */, - B633C5F41A1D190B0059AC12 /* tab_icon_inbox@2x.png in Resources */, E148750618A06966002CC4F3 /* DialerViewController.xib in Resources */, B633C5CE1A1D190B0059AC12 /* quit@2x.png in Resources */, E148750A18A06966002CC4F3 /* InCallViewController.xib in Resources */, - B633C5E71A1D190B0059AC12 /* spinner_connecting.png in Resources */, B633C5D01A1D190B0059AC12 /* red-delete@2x.png in Resources */, B633C59D1A1D190B0059AC12 /* endcall@2x.png in Resources */, - B633C5C91A1D190B0059AC12 /* outgoing_call_icon.png in Resources */, - B633C5EA1A1D190B0059AC12 /* spinner_connecting_flash@2x.png in Resources */, - B633C5E31A1D190B0059AC12 /* speaker_icon_selected.png in Resources */, - B633C5B01A1D190B0059AC12 /* incoming_call_icon.png in Resources */, B633C5CF1A1D190B0059AC12 /* received.png in Resources */, - B633C5AD1A1D190B0059AC12 /* in_call_phone_icon@2x.png in Resources */, - B633C5FA1A1D190B0059AC12 /* trash_icon@2x.png in Resources */, - B633C5C11A1D190B0059AC12 /* mute_icon_selected.png in Resources */, - B633C5AA1A1D190B0059AC12 /* icon_keypad.png in Resources */, B633C5B41A1D190B0059AC12 /* keypad@2x.png in Resources */, - B633C5FD1A1D190B0059AC12 /* volume_low.png in Resources */, B633C5DA1A1D190B0059AC12 /* settings_dark@2x.png in Resources */, E14874F818A06951002CC4F3 /* ContactTableViewCell.xib in Resources */, B633C5BC1A1D190B0059AC12 /* message_bubble@2x.png in Resources */, - B633C5EF1A1D190B0059AC12 /* tab_icon_contacts.png in Resources */, B633C5D11A1D190B0059AC12 /* reply.png in Resources */, - B633C5EE1A1D190B0059AC12 /* spinner_ringing@2x.png in Resources */, - B633C6001A1D190B0059AC12 /* whisper_notification_icon@2x.png in Resources */, + FC15B7BF1A1F80F200F59801 /* defaultConctact_light@2x.png in Resources */, E14874F918A06951002CC4F3 /* CountryCodeTableViewCell.xib in Resources */, - B633C5BF1A1D190B0059AC12 /* mute_icon.png in Resources */, - B633C5ED1A1D190B0059AC12 /* spinner_ringing.png in Resources */, - B633C5911A1D190B0059AC12 /* contacts_arrow@2x.png in Resources */, B633C5871A1D190B0059AC12 /* call_dark@2x.png in Resources */, - B633C5FC1A1D190B0059AC12 /* volume_high@2x.png in Resources */, B633C5BE1A1D190B0059AC12 /* missed.png in Resources */, - B633C5AC1A1D190B0059AC12 /* in_call_phone_icon.png in Resources */, B633C5851A1D190B0059AC12 /* blue-archive@2x.png in Resources */, - B633C5BD1A1D190B0059AC12 /* message_icon.png in Resources */, - B633C5AF1A1D190B0059AC12 /* in_call_phrase_icon@2x.png in Resources */, B633C5D21A1D190B0059AC12 /* savephoto@2x.png in Resources */, - B633C5D41A1D190B0059AC12 /* search_cancel@2x.png in Resources */, - B633C5A51A1D190B0059AC12 /* forward_button.png in Resources */, - B633C5F11A1D190B0059AC12 /* tab_icon_favourites.png in Resources */, - B633C5D81A1D190B0059AC12 /* send_code_icon@2x.png in Resources */, - B633C5CC1A1D190B0059AC12 /* phone_icon@2x.png in Resources */, B633C58C1A1D190B0059AC12 /* checkmark.png in Resources */, B633C5921A1D190B0059AC12 /* contacts_tab@2x.png in Resources */, - B633C5AE1A1D190B0059AC12 /* in_call_phrase_icon.png in Resources */, - B633C5D51A1D190B0059AC12 /* search_icon.png in Resources */, - B633C5811A1D190B0059AC12 /* archive_icon.png in Resources */, B6416FB8199A0478003C5699 /* Localizable.strings in Resources */, - B633C5F81A1D190B0059AC12 /* tab_icon_menu@2x.png in Resources */, - B633C5D91A1D190B0059AC12 /* settings.png in Resources */, - B633C5FB1A1D190B0059AC12 /* volume_high.png in Resources */, B633C5971A1D190B0059AC12 /* delete@2x.png in Resources */, FCAC964119FEF99A0046DFC5 /* InboxTableViewCell.xib in Resources */, - B633C5E21A1D190B0059AC12 /* speaker_icon@2x.png in Resources */, - B633C5A91A1D190B0059AC12 /* icon_favourites.png in Resources */, B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */, - B633C58B1A1D190B0059AC12 /* checkbox_empty@2x.png in Resources */, 70B8FEE21909FE360042E3F0 /* 171756__nenadsimic__picked-coin-echo-2.wav in Resources */, - B633C5881A1D190B0059AC12 /* checkbox_checkmark.png in Resources */, - B633C5E81A1D190B0059AC12 /* spinner_connecting@2x.png in Resources */, - B633C59B1A1D190B0059AC12 /* drop_down_arrow_icon.png in Resources */, - B633C5F71A1D190B0059AC12 /* tab_icon_menu.png in Resources */, - B633C5B91A1D190B0059AC12 /* menu_icon.png in Resources */, - B633C5E41A1D190B0059AC12 /* speaker_icon_selected@2x.png in Resources */, B633C5801A1D190B0059AC12 /* archive@2x.png in Resources */, E1370BEA18A0689000826894 /* AppIcon29x29.jpg in Resources */, E1370BEB18A0689000826894 /* AppIcon29x29.png in Resources */, - B633C5E11A1D190B0059AC12 /* speaker_icon.png in Resources */, - B633C5A31A1D190B0059AC12 /* favourite_true_icon.png in Resources */, E1370BEC18A0689000826894 /* AppIcon29x29@2x.png in Resources */, - B633C5991A1D190B0059AC12 /* dismiss_notification_icon.png in Resources */, - B633C5F61A1D190B0059AC12 /* tab_icon_keypad@2x.png in Resources */, - B633C5F91A1D190B0059AC12 /* trash_icon.png in Resources */, + FC1F90C71A223991004F8253 /* signals_tab@2x.png in Resources */, E1370BED18A0689000826894 /* AppIcon40x40.png in Resources */, B633C5C31A1D190B0059AC12 /* mute_off@2x.png in Resources */, + FC1F90C61A223991004F8253 /* settings_tab@2x.png in Resources */, E1370BEE18A0689000826894 /* AppIcon40x40@2x.png in Resources */, - B633C5FE1A1D190B0059AC12 /* volume_low@2x.png in Resources */, - B633C58A1A1D190B0059AC12 /* checkbox_empty.png in Resources */, - B633C59C1A1D190B0059AC12 /* drop_down_arrow_icon@2x.png in Resources */, - B633C5E01A1D190B0059AC12 /* signals.png in Resources */, E1370BEF18A0689000826894 /* AppIcon60x60.png in Resources */, - B633C5FF1A1D190B0059AC12 /* whisper_notification_icon.png in Resources */, - B633C5901A1D190B0059AC12 /* contacts_arrow.png in Resources */, - B633C5BA1A1D190B0059AC12 /* menu_icon@2x.png in Resources */, E1370BF018A0689000826894 /* AppIcon60x60@2x.png in Resources */, - B633C5D71A1D190B0059AC12 /* send_code_icon.png in Resources */, - B633C59A1A1D190B0059AC12 /* dismiss_notification_icon@2x.png in Resources */, - B633C5821A1D190B0059AC12 /* archive_icon@2x.png in Resources */, - B633C5D31A1D190B0059AC12 /* search_cancel.png in Resources */, E1370BF118A0689000826894 /* AppIcon76x76.png in Resources */, E1370BF218A0689000826894 /* AppIcon76x76@2x.png in Resources */, - B633C5F31A1D190B0059AC12 /* tab_icon_inbox.png in Resources */, B633C5B61A1D190B0059AC12 /* lock_white@2x.png in Resources */, B633C5DF1A1D190B0059AC12 /* signal@2x.png in Resources */, - B633C5CA1A1D190B0059AC12 /* outgoing_call_icon@2x.png in Resources */, - B633C5A11A1D190B0059AC12 /* favourite_false_icon.png in Resources */, - B633C5F01A1D190B0059AC12 /* tab_icon_contacts@2x.png in Resources */, B633C5831A1D190B0059AC12 /* backspace.png in Resources */, E1370BE018A0686600826894 /* busy.mp3 in Resources */, - B633C5A01A1D190B0059AC12 /* favourite.png in Resources */, E1370BE118A0686C00826894 /* completed.mp3 in Resources */, - B633C5EB1A1D190B0059AC12 /* spinner_error.png in Resources */, E1370BE218A0686C00826894 /* failure.mp3 in Resources */, - B633C5C61A1D190B0059AC12 /* notification_detail_icon@2x.png in Resources */, - B633C5F51A1D190B0059AC12 /* tab_icon_keypad.png in Resources */, - B633C59F1A1D190B0059AC12 /* expanded_cell_icon@2x.png in Resources */, - B633C5D61A1D190B0059AC12 /* search_icon@2x.png in Resources */, B633C5DB1A1D190B0059AC12 /* share@2x.png in Resources */, E1370BE318A0686C00826894 /* handshake.mp3 in Resources */, B633C58D1A1D190B0059AC12 /* contact_default_feed.png in Resources */, - B633C5C21A1D190B0059AC12 /* mute_icon_selected@2x.png in Resources */, - B633C5A71A1D190B0059AC12 /* home_icon.png in Resources */, - B633C5B11A1D190B0059AC12 /* incoming_call_icon@2x.png in Resources */, - B633C5B21A1D190B0059AC12 /* info@2x.png in Resources */, - B633C5AB1A1D190B0059AC12 /* icon_recents.png in Resources */, B633C5CD1A1D190B0059AC12 /* photo@2x.png in Resources */, - B633C59E1A1D190B0059AC12 /* expanded_cell_icon.png in Resources */, - B633C5C51A1D190B0059AC12 /* notification_detail_icon.png in Resources */, - B633C5A81A1D190B0059AC12 /* icon_contacts.png in Resources */, B633C5861A1D190B0059AC12 /* call@2x.png in Resources */, - B633C5C71A1D190B0059AC12 /* notification_mini_icon.png in Resources */, FCAC963519FEF4E20046DFC5 /* Storyboard.storyboard in Resources */, B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */, E1370BE418A0686C00826894 /* outring.mp3 in Resources */, B633C5841A1D190B0059AC12 /* backspace@2x.png in Resources */, - B633C5CB1A1D190B0059AC12 /* phone_icon.png in Resources */, - B633C5A21A1D190B0059AC12 /* favourite_false_icon@2x.png in Resources */, - B633C5EC1A1D190B0059AC12 /* spinner_error@2x.png in Resources */, - B633C5F21A1D190B0059AC12 /* tab_icon_favourites@2x.png in Resources */, B633C5B71A1D190B0059AC12 /* logo_intro@2x.png in Resources */, E1370BE518A0686C00826894 /* r.caf in Resources */, - B633C5C81A1D190B0059AC12 /* notification_mini_icon@2x.png in Resources */, B633C5981A1D190B0059AC12 /* delete_history@2x.png in Resources */, B633C5E51A1D190B0059AC12 /* speaker_off@2x.png in Resources */, - B633C5891A1D190B0059AC12 /* checkbox_checkmark@2x.png in Resources */, B633C58F1A1D190B0059AC12 /* contacts@2x.png in Resources */, - B633C5C01A1D190B0059AC12 /* mute_icon@2x.png in Resources */, E1370BE618A0686C00826894 /* sonarping.mp3 in Resources */, B633C5961A1D190B0059AC12 /* DefaultContactImage.png in Resources */, - B633C5A61A1D190B0059AC12 /* forward_button@2x.png in Resources */, E148751218A06AFD002CC4F3 /* HelveticaNeueLTStd-Bd.otf in Resources */, E148751318A06AFD002CC4F3 /* HelveticaNeueLTStd-Th.otf in Resources */, E148751418A06AFD002CC4F3 /* HelveticaNeueLTStd-Lt.otf in Resources */, @@ -3940,7 +3604,6 @@ E197B61318BBEC1A00F073E5 /* DesiredBufferDepthController.m in Sources */, 76EB064818170B33006006FC /* Zid.m in Sources */, B6B096741A1D25ED008BFAA6 /* TSMessagesManager.m in Sources */, - B6B096661A1D25ED008BFAA6 /* TSContact.m in Sources */, 76EB05E218170B33006006FC /* SecureEndPoint.m in Sources */, B63AF5CC1A1F757900D01AAD /* TSRegisterWithTokenRequest.m in Sources */, 76EB05DE18170B33006006FC /* Certificate.m in Sources */, @@ -4514,6 +4177,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-fobjc-arc-exceptions"; + PROVISIONING_PROFILE = "87a69a1c-864f-4e05-8d48-b9268ace6179"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -4565,7 +4229,7 @@ LLVM_LTO = NO; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_NAME = Signal; - PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE = "87a69a1c-864f-4e05-8d48-b9268ace6179"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 1; TEST_AFTER_BUILD = YES; @@ -4684,6 +4348,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "-fobjc-arc-exceptions"; + PROVISIONING_PROFILE = "87a69a1c-864f-4e05-8d48-b9268ace6179"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -4748,6 +4413,7 @@ "-DNS_BLOCK_ASSERTIONS=1", "-fobjc-arc-exceptions", ); + PROVISIONING_PROFILE = "87a69a1c-864f-4e05-8d48-b9268ace6179"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -4798,7 +4464,7 @@ LLVM_LTO = NO; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_NAME = Signal; - PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE = "87a69a1c-864f-4e05-8d48-b9268ace6179"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 1; TEST_AFTER_BUILD = YES; @@ -4852,7 +4518,7 @@ LLVM_LTO = NO; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_NAME = Signal; - PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE = "87a69a1c-864f-4e05-8d48-b9268ace6179"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 1; TEST_AFTER_BUILD = YES; diff --git a/Signal.xcworkspace/xcshareddata/Signal.xccheckout b/Signal.xcworkspace/xcshareddata/Signal.xccheckout index d6725997c5..711f5d132d 100644 --- a/Signal.xcworkspace/xcshareddata/Signal.xccheckout +++ b/Signal.xcworkspace/xcshareddata/Signal.xccheckout @@ -5,15 +5,13 @@ IDESourceControlProjectFavoriteDictionaryKey IDESourceControlProjectIdentifier - 90A05A58-76B3-4EF9-A59F-88109694A394 + DA00CCAC-808E-4CDA-A72F-CB8431C155C0 IDESourceControlProjectName Signal IDESourceControlProjectOriginsDictionary 5D79A077E31B3FE97A3C6613CBFFDD71C314D14C - github.com:WhisperSystems/Signal-iOS.git - D74FB800F048CB516BB4BC70047F7CC676D291B9 - https://github.com/FredericJacobs/Precompiled-Signal-Dependencies.git + https://github.com/WhisperSystems/Signal-iOS IDESourceControlProjectPath Signal.xcworkspace @@ -21,11 +19,9 @@ 5D79A077E31B3FE97A3C6613CBFFDD71C314D14C .. - D74FB800F048CB516BB4BC70047F7CC676D291B9 - ..Pods IDESourceControlProjectURL - github.com:WhisperSystems/Signal-iOS.git + https://github.com/WhisperSystems/Signal-iOS IDESourceControlProjectVersion 111 IDESourceControlProjectWCCIdentifier @@ -40,14 +36,6 @@ IDESourceControlWCCName Signal-iOS - - IDESourceControlRepositoryExtensionIdentifierKey - public.vcs.git - IDESourceControlWCCIdentifierKey - D74FB800F048CB516BB4BC70047F7CC676D291B9 - IDESourceControlWCCName - Signal-iOSPods - diff --git a/Signal/Images.xcassets/LaunchImage.launchimage/Contents.json b/Signal/Images.xcassets/LaunchImage.launchimage/Contents.json index 2b2d822424..cd2e2b82f2 100644 --- a/Signal/Images.xcassets/LaunchImage.launchimage/Contents.json +++ b/Signal/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -18,11 +18,12 @@ "scale" : "3x" }, { - "orientation" : "portrait", - "idiom" : "iphone", "extent" : "full-screen", - "minimum-system-version" : "8.0", + "idiom" : "iphone", "subtype" : "667h", + "filename" : "Default-6.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", "scale" : "2x" }, { diff --git a/Signal/Images.xcassets/LaunchImage.launchimage/Default-6.png b/Signal/Images.xcassets/LaunchImage.launchimage/Default-6.png new file mode 100644 index 0000000000..efc1cc250f Binary files /dev/null and b/Signal/Images.xcassets/LaunchImage.launchimage/Default-6.png differ diff --git a/Signal/Images/archive_icon.png b/Signal/Images/archive_icon.png deleted file mode 100644 index 9c6ad95b04..0000000000 Binary files a/Signal/Images/archive_icon.png and /dev/null differ diff --git a/Signal/Images/archive_icon@2x.png b/Signal/Images/archive_icon@2x.png deleted file mode 100644 index 9354084c0c..0000000000 Binary files a/Signal/Images/archive_icon@2x.png and /dev/null differ diff --git a/Signal/Images/checkbox_checkmark.png b/Signal/Images/checkbox_checkmark.png deleted file mode 100644 index 9bef98230c..0000000000 Binary files a/Signal/Images/checkbox_checkmark.png and /dev/null differ diff --git a/Signal/Images/checkbox_checkmark@2x.png b/Signal/Images/checkbox_checkmark@2x.png deleted file mode 100644 index b2f14d7fd7..0000000000 Binary files a/Signal/Images/checkbox_checkmark@2x.png and /dev/null differ diff --git a/Signal/Images/checkbox_empty.png b/Signal/Images/checkbox_empty.png deleted file mode 100644 index 25f7a1b25d..0000000000 Binary files a/Signal/Images/checkbox_empty.png and /dev/null differ diff --git a/Signal/Images/checkbox_empty@2x.png b/Signal/Images/checkbox_empty@2x.png deleted file mode 100644 index 36be44e792..0000000000 Binary files a/Signal/Images/checkbox_empty@2x.png and /dev/null differ diff --git a/Signal/Images/contacts.png b/Signal/Images/contacts.png deleted file mode 100644 index a4c3deeb11..0000000000 Binary files a/Signal/Images/contacts.png and /dev/null differ diff --git a/Signal/Images/contacts_arrow.png b/Signal/Images/contacts_arrow.png deleted file mode 100644 index b6d04bd189..0000000000 Binary files a/Signal/Images/contacts_arrow.png and /dev/null differ diff --git a/Signal/Images/contacts_arrow@2x.png b/Signal/Images/contacts_arrow@2x.png deleted file mode 100644 index 426a796cda..0000000000 Binary files a/Signal/Images/contacts_arrow@2x.png and /dev/null differ diff --git a/Signal/Images/defaultConctact_light@2x.png b/Signal/Images/defaultConctact_light@2x.png new file mode 100644 index 0000000000..a8aec6d4ee Binary files /dev/null and b/Signal/Images/defaultConctact_light@2x.png differ diff --git a/Signal/Images/dismiss_notification_icon.png b/Signal/Images/dismiss_notification_icon.png deleted file mode 100644 index 927932310e..0000000000 Binary files a/Signal/Images/dismiss_notification_icon.png and /dev/null differ diff --git a/Signal/Images/dismiss_notification_icon@2x.png b/Signal/Images/dismiss_notification_icon@2x.png deleted file mode 100644 index 44a041d1ea..0000000000 Binary files a/Signal/Images/dismiss_notification_icon@2x.png and /dev/null differ diff --git a/Signal/Images/drop_down_arrow_icon.png b/Signal/Images/drop_down_arrow_icon.png deleted file mode 100644 index 4552d778e1..0000000000 Binary files a/Signal/Images/drop_down_arrow_icon.png and /dev/null differ diff --git a/Signal/Images/drop_down_arrow_icon@2x.png b/Signal/Images/drop_down_arrow_icon@2x.png deleted file mode 100644 index 4552d778e1..0000000000 Binary files a/Signal/Images/drop_down_arrow_icon@2x.png and /dev/null differ diff --git a/Signal/Images/expanded_cell_icon.png b/Signal/Images/expanded_cell_icon.png deleted file mode 100644 index 42554a044e..0000000000 Binary files a/Signal/Images/expanded_cell_icon.png and /dev/null differ diff --git a/Signal/Images/expanded_cell_icon@2x.png b/Signal/Images/expanded_cell_icon@2x.png deleted file mode 100644 index 1b761f6b37..0000000000 Binary files a/Signal/Images/expanded_cell_icon@2x.png and /dev/null differ diff --git a/Signal/Images/favourite.png b/Signal/Images/favourite.png deleted file mode 100644 index 4e2e31def0..0000000000 Binary files a/Signal/Images/favourite.png and /dev/null differ diff --git a/Signal/Images/favourite_false_icon.png b/Signal/Images/favourite_false_icon.png deleted file mode 100644 index 4e68783037..0000000000 Binary files a/Signal/Images/favourite_false_icon.png and /dev/null differ diff --git a/Signal/Images/favourite_false_icon@2x.png b/Signal/Images/favourite_false_icon@2x.png deleted file mode 100644 index 670f8a0acc..0000000000 Binary files a/Signal/Images/favourite_false_icon@2x.png and /dev/null differ diff --git a/Signal/Images/favourite_true_icon.png b/Signal/Images/favourite_true_icon.png deleted file mode 100644 index 4e410f5bb7..0000000000 Binary files a/Signal/Images/favourite_true_icon.png and /dev/null differ diff --git a/Signal/Images/favourite_true_icon@2x.png b/Signal/Images/favourite_true_icon@2x.png deleted file mode 100644 index e6c287d3e8..0000000000 Binary files a/Signal/Images/favourite_true_icon@2x.png and /dev/null differ diff --git a/Signal/Images/forward_button.png b/Signal/Images/forward_button.png deleted file mode 100644 index 21cb2b542f..0000000000 Binary files a/Signal/Images/forward_button.png and /dev/null differ diff --git a/Signal/Images/forward_button@2x.png b/Signal/Images/forward_button@2x.png deleted file mode 100644 index 9f834be7bd..0000000000 Binary files a/Signal/Images/forward_button@2x.png and /dev/null differ diff --git a/Signal/Images/group_photo@2x.png b/Signal/Images/group_photo@2x.png new file mode 100644 index 0000000000..8bd7c0562d Binary files /dev/null and b/Signal/Images/group_photo@2x.png differ diff --git a/Signal/Images/home_icon.png b/Signal/Images/home_icon.png deleted file mode 100644 index a349f3afcd..0000000000 Binary files a/Signal/Images/home_icon.png and /dev/null differ diff --git a/Signal/Images/icon_contacts.png b/Signal/Images/icon_contacts.png deleted file mode 100644 index 36f6617a20..0000000000 Binary files a/Signal/Images/icon_contacts.png and /dev/null differ diff --git a/Signal/Images/icon_favourites.png b/Signal/Images/icon_favourites.png deleted file mode 100644 index 207083805d..0000000000 Binary files a/Signal/Images/icon_favourites.png and /dev/null differ diff --git a/Signal/Images/icon_keypad.png b/Signal/Images/icon_keypad.png deleted file mode 100644 index e14e8dc35d..0000000000 Binary files a/Signal/Images/icon_keypad.png and /dev/null differ diff --git a/Signal/Images/icon_recents.png b/Signal/Images/icon_recents.png deleted file mode 100644 index 710466a033..0000000000 Binary files a/Signal/Images/icon_recents.png and /dev/null differ diff --git a/Signal/Images/in_call_phone_icon.png b/Signal/Images/in_call_phone_icon.png deleted file mode 100644 index 88eb086370..0000000000 Binary files a/Signal/Images/in_call_phone_icon.png and /dev/null differ diff --git a/Signal/Images/in_call_phone_icon@2x.png b/Signal/Images/in_call_phone_icon@2x.png deleted file mode 100644 index 157c4ed8a7..0000000000 Binary files a/Signal/Images/in_call_phone_icon@2x.png and /dev/null differ diff --git a/Signal/Images/in_call_phrase_icon.png b/Signal/Images/in_call_phrase_icon.png deleted file mode 100644 index ed4020da42..0000000000 Binary files a/Signal/Images/in_call_phrase_icon.png and /dev/null differ diff --git a/Signal/Images/in_call_phrase_icon@2x.png b/Signal/Images/in_call_phrase_icon@2x.png deleted file mode 100644 index f8fc02eb83..0000000000 Binary files a/Signal/Images/in_call_phrase_icon@2x.png and /dev/null differ diff --git a/Signal/Images/incoming_call_icon.png b/Signal/Images/incoming_call_icon.png deleted file mode 100644 index 9aa6b40124..0000000000 Binary files a/Signal/Images/incoming_call_icon.png and /dev/null differ diff --git a/Signal/Images/incoming_call_icon@2x.png b/Signal/Images/incoming_call_icon@2x.png deleted file mode 100644 index 339af1f34c..0000000000 Binary files a/Signal/Images/incoming_call_icon@2x.png and /dev/null differ diff --git a/Signal/Images/info@2x.png b/Signal/Images/info@2x.png deleted file mode 100644 index 5fc14034ca..0000000000 Binary files a/Signal/Images/info@2x.png and /dev/null differ diff --git a/Signal/Images/menu_icon.png b/Signal/Images/menu_icon.png deleted file mode 100644 index cce32b4a05..0000000000 Binary files a/Signal/Images/menu_icon.png and /dev/null differ diff --git a/Signal/Images/menu_icon@2x.png b/Signal/Images/menu_icon@2x.png deleted file mode 100644 index 6d3448a674..0000000000 Binary files a/Signal/Images/menu_icon@2x.png and /dev/null differ diff --git a/Signal/Images/message_icon.png b/Signal/Images/message_icon.png deleted file mode 100644 index fa796921c0..0000000000 Binary files a/Signal/Images/message_icon.png and /dev/null differ diff --git a/Signal/Images/mute_icon.png b/Signal/Images/mute_icon.png deleted file mode 100644 index 93dc1870e1..0000000000 Binary files a/Signal/Images/mute_icon.png and /dev/null differ diff --git a/Signal/Images/mute_icon@2x.png b/Signal/Images/mute_icon@2x.png deleted file mode 100644 index d62812ab1d..0000000000 Binary files a/Signal/Images/mute_icon@2x.png and /dev/null differ diff --git a/Signal/Images/mute_icon_selected.png b/Signal/Images/mute_icon_selected.png deleted file mode 100644 index 684da52790..0000000000 Binary files a/Signal/Images/mute_icon_selected.png and /dev/null differ diff --git a/Signal/Images/mute_icon_selected@2x.png b/Signal/Images/mute_icon_selected@2x.png deleted file mode 100644 index 1f02616aca..0000000000 Binary files a/Signal/Images/mute_icon_selected@2x.png and /dev/null differ diff --git a/Signal/Images/notification_detail_icon.png b/Signal/Images/notification_detail_icon.png deleted file mode 100644 index bfcdd1300d..0000000000 Binary files a/Signal/Images/notification_detail_icon.png and /dev/null differ diff --git a/Signal/Images/notification_detail_icon@2x.png b/Signal/Images/notification_detail_icon@2x.png deleted file mode 100644 index a797248fb0..0000000000 Binary files a/Signal/Images/notification_detail_icon@2x.png and /dev/null differ diff --git a/Signal/Images/notification_mini_icon.png b/Signal/Images/notification_mini_icon.png deleted file mode 100644 index 4262352e54..0000000000 Binary files a/Signal/Images/notification_mini_icon.png and /dev/null differ diff --git a/Signal/Images/notification_mini_icon@2x.png b/Signal/Images/notification_mini_icon@2x.png deleted file mode 100644 index 840554e237..0000000000 Binary files a/Signal/Images/notification_mini_icon@2x.png and /dev/null differ diff --git a/Signal/Images/outgoing_call_icon.png b/Signal/Images/outgoing_call_icon.png deleted file mode 100644 index 0333ac38c5..0000000000 Binary files a/Signal/Images/outgoing_call_icon.png and /dev/null differ diff --git a/Signal/Images/outgoing_call_icon@2x.png b/Signal/Images/outgoing_call_icon@2x.png deleted file mode 100755 index b2610a8d61..0000000000 Binary files a/Signal/Images/outgoing_call_icon@2x.png and /dev/null differ diff --git a/Signal/Images/phone_icon.png b/Signal/Images/phone_icon.png deleted file mode 100644 index d0230b886f..0000000000 Binary files a/Signal/Images/phone_icon.png and /dev/null differ diff --git a/Signal/Images/phone_icon@2x.png b/Signal/Images/phone_icon@2x.png deleted file mode 100644 index 90f5f54056..0000000000 Binary files a/Signal/Images/phone_icon@2x.png and /dev/null differ diff --git a/Signal/Images/search_cancel.png b/Signal/Images/search_cancel.png deleted file mode 100644 index 229587b986..0000000000 Binary files a/Signal/Images/search_cancel.png and /dev/null differ diff --git a/Signal/Images/search_cancel@2x.png b/Signal/Images/search_cancel@2x.png deleted file mode 100644 index a0354eb4cd..0000000000 Binary files a/Signal/Images/search_cancel@2x.png and /dev/null differ diff --git a/Signal/Images/search_icon.png b/Signal/Images/search_icon.png deleted file mode 100644 index d05d3ecf8b..0000000000 Binary files a/Signal/Images/search_icon.png and /dev/null differ diff --git a/Signal/Images/search_icon@2x.png b/Signal/Images/search_icon@2x.png deleted file mode 100644 index b6c9d99946..0000000000 Binary files a/Signal/Images/search_icon@2x.png and /dev/null differ diff --git a/Signal/Images/send_code_icon.png b/Signal/Images/send_code_icon.png deleted file mode 100644 index 372c0ca141..0000000000 Binary files a/Signal/Images/send_code_icon.png and /dev/null differ diff --git a/Signal/Images/send_code_icon@2x.png b/Signal/Images/send_code_icon@2x.png deleted file mode 100644 index 5d3ed011b5..0000000000 Binary files a/Signal/Images/send_code_icon@2x.png and /dev/null differ diff --git a/Signal/Images/settings.png b/Signal/Images/settings.png deleted file mode 100644 index cac25f6955..0000000000 Binary files a/Signal/Images/settings.png and /dev/null differ diff --git a/Signal/Images/settings_tab@2x.png b/Signal/Images/settings_tab@2x.png new file mode 100644 index 0000000000..1b60e49906 Binary files /dev/null and b/Signal/Images/settings_tab@2x.png differ diff --git a/Signal/Images/signals.png b/Signal/Images/signals.png deleted file mode 100644 index a3eb26482a..0000000000 Binary files a/Signal/Images/signals.png and /dev/null differ diff --git a/Signal/Images/signals_tab@2x.png b/Signal/Images/signals_tab@2x.png new file mode 100644 index 0000000000..9a30839282 Binary files /dev/null and b/Signal/Images/signals_tab@2x.png differ diff --git a/Signal/Images/speaker_icon.png b/Signal/Images/speaker_icon.png deleted file mode 100644 index f9d537d407..0000000000 Binary files a/Signal/Images/speaker_icon.png and /dev/null differ diff --git a/Signal/Images/speaker_icon@2x.png b/Signal/Images/speaker_icon@2x.png deleted file mode 100644 index 3c35791da3..0000000000 Binary files a/Signal/Images/speaker_icon@2x.png and /dev/null differ diff --git a/Signal/Images/speaker_icon_selected.png b/Signal/Images/speaker_icon_selected.png deleted file mode 100644 index 4b43cb39d5..0000000000 Binary files a/Signal/Images/speaker_icon_selected.png and /dev/null differ diff --git a/Signal/Images/speaker_icon_selected@2x.png b/Signal/Images/speaker_icon_selected@2x.png deleted file mode 100644 index 6835274f55..0000000000 Binary files a/Signal/Images/speaker_icon_selected@2x.png and /dev/null differ diff --git a/Signal/Images/spinner_connecting.png b/Signal/Images/spinner_connecting.png deleted file mode 100644 index e2f5cd3254..0000000000 Binary files a/Signal/Images/spinner_connecting.png and /dev/null differ diff --git a/Signal/Images/spinner_connecting@2x.png b/Signal/Images/spinner_connecting@2x.png deleted file mode 100644 index cedf1f5e3f..0000000000 Binary files a/Signal/Images/spinner_connecting@2x.png and /dev/null differ diff --git a/Signal/Images/spinner_connecting_flash.png b/Signal/Images/spinner_connecting_flash.png deleted file mode 100644 index d6c49eae75..0000000000 Binary files a/Signal/Images/spinner_connecting_flash.png and /dev/null differ diff --git a/Signal/Images/spinner_connecting_flash@2x.png b/Signal/Images/spinner_connecting_flash@2x.png deleted file mode 100644 index b0e1f97e20..0000000000 Binary files a/Signal/Images/spinner_connecting_flash@2x.png and /dev/null differ diff --git a/Signal/Images/spinner_error.png b/Signal/Images/spinner_error.png deleted file mode 100644 index 82eb4f0007..0000000000 Binary files a/Signal/Images/spinner_error.png and /dev/null differ diff --git a/Signal/Images/spinner_error@2x.png b/Signal/Images/spinner_error@2x.png deleted file mode 100644 index afe43819d2..0000000000 Binary files a/Signal/Images/spinner_error@2x.png and /dev/null differ diff --git a/Signal/Images/spinner_ringing.png b/Signal/Images/spinner_ringing.png deleted file mode 100644 index fd57177634..0000000000 Binary files a/Signal/Images/spinner_ringing.png and /dev/null differ diff --git a/Signal/Images/spinner_ringing@2x.png b/Signal/Images/spinner_ringing@2x.png deleted file mode 100644 index 270f1374cc..0000000000 Binary files a/Signal/Images/spinner_ringing@2x.png and /dev/null differ diff --git a/Signal/Images/tab_icon_contacts.png b/Signal/Images/tab_icon_contacts.png deleted file mode 100644 index c220edb565..0000000000 Binary files a/Signal/Images/tab_icon_contacts.png and /dev/null differ diff --git a/Signal/Images/tab_icon_contacts@2x.png b/Signal/Images/tab_icon_contacts@2x.png deleted file mode 100644 index 9869dc31b2..0000000000 Binary files a/Signal/Images/tab_icon_contacts@2x.png and /dev/null differ diff --git a/Signal/Images/tab_icon_favourites.png b/Signal/Images/tab_icon_favourites.png deleted file mode 100644 index 999b6d0f1b..0000000000 Binary files a/Signal/Images/tab_icon_favourites.png and /dev/null differ diff --git a/Signal/Images/tab_icon_favourites@2x.png b/Signal/Images/tab_icon_favourites@2x.png deleted file mode 100644 index ba6a09e3a4..0000000000 Binary files a/Signal/Images/tab_icon_favourites@2x.png and /dev/null differ diff --git a/Signal/Images/tab_icon_inbox.png b/Signal/Images/tab_icon_inbox.png deleted file mode 100644 index 8cc752ce88..0000000000 Binary files a/Signal/Images/tab_icon_inbox.png and /dev/null differ diff --git a/Signal/Images/tab_icon_inbox@2x.png b/Signal/Images/tab_icon_inbox@2x.png deleted file mode 100644 index b6956f1428..0000000000 Binary files a/Signal/Images/tab_icon_inbox@2x.png and /dev/null differ diff --git a/Signal/Images/tab_icon_keypad.png b/Signal/Images/tab_icon_keypad.png deleted file mode 100644 index 80ffd8756c..0000000000 Binary files a/Signal/Images/tab_icon_keypad.png and /dev/null differ diff --git a/Signal/Images/tab_icon_keypad@2x.png b/Signal/Images/tab_icon_keypad@2x.png deleted file mode 100644 index ebe727ab47..0000000000 Binary files a/Signal/Images/tab_icon_keypad@2x.png and /dev/null differ diff --git a/Signal/Images/tab_icon_menu.png b/Signal/Images/tab_icon_menu.png deleted file mode 100644 index 29369f75c6..0000000000 Binary files a/Signal/Images/tab_icon_menu.png and /dev/null differ diff --git a/Signal/Images/tab_icon_menu@2x.png b/Signal/Images/tab_icon_menu@2x.png deleted file mode 100644 index 58d95ac267..0000000000 Binary files a/Signal/Images/tab_icon_menu@2x.png and /dev/null differ diff --git a/Signal/Images/trash_icon.png b/Signal/Images/trash_icon.png deleted file mode 100644 index 8e53c7e2b5..0000000000 Binary files a/Signal/Images/trash_icon.png and /dev/null differ diff --git a/Signal/Images/trash_icon@2x.png b/Signal/Images/trash_icon@2x.png deleted file mode 100644 index 4cddd6af40..0000000000 Binary files a/Signal/Images/trash_icon@2x.png and /dev/null differ diff --git a/Signal/Images/volume_high.png b/Signal/Images/volume_high.png deleted file mode 100644 index 51512f88d3..0000000000 Binary files a/Signal/Images/volume_high.png and /dev/null differ diff --git a/Signal/Images/volume_high@2x.png b/Signal/Images/volume_high@2x.png deleted file mode 100644 index dd495ee61e..0000000000 Binary files a/Signal/Images/volume_high@2x.png and /dev/null differ diff --git a/Signal/Images/volume_low.png b/Signal/Images/volume_low.png deleted file mode 100644 index 9926936396..0000000000 Binary files a/Signal/Images/volume_low.png and /dev/null differ diff --git a/Signal/Images/volume_low@2x.png b/Signal/Images/volume_low@2x.png deleted file mode 100644 index cd8360d8f8..0000000000 Binary files a/Signal/Images/volume_low@2x.png and /dev/null differ diff --git a/Signal/Images/whisper_notification_icon.png b/Signal/Images/whisper_notification_icon.png deleted file mode 100644 index 2ddbb53368..0000000000 Binary files a/Signal/Images/whisper_notification_icon.png and /dev/null differ diff --git a/Signal/Images/whisper_notification_icon@2x.png b/Signal/Images/whisper_notification_icon@2x.png deleted file mode 100644 index 459b6beda5..0000000000 Binary files a/Signal/Images/whisper_notification_icon@2x.png and /dev/null differ diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 85c59b48c1..5e0126f800 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -13,7 +13,7 @@ CFBundleIcons~ipad CFBundleIdentifier - org.whispersystems.signal.branch + org.whispersystems.signal.textSecure CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index d37230c5f1..3acaa93ee5 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -12,6 +12,7 @@ #import "PriorityQueue.h" #import "RecentCallManager.h" #import "Release.h" +#import "TSStorageManager.h" #import "TSAccountManager.h" #import "Util.h" #import "VersionMigrations.h" @@ -58,47 +59,6 @@ } } -/** - * Protects the preference and logs file with disk encryption and prevents them to leak to iCloud. - */ - -- (void)protectPreferenceFiles{ - - NSMutableArray *pathsToExclude = [NSMutableArray array]; - NSString *preferencesPath =[NSHomeDirectory() stringByAppendingString:@"/Library/Preferences/"]; - - NSError *error; - - NSDictionary *attrs = @{NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication}; - [NSFileManager.defaultManager setAttributes:attrs ofItemAtPath:preferencesPath error:&error]; - - [pathsToExclude addObject:[[preferencesPath stringByAppendingString:NSBundle.mainBundle.bundleIdentifier] stringByAppendingString:@".plist"]]; - - NSString *logPath = [NSHomeDirectory() stringByAppendingString:@"/Library/Caches/Logs/"]; - NSArray *logsFiles = [NSFileManager.defaultManager contentsOfDirectoryAtPath:logPath error:&error]; - - attrs = @{NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication}; - [NSFileManager.defaultManager setAttributes:attrs ofItemAtPath:logPath error:&error]; - - for (NSString *logsFile in logsFiles) { - [pathsToExclude addObject:[logPath stringByAppendingString:logsFile]]; - } - - for (NSString *pathToExclude in pathsToExclude) { - [[NSURL fileURLWithPath:pathToExclude] setResourceValue:@YES - forKey:NSURLIsExcludedFromBackupKey - error:&error]; - } - - if (error) { - DDLogError(@"Error while removing log files from backup: %@", error.description); - UIAlertView *alert = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"WARNING", @"") message:NSLocalizedString(@"DISABLING_BACKUP_FAILED", @"") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil, nil]; - [alert show]; - return; - } - -} - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { BOOL loggingIsEnabled; @@ -121,8 +81,9 @@ [DebugLogger.sharedInstance enableFileLogging]; } + [[TSStorageManager sharedManager] setupDatabase]; + [self performUpdateCheck]; - [self protectPreferenceFiles]; //self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; @@ -144,6 +105,21 @@ [self application:application didReceiveRemoteNotification:remoteNotif]; } + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:[NSBundle mainBundle]]; + + UIViewController *viewController; + + if (![TSAccountManager isRegistered]) { + viewController = [storyboard instantiateViewControllerWithIdentifier:@"RegisterInitialViewController"]; + } else{ + viewController = [storyboard instantiateViewControllerWithIdentifier:@"UserInitialViewController"]; + } + + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = viewController; + + [self.window makeKeyAndVisible]; + [Environment.phoneManager.currentCallObservable watchLatestValue:^(CallState* latestCall) { if (latestCall == nil){ return; @@ -166,15 +142,6 @@ [self.window.rootViewController presentViewController:callViewController animated:NO completion:nil]; } onThread:NSThread.mainThread untilCancelled:nil]; - UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:[NSBundle mainBundle]]; - - UIViewController *viewController; - - BOOL isNewUser = NO; - - self.window.rootViewController = isNewUser ? viewControllerForNewUser : viewController; - [self.window makeKeyAndVisible]; - return YES; } diff --git a/Signal/src/Storyboard/Storyboard.storyboard b/Signal/src/Storyboard/Storyboard.storyboard old mode 100644 new mode 100755 index d11a86f853..ac6fc23975 --- a/Signal/src/Storyboard/Storyboard.storyboard +++ b/Signal/src/Storyboard/Storyboard.storyboard @@ -1,5 +1,5 @@ - + @@ -24,7 +24,7 @@ - + @@ -120,7 +120,7 @@ - + @@ -480,12 +480,14 @@ Lorem ipsum : Quick explanation of Fingerprints - + + + - + @@ -509,12 +511,12 @@ Lorem ipsum : Quick explanation of Fingerprints - + - + @@ -696,10 +698,16 @@ Lorem ipsum : Quick explanation of Fingerprints - + + + - - + + + + + + @@ -1523,7 +1531,9 @@ Lorem ipsum : Quick explanation of Fingerprints - + + + @@ -1599,6 +1609,9 @@ Lorem ipsum : Quick explanation of Fingerprints + + + - + @@ -1883,7 +1899,7 @@ Lorem ipsum : Quick explanation of Fingerprints - + @@ -1921,8 +1937,11 @@ Lorem ipsum : Quick explanation of Fingerprints + + + - + @@ -1960,6 +1979,9 @@ Lorem ipsum : Quick explanation of Fingerprints + + + @@ -2221,7 +2243,7 @@ Lorem ipsum : Quick explanation of Fingerprints - + @@ -2266,7 +2288,7 @@ Lorem ipsum : Quick explanation of Fingerprints - + @@ -2297,11 +2319,24 @@ Lorem ipsum : Quick explanation of Fingerprints @@ -2329,7 +2364,7 @@ Licensed under the GPLv3 - + @@ -2337,17 +2372,11 @@ Licensed under the GPLv3 - + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + @@ -2418,22 +2419,14 @@ Licensed under the GPLv3 - - + - - - - - - - - + @@ -2442,21 +2435,12 @@ Licensed under the GPLv3 - - - - - - - - - - + @@ -2465,21 +2449,11 @@ Licensed under the GPLv3 - - - - - - - - - - @@ -2835,7 +2809,7 @@ Licensed under the GPLv3 - + @@ -2982,7 +2956,7 @@ Licensed under the GPLv3 - + @@ -3078,14 +3052,6 @@ Licensed under the GPLv3 - - - - - - - - @@ -3124,31 +3090,6 @@ Licensed under the GPLv3 - @@ -3167,6 +3108,35 @@ Licensed under the GPLv3 + @@ -3174,13 +3144,17 @@ Licensed under the GPLv3 - - + + + + + + - + @@ -3193,8 +3167,8 @@ Licensed under the GPLv3 - + @@ -3227,7 +3201,7 @@ Licensed under the GPLv3 - + @@ -3315,17 +3289,17 @@ Licensed under the GPLv3 + - - + - + diff --git a/Signal/src/call/RecentCallManager.m b/Signal/src/call/RecentCallManager.m index 4c101a71be..6efde4b245 100644 --- a/Signal/src/call/RecentCallManager.m +++ b/Signal/src/call/RecentCallManager.m @@ -34,7 +34,7 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*); } -(void) watchForContactUpdatesFrom:(ContactsManager*) contactManager untillCancelled:(TOCCancelToken*) cancelToken{ - [contactManager.getObservableWhisperUsers watchLatestValue:^(NSArray* latestUsers) { + [contactManager.getObservableRedPhoneUsers watchLatestValue:^(NSArray* latestUsers) { for (RecentCall* recentCall in _allRecents) { if (![contactManager latestContactWithRecordId:recentCall.contactRecordID]) { Contact* contact = [contactManager latestContactForPhoneNumber:recentCall.phoneNumber]; diff --git a/Signal/src/contact/Contact.h b/Signal/src/contact/Contact.h index 764913c539..f0f90dd289 100644 --- a/Signal/src/contact/Contact.h +++ b/Signal/src/contact/Contact.h @@ -10,18 +10,15 @@ @interface Contact : NSObject -@property (readonly,nonatomic) NSString* firstName; -@property (readonly,nonatomic) NSString* lastName; -@property (readonly,nonatomic) NSArray* parsedPhoneNumbers; -@property (readonly,nonatomic) NSArray* userTextPhoneNumbers; -@property (readonly,nonatomic) NSArray* emails; -@property (readonly,nonatomic) UIImage* image; -@property (readonly,nonatomic) NSString *notes; +@property (readonly,nonatomic) NSString *firstName; +@property (readonly,nonatomic) NSString *lastName; +@property (readonly,nonatomic) NSArray *parsedPhoneNumbers; +@property (readonly,nonatomic) NSArray *userTextPhoneNumbers; +@property (readonly,nonatomic) NSArray *emails; +@property (readonly,nonatomic) UIImage *image; +@property (readonly,nonatomic) NSString *notes; @property (readonly,nonatomic) ABRecordID recordID; -@property (nonatomic, assign) BOOL isTextSecureContact; -@property (nonatomic, assign) BOOL isRedPhoneContact; - + (Contact*)contactWithFirstName:(NSString*)firstName andLastName:(NSString *)lastName andUserTextPhoneNumbers:(NSArray*)phoneNumbers @@ -36,6 +33,9 @@ andContactID:(ABRecordID)record andNotes:(NSString *)notes; -- (NSString *)fullName; +- (NSString*)fullName; + +- (BOOL)isTextSecureContact; +- (BOOL)isRedPhoneContact; @end diff --git a/Signal/src/contact/Contact.m b/Signal/src/contact/Contact.m index 0a5591e8da..126cdee6bc 100644 --- a/Signal/src/contact/Contact.m +++ b/Signal/src/contact/Contact.m @@ -1,7 +1,10 @@ #import "Contact.h" +#import "ContactsManager.h" +#import "TSStorageManager.h" #import "Util.h" #import "Environment.h" #import "PreferencesUtil.h" +#import "TSRecipient.h" static NSString *const DEFAULTS_KEY_CONTACT = @"DefaultsKeyContact"; static NSString *const DEFAULTS_KEY_PHONE_NUMBER = @"DefaultsKeyPhoneNumber"; @@ -79,4 +82,22 @@ static NSString *const DEFAULTS_KEY_DATE = @"DefaultsKeyDate"; } } +- (BOOL)isTextSecureContact{ + __block BOOL isRecipient = NO; + [[TSStorageManager sharedManager].dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + for (PhoneNumber *number in self.parsedPhoneNumbers) { + if ([TSRecipient recipientWithTextSecureIdentifier:number.toE164 withTransaction:transaction]) { + isRecipient = YES; + break; + } + } + }]; + return isRecipient; +} + +- (BOOL)isRedPhoneContact{ + ContactsManager *contactManager = [Environment getCurrent].contactsManager; + return [contactManager isContactRegisteredWithRedPhone:self]; +} + @end diff --git a/Signal/src/contact/ContactsManager.h b/Signal/src/contact/ContactsManager.h index 7dd70b6ee7..3862a84d77 100644 --- a/Signal/src/contact/ContactsManager.h +++ b/Signal/src/contact/ContactsManager.h @@ -19,32 +19,32 @@ typedef void(^ABReloadRequestCompletionBlock)(NSArray *contacts); @interface ContactsManager : NSObject { @private TOCFuture* futureAddressBook; @private ObservableValueController* observableContactsController; -@private ObservableValueController* observableWhisperUsersController; +@private ObservableValueController* observableRedPhoneUsersController; +@private ObservableValueController* observableTextSecureUsersController; @private TOCCancelTokenSource* life; @private NSDictionary *latestContactsById; @private NSDictionary *latestWhisperUsersById; } -(ObservableValue *) getObservableContacts; --(ObservableValue *) getObservableWhisperUsers; +-(ObservableValue *) getObservableRedPhoneUsers; -(NSArray*) getContactsFromAddressBook:(ABAddressBookRef)addressBook; -(Contact*) latestContactWithRecordId:(ABRecordID)recordId; -(Contact*) latestContactForPhoneNumber:(PhoneNumber *)phoneNumber; -(NSArray*) latestContactsWithSearchString:(NSString *)searchString; --(void) addContactsToKnownWhisperUsers:(NSArray*) contacts; - +(NSDictionary *)groupContactsByFirstLetter:(NSArray *)contacts matchingSearchString:(NSString *)optionalSearchString; +(BOOL)name:(NSString *)nameString matchesQuery:(NSString *)queryString; +(BOOL)phoneNumber:(PhoneNumber *)phoneNumber matchesQuery:(NSString *)queryString; --(BOOL)isContactRegisteredWithWhisper:(Contact*) contact; +-(BOOL)isContactRegisteredWithRedPhone:(Contact*) contact; -(void) doAfterEnvironmentInitSetup; --(void) enableNewUserNotifications; --(NSUInteger) getNumberOfUnacknowledgedCurrentUsers; +- (NSArray*)allContacts; +- (NSArray*)textSecureContacts; +- (NSString*)nameStringForPhoneIdentifier:(NSString*)identifier; @end diff --git a/Signal/src/contact/ContactsManager.m b/Signal/src/contact/ContactsManager.m index ec3775926b..7d15fecb4b 100644 --- a/Signal/src/contact/ContactsManager.m +++ b/Signal/src/contact/ContactsManager.m @@ -10,16 +10,9 @@ #define ADDRESSBOOK_QUEUE dispatch_get_main_queue() -static NSString *const FAVOURITES_DEFAULT_KEY = @"FAVOURITES_DEFAULT_KEY"; -static NSString *const KNOWN_USERS_DEFAULT_KEY = @"KNOWN_USERS_DEFAULT_KEY"; - typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL*); @interface ContactsManager () { - NSMutableArray *_favouriteContactIds; - NSMutableArray *_knownWhisperUserIds; - BOOL newUserNotificationsEnabled; - id addressBookReference; } @@ -30,11 +23,9 @@ typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL*); - (id)init { self = [super init]; if (self) { - newUserNotificationsEnabled = [self knownUserStoreInitialized]; - _knownWhisperUserIds = [self loadKnownWhisperUsers]; - life = [TOCCancelTokenSource new]; - observableContactsController = [ObservableValueController observableValueControllerWithInitialValue:nil]; - observableWhisperUsersController = [ObservableValueController observableValueControllerWithInitialValue:nil]; + life = [TOCCancelTokenSource new]; + observableContactsController = [ObservableValueController observableValueControllerWithInitialValue:nil]; + observableRedPhoneUsersController = [ObservableValueController observableValueControllerWithInitialValue:nil]; [self registerNotificationHandlers]; } return self; @@ -47,9 +38,9 @@ typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL*); } } untilCancelled:life.token]; - [observableWhisperUsersController watchLatestValueOnArbitraryThread:^(NSArray *latestUsers) { + [observableRedPhoneUsersController watchLatestValueOnArbitraryThread:^(NSArray *latestUsers) { @synchronized(self) { - [self setupLatestWhisperUsers:latestUsers]; + [self setupLatestRedPhoneUsers:latestUsers]; } } untilCancelled:life.token]; } @@ -64,13 +55,11 @@ typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL*); } -(void) updatedDirectoryHandler:(NSNotification*) notification { - [self checkForNewWhisperUsers]; + NSArray *currentUsers = [self getRedPhoneUsersFromContactsArray:latestContactsById.allValues]; + + [observableRedPhoneUsersController updateValue:currentUsers]; } --(void) enableNewUserNotifications{ - newUserNotificationsEnabled = YES; -} - #pragma mark - Address Book callbacks void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef info, void *context); @@ -110,12 +99,12 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in latestContactsById = [ContactsManager keyContactsById:contacts]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - [self checkForNewWhisperUsers]; + [self updatedDirectoryHandler:nil]; }); } } -- (void)setupLatestWhisperUsers:(NSArray *)users { +- (void)setupLatestRedPhoneUsers:(NSArray *)users { if (users) { latestWhisperUsersById = [ContactsManager keyContactsById:users]; } @@ -127,8 +116,8 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in return observableContactsController; } --(ObservableValue *) getObservableWhisperUsers { - return observableWhisperUsersController; +-(ObservableValue *) getObservableRedPhoneUsers { + return observableRedPhoneUsersController; } #pragma mark - Address Book utils @@ -344,7 +333,11 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in } } --(NSArray*) recordsForContacts:(NSArray*) contacts{ +- (NSArray*)allContacts { + return [latestContactsById allValues]; +} + +- (NSArray*)recordsForContacts:(NSArray*) contacts{ return [contacts map:^id(Contact *contact) { return @([contact recordID]); }]; @@ -387,40 +380,26 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in #pragma mark - Whisper User Management --(NSUInteger) checkForNewWhisperUsers { - NSArray *currentUsers = [self getWhisperUsersFromContactsArray:latestContactsById.allValues]; - NSArray *newUsers = [self getNewItemsFrom:currentUsers comparedTo:latestWhisperUsersById.allValues]; - - if(newUsers.count > 0){ - [observableWhisperUsersController updateValue:currentUsers]; - } - - NSArray *unacknowledgedUserIds = [self getUnacknowledgedUsersFrom:currentUsers]; - if(unacknowledgedUserIds.count > 0){ - NSArray *unacknowledgedUsers = [self contactsForContactIds: unacknowledgedUserIds]; - if(!newUserNotificationsEnabled){ - [self addContactsToKnownWhisperUsers:unacknowledgedUsers]; - }else{ - NSDictionary *payload = @{NOTIFICATION_DATAKEY_NEW_USERS: unacknowledgedUsers}; - [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_NEW_USERS_AVAILABLE object:self userInfo:payload]; - } - } - return newUsers.count; -} - --(NSArray*) getUnacknowledgedUsersFrom:(NSArray*) users { - NSArray *userIds = [self recordsForContacts:users]; - return [self getNewItemsFrom:userIds comparedTo:_knownWhisperUserIds ]; -} - --(NSUInteger) getNumberOfUnacknowledgedCurrentUsers{ - NSArray *currentUsers = [self getWhisperUsersFromContactsArray:latestContactsById.allValues]; - return [[self getUnacknowledgedUsersFrom:currentUsers] count]; -} - --(NSArray*) getWhisperUsersFromContactsArray:(NSArray*) contacts { +-(NSArray*) getRedPhoneUsersFromContactsArray:(NSArray*) contacts { return [contacts filter:^int(Contact* contact) { - return [self isContactRegisteredWithWhisper:contact]; + return [self isContactRegisteredWithRedPhone:contact]; + }]; +} + +-(NSArray*) textSecureContacts { + return [[self.allContacts filter:^int(Contact* contact) { + return [contact isTextSecureContact]; + }] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { + Contact *contact1 = (Contact*)obj1; + Contact *contact2 = (Contact*)obj2; + + BOOL firstNameOrdering = ABPersonGetSortOrdering() == kABPersonCompositeNameFormatFirstNameFirst?YES:NO; + + if (firstNameOrdering) { + return [contact1.firstName compare:contact2.firstName]; + } else { + return [contact2.lastName compare:contact2.lastName]; + } }]; } @@ -432,50 +411,29 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in return newSet.allObjects; } -- (BOOL)isContactRegisteredWithWhisper:(Contact*) contact { +- (BOOL)isContactRegisteredWithRedPhone:(Contact*) contact { for(PhoneNumber *phoneNumber in contact.parsedPhoneNumbers){ - if ( [self isPhoneNumberRegisteredWithWhisper:phoneNumber]) { + if ( [self isPhoneNumberRegisteredWithRedPhone:phoneNumber]) { return YES; } } return NO; } -- (BOOL)isPhoneNumberRegisteredWithWhisper:(PhoneNumber *)phoneNumber { +- (BOOL)isPhoneNumberRegisteredWithRedPhone:(PhoneNumber *)phoneNumber { PhoneNumberDirectoryFilter* directory = Environment.getCurrent.phoneDirectoryManager.getCurrentFilter; return phoneNumber != nil && [directory containsPhoneNumber:phoneNumber]; } --(void) addContactsToKnownWhisperUsers:(NSArray*) contacts { - for( Contact *contact in contacts){ - [_knownWhisperUserIds addObject:@([contact recordID])]; +- (NSString*)nameStringForPhoneIdentifier:(NSString*)identifier{ + for (Contact *contact in self.textSecureContacts) { + for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) { + if ([phoneNumber.toE164 isEqualToString:identifier]) { + return contact.fullName; + } + } } - NSMutableSet *users = [NSMutableSet setWithArray:latestWhisperUsersById.allValues]; - [users addObjectsFromArray:contacts]; - - [observableWhisperUsersController updateValue:users.allObjects]; - [self saveKnownWhisperUsers]; -} - --(BOOL) knownUserStoreInitialized{ - NSUserDefaults *d = [NSUserDefaults.standardUserDefaults objectForKey:KNOWN_USERS_DEFAULT_KEY]; - return (Nil != d); -} - --(NSMutableArray*) loadKnownWhisperUsers{ - NSArray *knownUsers = [NSUserDefaults.standardUserDefaults objectForKey:KNOWN_USERS_DEFAULT_KEY]; - return knownUsers == nil ? [NSMutableArray array] : knownUsers.mutableCopy; -} - --(void) saveKnownWhisperUsers{ - _knownWhisperUserIds = [NSMutableArray arrayWithArray:[latestWhisperUsersById allKeys]]; - [NSUserDefaults.standardUserDefaults setObject:[_knownWhisperUserIds copy] forKey:KNOWN_USERS_DEFAULT_KEY]; - [NSUserDefaults.standardUserDefaults synchronize]; -} - --(void) clearKnownWhisUsers{ - [NSUserDefaults.standardUserDefaults setObject:@[] forKey:KNOWN_USERS_DEFAULT_KEY]; - [NSUserDefaults.standardUserDefaults synchronize]; + return nil; } @end diff --git a/Signal/src/network/http/RPServerRequestsManager.m b/Signal/src/network/http/RPServerRequestsManager.m index 394144122f..9219e83203 100644 --- a/Signal/src/network/http/RPServerRequestsManager.m +++ b/Signal/src/network/http/RPServerRequestsManager.m @@ -82,7 +82,6 @@ MacrosSingletonImplemention TOCFutureSource *requestFutureSource = [TOCFutureSource new]; [self performRequest:apiCall success:^(NSURLSessionDataTask *task, id responseObject) { - NSLog(@"ResponseObject: %@", responseObject); [requestFutureSource trySetResult:task.response]; } failure:^(NSURLSessionDataTask *task, NSError *error) { [requestFutureSource trySetFailure:error]; diff --git a/Signal/src/phone/signaling/number directory/PhoneNumberDirectoryFilterManager.m b/Signal/src/phone/signaling/number directory/PhoneNumberDirectoryFilterManager.m index 677a1cff99..a317b47ab2 100644 --- a/Signal/src/phone/signaling/number directory/PhoneNumberDirectoryFilterManager.m +++ b/Signal/src/phone/signaling/number directory/PhoneNumberDirectoryFilterManager.m @@ -1,11 +1,16 @@ #import "PhoneNumberDirectoryFilterManager.h" +#import "ContactsManager.h" +#import "Cryptography.h" #import "Environment.h" #import "NotificationManifest.h" #import "PreferencesUtil.h" #import "RPServerRequestsManager.h" #import "SignalUtil.h" #import "ThreadManager.h" +#import "TSContactsIntersectionRequest.h" +#import "TSStorageManager.h" +#import "TSRecipient.h" #import "Util.h" #define MINUTE (60.0) @@ -18,13 +23,13 @@ @private TOCCancelTokenSource* currentUpdateLifetime; } --(id) init { +- (id)init { if (self = [super init]) { phoneNumberDirectoryFilter = PhoneNumberDirectoryFilter.phoneNumberDirectoryFilterDefault; } return self; } --(void) startUntilCancelled:(TOCCancelToken*)cancelToken { +- (void)startUntilCancelled:(TOCCancelToken*)cancelToken { lifetimeToken = cancelToken; phoneNumberDirectoryFilter = [Environment.preferences tryGetSavedPhoneNumberDirectory]; @@ -35,21 +40,21 @@ [self scheduleUpdate]; } --(PhoneNumberDirectoryFilter*) getCurrentFilter { +- (PhoneNumberDirectoryFilter*)getCurrentFilter { @synchronized(self) { return phoneNumberDirectoryFilter; } } --(void)forceUpdate { +- (void)forceUpdate { [self scheduleUpdateAt:NSDate.date]; } --(void) scheduleUpdate { +- (void)scheduleUpdate { return [self scheduleUpdateAt:self.getCurrentFilter.getExpirationDate]; } --(void) scheduleUpdateAt:(NSDate*)date { +- (void)scheduleUpdateAt:(NSDate*)date { void(^doUpdate)(void) = ^{ if (Environment.isRedPhoneRegistered) { - [self update]; + [self updateRedPhone]; } }; @@ -63,8 +68,10 @@ unlessCancelled:currentUpdateLifetime.token]; } --(void) update { - [[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall fetchBloomFilter] success:^(NSURLSessionDataTask *task, NSData *responseObject) { + +- (void) updateRedPhone { + + [[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall fetchBloomFilter] success:^(NSURLSessionDataTask *task, id responseObject) { PhoneNumberDirectoryFilter *directory = [PhoneNumberDirectoryFilter phoneNumberDirectoryFilterFromURLResponse:(NSHTTPURLResponse*)task.response body:responseObject]; @synchronized(self) { @@ -72,10 +79,9 @@ } [Environment.preferences setSavedPhoneNumberDirectory:directory]; - [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_DIRECTORY_WAS_UPDATED object:nil]; - [self scheduleUpdate]; - + [self updateTextSecureWithRedPhoneSucces:YES]; } failure:^(NSURLSessionDataTask *task, NSError *error) { + DDLogError(@"Error to fetch contact interesection: %@", error.debugDescription); NSString* desc = [NSString stringWithFormat:@"Failed to retrieve directory. Retrying in %f hours.", DIRECTORY_UPDATE_RETRY_PERIOD/HOUR]; Environment.errorNoter(desc, error, false); @@ -84,11 +90,67 @@ sinceDate:[NSDate date]]; @synchronized(self) { phoneNumberDirectoryFilter = [PhoneNumberDirectoryFilter phoneNumberDirectoryFilterWithBloomFilter:filter - andExpirationDate:retryDate]; + andExpirationDate:retryDate]; } + [self updateTextSecureWithRedPhoneSucces:NO]; + }]; +} + +- (void)updateTextSecureWithRedPhoneSucces:(BOOL)redPhoneSuccess { + NSArray *allContacts = [[[Environment getCurrent] contactsManager] allContacts]; + + NSMutableDictionary *contactsByPhoneNumber = [NSMutableDictionary dictionary]; + NSMutableDictionary *phoneNumbersByHashes = [NSMutableDictionary dictionary]; + + for (Contact *contact in allContacts) { + for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) { + [phoneNumbersByHashes setObject:phoneNumber.toE164 forKey:[Cryptography truncatedSHA1Base64EncodedWithoutPadding:phoneNumber.toE164]]; + [contactsByPhoneNumber setObject:contact forKey:phoneNumber.toE164]; + } + } + + NSArray *hashes = [phoneNumbersByHashes allKeys]; + + TSRequest *request = [[TSContactsIntersectionRequest alloc]initWithHashesArray:hashes]; + + [[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *tsTask, id responseDict) { + NSMutableArray *tsIdentifiers = [NSMutableArray array]; + NSMutableDictionary *relayForIdentifier = [NSMutableDictionary dictionary]; + NSArray *contactsArray = [(NSDictionary*)responseDict objectForKey:@"contacts"]; + + if (contactsArray) { + for (NSDictionary *dict in contactsArray) { + NSString *hash = [dict objectForKey:@"token"]; + + if (hash) { + [tsIdentifiers addObject:[phoneNumbersByHashes objectForKey:hash]]; + + NSString *relay = [dict objectForKey:@"relay"]; + if (relay) { + [relayForIdentifier setObject:relay forKey:[phoneNumbersByHashes objectForKey:hash]]; + } + } + } + } + + [[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + for (NSString *identifier in tsIdentifiers) { + TSRecipient *recipient = [TSRecipient recipientWithTextSecureIdentifier:identifier withTransaction:transaction]; + if (!recipient) { + NSString *relay = [relayForIdentifier objectForKey:recipient]; + recipient = [[TSRecipient alloc] initWithTextSecureIdentifier:identifier relay:relay]; + } + [recipient saveWithTransaction:transaction]; + } + }]; + + [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_DIRECTORY_WAS_UPDATED object:nil]; + [self scheduleUpdate]; + } failure:^(NSURLSessionDataTask *task, NSError *error) { [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_DIRECTORY_FAILED object:nil]; }]; } + @end diff --git a/Signal/src/textsecure/Account/TSAccountManager.h b/Signal/src/textsecure/Account/TSAccountManager.h index 2ccd6150b6..9e5e96d9d2 100644 --- a/Signal/src/textsecure/Account/TSAccountManager.h +++ b/Signal/src/textsecure/Account/TSAccountManager.h @@ -9,6 +9,9 @@ #import #import "TSConstants.h" +static NSString *const TSRegistrationErrorDomain = @"TSRegistrationErrorDomain"; +static NSString *const TSRegistrationErrorUserInfoHTTPStatus = @"TSHTTPStatus"; + typedef NS_ENUM(NSUInteger, TSRegistrationFailure) { kTSRegistrationFailureAuthentication, kTSRegistrationFailureNetwork, @@ -20,7 +23,7 @@ typedef NS_ENUM(NSUInteger, TSRegistrationFailure) { kTSRegistrationFailureRequest }; -typedef void(^failedVerificationBlock)(TSRegistrationFailure failureType); +typedef void(^failedVerificationBlock)(NSError *error); @interface TSAccountManager : NSObject @@ -69,4 +72,6 @@ typedef void(^failedVerificationBlock)(TSRegistrationFailure failureType); #endif ++ (NSError *)errorForRegistrationFailure:(TSRegistrationFailure)failureType HTTPStatusCode:(long)HTTPStatus; + @end diff --git a/Signal/src/textsecure/Account/TSAccountManager.m b/Signal/src/textsecure/Account/TSAccountManager.m index 501a307413..c19001c64d 100644 --- a/Signal/src/textsecure/Account/TSAccountManager.m +++ b/Signal/src/textsecure/Account/TSAccountManager.m @@ -36,7 +36,7 @@ } + (NSString *)registeredNumber { - YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] databaseConnection]; + YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] newDatabaseConnection]; __block NSString *phoneNumber; [dbConn readWithBlock:^(YapDatabaseReadTransaction *transaction) { @@ -47,7 +47,7 @@ } + (int)getOrGenerateRegistrationId { - YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] databaseConnection]; + YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] newDatabaseConnection]; __block int registrationID; [dbConn readWithBlock:^(YapDatabaseReadTransaction *transaction) { @@ -68,23 +68,28 @@ } + (void)registerForPushNotifications:(NSData *)pushToken success:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock{ - + NSString *stringToken = [[pushToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<> "]]; [[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRegisterForPushRequest alloc] initWithPushIdentifier:stringToken] success:^(NSURLSessionDataTask *task, id responseObject) { success(); } failure:^(NSURLSessionDataTask *task, NSError *error) { + + NSLog(@"NSError: %@", error.debugDescription); + + TSRegistrationFailure failureType = kTSRegistrationFailureNetwork; switch ([task statusCode]) { case 401: - failureBlock(kTSRegistrationFailureAuthentication); + failureType = kTSRegistrationFailureAuthentication; break; case 415: - failureBlock(kTSRegistrationFailureRequest); + failureType = kTSRegistrationFailureRequest; break; default: - failureBlock(kTSRegistrationFailureNetwork); break; } + + failureBlock([self errorForRegistrationFailure:failureType HTTPStatusCode:[task statusCode]]); }]; } @@ -93,7 +98,7 @@ NSString *authToken = [self generateNewAccountAuthenticationToken]; NSString *signalingKey = [self generateNewSignalingKeyToken]; NSString *phoneNumber = [[tsToken componentsSeparatedByString:@":"] objectAtIndex:0]; - + require(phoneNumber != nil); require(signalingKey != nil); require(authToken != nil); @@ -107,17 +112,27 @@ long statuscode = response.statusCode; if (statuscode == 200 || statuscode == 204) { - + [TSStorageManager storeServerToken:authToken signalingKey:signalingKey phoneNumber:phoneNumber]; - [self registerPreKeys:successBlock failure:failureBlock]; + + [self registerForPushNotifications:pushToken success:^{ + [self registerPreKeys:^{ + successBlock(); + } failure:failureBlock]; + } failure:^(NSError *error) { + failureBlock([self errorForRegistrationFailure:kTSRegistrationFailureNetwork HTTPStatusCode:0]); + }]; } else{ - failureBlock(kTSRegistrationFailureNetwork); + failureBlock([self errorForRegistrationFailure:kTSRegistrationFailureNetwork HTTPStatusCode:statuscode]); } } failure:^(NSURLSessionDataTask *task, NSError *error) { + DDLogError(@"Error registering with TextSecure: %@", error.debugDescription); + //TODO: Cover all error types: https://github.com/WhisperSystems/TextSecure-Server/wiki/API-Protocol - failureBlock(kTSRegistrationFailureNetwork); + // Above link doesn't appear to document the endpoint /v1/accounts/token/{token} - is it similar to /v1/accounts/code/{code} ? + failureBlock([self errorForRegistrationFailure:kTSRegistrationFailureNetwork HTTPStatusCode:[task statusCode]]); }]; } @@ -138,6 +153,40 @@ } failure:failureBlock]; } +#pragma mark Errors + ++ (NSError *)errorForRegistrationFailure:(TSRegistrationFailure)failureType HTTPStatusCode:(long)HTTPStatus { + + NSString *description = NSLocalizedString(@"REGISTRATION_ERROR", @""); + NSString *failureReason = nil; + + // TODO: Need localized strings for the rest of the values in the TSRegistrationFailure enum + if (failureType == kTSRegistrationFailureWrongCode) { + failureReason = NSLocalizedString(@"REGISTER_CHALLENGE_ALERT_VIEW_BODY", @""); + } else if (failureType == kTSRegistrationFailureRateLimit) { + failureReason = NSLocalizedString(@"REGISTER_RATE_LIMITING_BODY", @""); + } else if (failureType == kTSRegistrationFailureNetwork) { + failureReason = NSLocalizedString(@"REGISTRATION_BODY", @""); + } else { + failureReason = NSLocalizedString(@"REGISTER_CHALLENGE_UNKNOWN_ERROR", @""); + } + + NSMutableDictionary *userInfo = NSMutableDictionary.new; + + userInfo[NSLocalizedDescriptionKey] = description; + + if (failureReason != nil) { + userInfo[NSLocalizedFailureReasonErrorKey] = failureReason; + } + if (HTTPStatus != 0) { + userInfo[TSRegistrationErrorUserInfoHTTPStatus] = @(HTTPStatus); + } + + NSError *error = [NSError errorWithDomain:TSRegistrationErrorDomain code:failureType userInfo:userInfo]; + + return error; +} + #pragma mark Server keying material + (NSString*)generateNewAccountAuthenticationToken { diff --git a/Signal/src/textsecure/Account/TSPreKeyManager.m b/Signal/src/textsecure/Account/TSPreKeyManager.m index 43b68c5608..d5f87d4ddc 100644 --- a/Signal/src/textsecure/Account/TSPreKeyManager.m +++ b/Signal/src/textsecure/Account/TSPreKeyManager.m @@ -42,7 +42,7 @@ success(); } failure:^(NSURLSessionDataTask *task, NSError *error) { - failureBlock(kTSRegistrationFailureNetwork); + failureBlock([TSAccountManager errorForRegistrationFailure:kTSRegistrationFailureNetwork HTTPStatusCode:0]); }]; } diff --git a/Signal/src/textsecure/Contacts/TSContact.h b/Signal/src/textsecure/Contacts/TSContact.h deleted file mode 100644 index c61f467253..0000000000 --- a/Signal/src/textsecure/Contacts/TSContact.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// TSContact.h -// TextSecureKit -// -// Created by Frederic Jacobs on 12/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. -// - -#import -#import - -#if TARGET_OS_IPHONE -#import -#import -#endif - -#import "TSInteraction.h" -#import "TSYapDatabaseObject.h" - -typedef NS_OPTIONS(NSInteger, TSServicesAvailable){ - TSServiceRedPhone, - TSServiceTextSecure -}; - -/** - * TSContacts always have one property, the identifier they are registered with on TextSecure. All the rest is optional. - */ - -@interface TSContact : TSYapDatabaseObject - -- (instancetype)initWithRecipientId:(NSString*)recipientId; - -- (TSServicesAvailable)availableServices; -- (TSInteraction*)lastMessageWithTransaction:(YapDatabaseReadTransaction *)transaction; - -#if TARGET_OS_IPHONE -- (ABRecordID*)addressBookID; -- (NSString*)firstName; -- (NSString*)lastName; -#endif - -@end diff --git a/Signal/src/textsecure/Contacts/TSContact.m b/Signal/src/textsecure/Contacts/TSContact.m deleted file mode 100644 index 469321e0a9..0000000000 --- a/Signal/src/textsecure/Contacts/TSContact.m +++ /dev/null @@ -1,31 +0,0 @@ -// -// TSContact.m -// TextSecureKit -// -// Created by Frederic Jacobs on 12/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. -// - -#import "TSContact.h" - -static NSString *recipientKey = @"TSIdentifierRecipientIdKey"; - -@implementation TSContact - -+ (BOOL)supportsSecureCoding{ - return YES; -} - -- (id)initWithCoder:(NSCoder *)aDecoder{ - NSString *recipientId = [aDecoder decodeObjectOfClass:[NSString class] forKey:recipientKey]; - return [self initWithRecipientId:recipientId]; -} - - -+ (NSString*)collection{ - return @"TSContactCollection"; -} - -# pragma mark AddressBook Lookups - -@end diff --git a/Signal/src/textsecure/Contacts/TSRecipient.m b/Signal/src/textsecure/Contacts/TSRecipient.m index a4f6a7b0d2..79871328e8 100644 --- a/Signal/src/textsecure/Contacts/TSRecipient.m +++ b/Signal/src/textsecure/Contacts/TSRecipient.m @@ -9,10 +9,10 @@ #import "TSStorageManager+IdentityKeyStore.h" #import "TSRecipient.h" -@interface TSRecipient (){ - NSMutableSet *devices; - NSData *verifiedKey; -} +@interface TSRecipient () + +@property (nonatomic, retain) NSMutableSet *devices; +@property (nonatomic, copy) NSData *verifiedKey; @end @@ -22,48 +22,44 @@ return @"TSRecipient"; } -- (instancetype)initWithTextSecureIdentifier:(NSString*)textSecureIdentifier{ +- (instancetype)initWithTextSecureIdentifier:(NSString*)textSecureIdentifier relay:(NSString *)relay{ self = [super initWithUniqueId:textSecureIdentifier]; if (self) { - devices = [NSMutableSet setWithObject:[NSNumber numberWithInt:1]]; - verifiedKey = nil; + _devices = [NSMutableSet setWithObject:[NSNumber numberWithInt:1]]; + _verifiedKey = nil; + _relay = relay; } return self; } + (instancetype)recipientWithTextSecureIdentifier:(NSString*)textSecureIdentifier withTransaction:(YapDatabaseReadTransaction*)transaction{ - TSRecipient *recipient = [self fetchObjectWithUniqueID:textSecureIdentifier transaction:transaction]; - - if (!recipient) { - recipient = [[self alloc] initWithTextSecureIdentifier:textSecureIdentifier]; - } - return recipient; + return [self fetchObjectWithUniqueID:textSecureIdentifier transaction:transaction]; } - (NSSet*)devices{ - return [devices copy]; + return [_devices copy]; } - (void)addDevices:(NSSet *)set{ - [devices unionSet:set]; + [_devices unionSet:set]; } - (void)removeDevices:(NSSet *)set{ - [devices minusSet:set]; + [_devices minusSet:set]; } #pragma mark Fingerprint verification - (BOOL)hasVerifiedFingerprint{ - if (verifiedKey) { - BOOL equalsStoredValue = [verifiedKey isEqualToData:[[TSStorageManager sharedManager] identityKeyForRecipientId:self.uniqueId]]; + if (self.verifiedKey) { + BOOL equalsStoredValue = [self.verifiedKey isEqualToData:[[TSStorageManager sharedManager] identityKeyForRecipientId:self.uniqueId]]; if (equalsStoredValue) { return YES; } else{ - verifiedKey = nil; + self.verifiedKey = nil; return NO; } @@ -74,9 +70,9 @@ - (void)setFingerPrintVerified:(BOOL)verified transaction:(YapDatabaseReadTransaction*)transaction{ if (verified) { - verifiedKey = [[TSStorageManager sharedManager] identityKeyForRecipientId:self.uniqueId]; + self.verifiedKey = [[TSStorageManager sharedManager] identityKeyForRecipientId:self.uniqueId]; } else{ - verifiedKey = nil; + self.verifiedKey = nil; } } diff --git a/Signal/src/textsecure/Contacts/TSThread.m b/Signal/src/textsecure/Contacts/TSThread.m index 56f705e62d..7171b2ddaa 100644 --- a/Signal/src/textsecure/Contacts/TSThread.m +++ b/Signal/src/textsecure/Contacts/TSThread.m @@ -8,7 +8,8 @@ #import "TSThread.h" -#import "TSContact.h" +#import "Environment.h" +#import "ContactsManager.h" #import "TSGroup.h" @implementation TSThread @@ -32,4 +33,16 @@ return FALSE; } +- (uint64_t)lastMessageId{ + return 0; +} + +- (NSDate*)lastMessageDate{ + return [NSDate date]; +} + +- (UIImage*)image{ + return nil; +} + @end diff --git a/Signal/src/textsecure/Contacts/Threads/TSContactThread.h b/Signal/src/textsecure/Contacts/Threads/TSContactThread.h index 887ad15f9f..8a62249ef2 100644 --- a/Signal/src/textsecure/Contacts/Threads/TSContactThread.h +++ b/Signal/src/textsecure/Contacts/Threads/TSContactThread.h @@ -13,7 +13,7 @@ @interface TSContactThread : TSThread -+ (instancetype)threadWithContactId:(NSString*)contactId; ++ (instancetype)threadWithContactId:(NSString*)contactId transaction:(YapDatabaseReadWriteTransaction*)transaction; - (TSRecipient*)recipient; diff --git a/Signal/src/textsecure/Contacts/Threads/TSContactThread.m b/Signal/src/textsecure/Contacts/Threads/TSContactThread.m index b9660f3253..65f693475e 100644 --- a/Signal/src/textsecure/Contacts/Threads/TSContactThread.m +++ b/Signal/src/textsecure/Contacts/Threads/TSContactThread.m @@ -8,7 +8,9 @@ #import "TSContactThread.h" +#import "Environment.h" #import "TSStorageManager.h" +#import "ContactsManager.h" #define TSContactThreadPrefix @"c" @@ -23,13 +25,13 @@ return self; } -+ (instancetype)threadWithContactId:(NSString*)contactId{ ++ (instancetype)threadWithContactId:(NSString*)contactId transaction:(YapDatabaseReadWriteTransaction*)transaction { - TSContactThread *thread = [self fetchObjectWithUniqueID:[self threadIdFromContactId:contactId]]; + TSContactThread *thread = [self fetchObjectWithUniqueID:[self threadIdFromContactId:contactId] transaction:transaction]; if (!thread) { thread = [[TSContactThread alloc] initWithContactId:contactId]; - [thread save]; + [thread saveWithTransaction:transaction]; } return thread; @@ -43,6 +45,17 @@ return false; } +- (NSString*)name{ + NSString *contactId = [self contactIdentifier]; + NSString *name = [[Environment getCurrent].contactsManager nameStringForPhoneIdentifier:contactId]; + + if (!name) { + name = contactId; + } + + return name; +} + + (NSString*)threadIdFromContactId:(NSString*)contactId{ return [TSContactThreadPrefix stringByAppendingString:contactId]; } diff --git a/Signal/src/textsecure/Messages/TSCall.h b/Signal/src/textsecure/Messages/TSCall.h index 7200224ada..9cb3c219bd 100644 --- a/Signal/src/textsecure/Messages/TSCall.h +++ b/Signal/src/textsecure/Messages/TSCall.h @@ -9,7 +9,6 @@ #import #import "TSInteraction.h" -#import "TSContact.h" @interface TSCall : TSInteraction diff --git a/Signal/src/textsecure/Messages/TSErrorMessage.h b/Signal/src/textsecure/Messages/TSErrorMessage.h index 2c2a0171b8..aa1f1751ae 100644 --- a/Signal/src/textsecure/Messages/TSErrorMessage.h +++ b/Signal/src/textsecure/Messages/TSErrorMessage.h @@ -22,7 +22,7 @@ typedef NS_ENUM(int32_t, TSErrorMessageType){ TSErrorMessageInvalidVersion }; -+ (instancetype)invalidProtocolBufferWithSignal:(IncomingPushMessageSignal*)preKeyMessage; ++ (instancetype)invalidProtocolBufferWithException:(NSException*)exception; + (instancetype)duplicateMessageWithSignal:(IncomingPushMessageSignal*)preKeyMessage; + (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)preKeyMessage; + (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)preKeyMessage; diff --git a/Signal/src/textsecure/Messages/TSMessagesManager.m b/Signal/src/textsecure/Messages/TSMessagesManager.m index 387728b61b..5ba6b0a05e 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager.m +++ b/Signal/src/textsecure/Messages/TSMessagesManager.m @@ -14,8 +14,6 @@ #import "IncomingPushMessageSignal.pb.h" #import "NSData+Base64.h" -#import "TSContact.h" - #import "TSIncomingMessage.h" #import "TSErrorMessage.h" #import "TSInfoMessage.h" @@ -49,46 +47,56 @@ self = [super init]; if (self) { - _dbConnection = [TSStorageManager sharedManager].databaseConnection; + _dbConnection = [TSStorageManager sharedManager].newDatabaseConnection; } return self; } - (void)handleMessageSignal:(NSData*)signalData{ - NSData *decryptedPayload = [Cryptography decryptAppleMessagePayload:signalData withSignalingKey:TSStorageManager.signalingKey]; + NSString *base64String = [[NSString alloc] initWithData:signalData encoding:NSUTF8StringEncoding]; + + NSData *encryptedSignal = [NSData dataFromBase64String:base64String]; + NSData *decryptedPayload = [Cryptography decryptAppleMessagePayload:encryptedSignal + withSignalingKey:TSStorageManager.signalingKey]; if (!decryptedPayload) { + DDLogWarn(@"Failed to decrypt incoming payload or bad HMAC"); return; } - IncomingPushMessageSignal *messageSignal = [IncomingPushMessageSignal parseFromData:decryptedPayload]; - - switch (messageSignal.type) { - case IncomingPushMessageSignalTypeCiphertext: - [self handleSecureMessage:messageSignal]; - break; - - case IncomingPushMessageSignalTypePrekeyBundle: - [self handlePreKeyBundle:messageSignal]; - break; - + @try { + IncomingPushMessageSignal *messageSignal = [IncomingPushMessageSignal parseFromData:decryptedPayload]; + + switch (messageSignal.type) { + case IncomingPushMessageSignalTypeCiphertext: + [self handleSecureMessage:messageSignal]; + break; + + case IncomingPushMessageSignalTypePrekeyBundle: + [self handlePreKeyBundle:messageSignal]; + break; + // Other messages are just dismissed for now. - - case IncomingPushMessageSignalTypeKeyExchange: - NSLog(@"Key exchange!"); - break; - case IncomingPushMessageSignalTypePlaintext: - NSLog(@"Plaintext"); - break; - case IncomingPushMessageSignalTypeReceipt: - NSLog(@"Receipt"); - break; - case IncomingPushMessageSignalTypeUnknown: - NSLog(@"Unknown"); - break; - default: - break; + + case IncomingPushMessageSignalTypeKeyExchange: + DDLogWarn(@"Received Key Exchange Message, not supported"); + break; + case IncomingPushMessageSignalTypePlaintext: + DDLogWarn(@"Received a plaintext message"); + break; + case IncomingPushMessageSignalTypeReceipt: + DDLogInfo(@"Received a delivery receipt"); + break; + case IncomingPushMessageSignalTypeUnknown: + DDLogWarn(@"Received an unknown message type"); + break; + default: + break; + } + } + @catch (NSException *exception) { + DDLogWarn(@"Received an incorrectly formatted protocol buffer: %@", exception.debugDescription); } } @@ -102,16 +110,12 @@ // Deal with failure } - WhisperMessage *message = [[WhisperMessage alloc] initWithData:secureMessage.message]; - - if (!message) { - [self failedProtocolBufferDeserialization:secureMessage]; - return; - } - - NSData *plaintext; + PushMessageContent *content; @try { + + WhisperMessage *message = [[WhisperMessage alloc] initWithData:secureMessage.message]; + SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager preKeyStore:storageManager signedPreKeyStore:storageManager @@ -119,20 +123,15 @@ recipientId:recipientId deviceId:deviceId]; - plaintext = [[cipher decrypt:message] removePadding]; + NSData *plaintext = [[cipher decrypt:message] removePadding]; + + content = [PushMessageContent parseFromData:plaintext]; } @catch (NSException *exception) { [self processException:exception pushSignal:secureMessage]; return; } - PushMessageContent *content = [PushMessageContent parseFromData:plaintext]; - - if (!content) { - [self failedProtocolBufferDeserialization:secureMessage]; - return; - } - [self handleIncomingMessage:secureMessage withPushContent:content]; } } @@ -143,16 +142,11 @@ NSString *recipientId = preKeyMessage.source; int deviceId = preKeyMessage.sourceDevice; - PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:preKeyMessage.message]; + PushMessageContent *content; - if (!message) { - [self failedProtocolBufferDeserialization:preKeyMessage]; - return; - } - - - NSData *plaintext; @try { + PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:preKeyMessage.message]; + SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager preKeyStore:storageManager signedPreKeyStore:storageManager @@ -160,20 +154,15 @@ recipientId:recipientId deviceId:deviceId]; - plaintext = [[cipher decrypt:message] removePadding]; + NSData *plaintext = [[cipher decrypt:message] removePadding]; + + content = [PushMessageContent parseFromData:plaintext]; } @catch (NSException *exception) { [self processException:exception pushSignal:preKeyMessage]; return; } - PushMessageContent *content = [PushMessageContent parseFromData:plaintext]; - - if (!content) { - [self failedProtocolBufferDeserialization:preKeyMessage]; - return; - } - [self handleIncomingMessage:preKeyMessage withPushContent:content]; } @@ -196,12 +185,14 @@ } - (void)handleEndSessionMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content{ - TSContactThread *thread = [TSContactThread threadWithContactId:message.source]; - uint64_t timeStamp = message.timestamp; - - if (thread){ - [[[TSInfoMessage alloc] initWithTimestamp:timeStamp inThread:thread messageType:TSInfoMessageTypeSessionDidEnd] save]; - } + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + TSContactThread *thread = [TSContactThread threadWithContactId:message.source transaction:transaction]; + uint64_t timeStamp = message.timestamp; + + if (thread){ + [[[TSInfoMessage alloc] initWithTimestamp:timeStamp inThread:thread messageType:TSInfoMessageTypeSessionDidEnd] saveWithTransaction:transaction]; + } + }]; [[TSStorageManager sharedManager] deleteAllSessionsForContact:message.source]; } @@ -219,25 +210,22 @@ NSString *body = content.body; NSData *groupId = content.hasGroup?content.group.id:nil; - TSIncomingMessage *incomingMessage; - - if (groupId) { - TSGroupThread *thread = [TSGroupThread threadWithGroupId:groupId]; - incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:thread authorId:message.source messageBody:body attachements:nil]; - } else{ - TSContactThread *thread = [TSContactThread threadWithContactId:message.source]; - incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:thread messageBody:body attachements:nil]; - } - - NSLog(@"Incoming message: %@", incomingMessage.body); - [incomingMessage save]; -} - -- (void)failedProtocolBufferDeserialization:(IncomingPushMessageSignal*)signal{ - NSLog(@"Failed Protocol buffer deserialization"); - TSErrorMessage *errorMessage = [TSErrorMessage invalidProtocolBufferWithSignal:signal]; - [errorMessage save]; - return; + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + TSIncomingMessage *incomingMessage; + TSThread *thread; + if (groupId) { + TSGroupThread *gThread = [TSGroupThread threadWithGroupId:groupId]; + incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:gThread authorId:message.source messageBody:body attachements:nil]; + thread = gThread; + } else{ + TSContactThread *cThread = [TSContactThread threadWithContactId:message.source transaction:transaction]; + incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:cThread messageBody:body attachements:nil]; + thread = cThread; + } + + [incomingMessage saveWithTransaction:transaction]; + [thread saveWithTransaction:transaction]; + }]; } - (void)processException:(NSException*)exception pushSignal:(IncomingPushMessageSignal*)signal{ diff --git a/Signal/src/textsecure/Network/API/Requests/TSContactsIntersectionRequest.h b/Signal/src/textsecure/Network/API/Requests/TSContactsIntersectionRequest.h index 7a794bc986..81998329b4 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSContactsIntersectionRequest.h +++ b/Signal/src/textsecure/Network/API/Requests/TSContactsIntersectionRequest.h @@ -8,6 +8,8 @@ #import "TSRequest.h" +#import "TSNetworkManager.h" + @interface TSContactsIntersectionRequest : TSRequest - (id)initWithHashesArray:(NSArray*)hashes; diff --git a/Signal/src/textsecure/Network/API/Requests/TSRegisterWithTokenRequest.m b/Signal/src/textsecure/Network/API/Requests/TSRegisterWithTokenRequest.m index 0bb816b120..bca8be00c9 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSRegisterWithTokenRequest.m +++ b/Signal/src/textsecure/Network/API/Requests/TSRegisterWithTokenRequest.m @@ -21,7 +21,10 @@ self.numberToValidate = number; - [self.parameters addEntriesFromDictionary:@{@"signalingKey": signalingKey, @"AuthKey": authKey, @"supportsSMS": @FALSE, @"registrationId": [NSString stringWithFormat:@"%i",[TSAccountManager getOrGenerateRegistrationId]]}]; + [self.parameters addEntriesFromDictionary:@{@"signalingKey": signalingKey, + @"AuthKey": authKey, + @"supportsSMS": @"0", + @"registrationId": [NSString stringWithFormat:@"%i",[TSAccountManager getOrGenerateRegistrationId]]}]; [self setHTTPMethod:@"PUT"]; diff --git a/Signal/src/textsecure/Network/API/TSNetworkManager.m b/Signal/src/textsecure/Network/API/TSNetworkManager.m index 7cbd2bb75b..4b01859b03 100644 --- a/Signal/src/textsecure/Network/API/TSNetworkManager.m +++ b/Signal/src/textsecure/Network/API/TSNetworkManager.m @@ -39,7 +39,7 @@ if (self = [super init]) { NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration; self.operationManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[[NSURL alloc] initWithString:textSecureServerURL] sessionConfiguration:sessionConf]; - AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; + AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; //TODO: pinging cert policy.allowInvalidCertificates = YES; NSString *certPath = [NSBundle.mainBundle pathForResource:@"whisperReal" ofType:@"cer"]; NSData *certData = [NSData dataWithContentsOfFile:certPath]; diff --git a/Signal/src/textsecure/Network/WebSockets/TSSocketManager.m b/Signal/src/textsecure/Network/WebSockets/TSSocketManager.m index feb79d1bde..76e02c0c55 100644 --- a/Signal/src/textsecure/Network/WebSockets/TSSocketManager.m +++ b/Signal/src/textsecure/Network/WebSockets/TSSocketManager.m @@ -53,7 +53,7 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification"; + (void)becomeActive { TSSocketManager *sharedInstance = [self sharedManager]; - SRWebSocket *socket =[sharedInstance websocket]; + SRWebSocket *socket = [sharedInstance websocket]; if (socket) { switch ([socket readyState]) { @@ -76,8 +76,8 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification"; NSString *webSocketConnect = [textSecureWebSocketAPI stringByAppendingString:[[self sharedManager] webSocketAuthenticationString]]; NSURL *webSocketConnectURL = [NSURL URLWithString:webSocketConnect]; - socket = [[SRWebSocket alloc] initWithURL:webSocketConnectURL]; - socket.delegate = [self sharedManager]; + socket = [[SRWebSocket alloc] initWithURL:webSocketConnectURL]; + socket.delegate = [self sharedManager]; [socket open]; [[self sharedManager] setWebsocket:socket]; } @@ -90,7 +90,7 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification"; #pragma mark - Delegate methods - (void) webSocketDidOpen:(SRWebSocket *)webSocket { - self.timer = [NSTimer scheduledTimerWithTimeInterval:kWebSocketHeartBeat target:self selector:@selector(webSocketHeartBeat) userInfo:nil repeats:YES]; + self.timer = [NSTimer scheduledTimerWithTimeInterval:kWebSocketHeartBeat target:self selector:@selector(webSocketHeartBeat) userInfo:nil repeats:YES]; self.status = kSocketStatusOpen; } @@ -140,7 +140,6 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification"; } - (void)webSocketHeartBeat { - DDLogVerbose(@"WebSocket sent ping"); [self.websocket sendPing:nil]; } diff --git a/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+SignedPreKeyStore.m b/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+SignedPreKeyStore.m index 75364a727a..6b765c204b 100644 --- a/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+SignedPreKeyStore.m +++ b/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+SignedPreKeyStore.m @@ -37,7 +37,7 @@ - (NSArray*)loadSignedPreKeys { NSMutableArray *signedPreKeyRecords = [NSMutableArray array]; - YapDatabaseConnection *conn = [self databaseConnection]; + YapDatabaseConnection *conn = [self newDatabaseConnection]; [conn readWithBlock:^(YapDatabaseReadTransaction *transaction) { [transaction enumerateRowsInCollection:TSStorageManagerSignedPreKeyStoreCollection diff --git a/Signal/src/textsecure/Storage/TSDatabaseView.h b/Signal/src/textsecure/Storage/TSDatabaseView.h index 833311ff76..409385ac4b 100644 --- a/Signal/src/textsecure/Storage/TSDatabaseView.h +++ b/Signal/src/textsecure/Storage/TSDatabaseView.h @@ -10,4 +10,12 @@ @interface TSDatabaseView : NSObject +extern NSString *TSThreadGroup; + +extern NSString *TSThreadDatabaseViewExtensionName; +extern NSString *TSMessageDatabaseViewExtensionName; + ++ (BOOL)registerThreadDatabaseView; ++ (BOOL)registerBuddyConversationDatabaseView; + @end diff --git a/Signal/src/textsecure/Storage/TSDatabaseView.m b/Signal/src/textsecure/Storage/TSDatabaseView.m index a1e03be9ef..58536d0556 100644 --- a/Signal/src/textsecure/Storage/TSDatabaseView.m +++ b/Signal/src/textsecure/Storage/TSDatabaseView.m @@ -11,17 +11,18 @@ #import #import "TSThread.h" -#import "TSStorageManager.h" #import "TSInteraction.h" +#import "TSStorageManager.h" +#import "TSRecipient.h" NSString *TSThreadGroup = @"TSThreadGroup"; -NSString *TSThreadDatabaseViewExtensionName = @"TSThreadDatabaseViewExtensionName"; -NSString *TSMessageDatabaseViewExtensionName = @"TSMessageDatabaseViewExtensionName"; +NSString *TSThreadDatabaseViewExtensionName = @"TSThreadDatabaseViewExtensionName"; +NSString *TSMessageDatabaseViewExtensionName = @"TSMessageDatabaseViewExtensionName"; @implementation TSDatabaseView -+ (BOOL)registerThreadDatabaseView{ ++ (BOOL)registerThreadDatabaseView { YapDatabaseView *threadView = [[TSStorageManager sharedManager].database registeredExtension:TSThreadDatabaseViewExtensionName]; if (threadView) { return YES; @@ -61,7 +62,7 @@ NSString *TSMessageDatabaseViewExtensionName = @"TSMessageDatabaseViewExtensionN return [[TSStorageManager sharedManager].database registerExtension:databaseView withName:TSThreadDatabaseViewExtensionName]; } -+ (BOOL)registerBuddyConversationDatabaseView{ ++ (BOOL)registerBuddyConversationDatabaseView { if ([[TSStorageManager sharedManager].database registeredExtension:TSMessageDatabaseViewExtensionName]) { return YES; } diff --git a/Signal/src/textsecure/Storage/TSStorageManager+keyingMaterial.m b/Signal/src/textsecure/Storage/TSStorageManager+keyingMaterial.m index 49c9c20020..5401166343 100644 --- a/Signal/src/textsecure/Storage/TSStorageManager+keyingMaterial.m +++ b/Signal/src/textsecure/Storage/TSStorageManager+keyingMaterial.m @@ -22,7 +22,7 @@ } + (void)storeServerToken:(NSString*)authToken signalingKey:(NSString*)signalingKey phoneNumber:(NSString*)phoneNumber { - YapDatabaseConnection *dbConn = [[self sharedManager] databaseConnection]; + YapDatabaseConnection *dbConn = [[self sharedManager] dbConnection]; [dbConn readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction setObject:authToken forKey:TSStorageServerAuthToken inCollection:TSStorageUserAccountCollection]; diff --git a/Signal/src/textsecure/Storage/TSStorageManager.h b/Signal/src/textsecure/Storage/TSStorageManager.h index af26df20ea..5ff5678c6b 100644 --- a/Signal/src/textsecure/Storage/TSStorageManager.h +++ b/Signal/src/textsecure/Storage/TSStorageManager.h @@ -15,12 +15,15 @@ @class PreKeyRecord; @class SignedPreKeyRecord; +extern NSString *const TSUIDatabaseConnectionDidUpdateNotification; + @interface TSStorageManager : NSObject + (instancetype)sharedManager; +- (void)setupDatabase; - (YapDatabase*)database; -- (YapDatabaseConnection*)databaseConnection; +- (YapDatabaseConnection*)newDatabaseConnection; - (void)setObject:(id)object forKey:(NSString*)key inCollection:(NSString*)collection; - (void)removeObjectForKey:(NSString*)string inCollection:(NSString *)collection; @@ -38,4 +41,6 @@ - (SignedPreKeyRecord*)signedPreKeyRecordForKey:(NSString*)key inCollection:(NSString*)collection; - (void)purgeCollection:(NSString*)collection; +@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; + @end diff --git a/Signal/src/textsecure/Storage/TSStorageManager.m b/Signal/src/textsecure/Storage/TSStorageManager.m index fb7994aefd..1460a586c9 100644 --- a/Signal/src/textsecure/Storage/TSStorageManager.m +++ b/Signal/src/textsecure/Storage/TSStorageManager.m @@ -13,6 +13,11 @@ #import "CryptoTools.h" #import "NSData+Base64.h" +#import "TSDatabaseView.h" + + +NSString *const TSUIDatabaseConnectionDidUpdateNotification = @"TSUIDatabaseConnectionDidUpdateNotification"; + static const NSString *const databaseName = @"Signal.sqlite"; static NSString * keychainService = @"TSKeyChainService"; static NSString * keychainDBPassAccount = @"TSDatabasePass"; @@ -20,7 +25,6 @@ static NSString * keychainDBPassAccount = @"TSDatabasePass"; @interface TSStorageManager () @property YapDatabase *database; -@property YapDatabaseConnection *dbConnection; @end @@ -31,6 +35,7 @@ static NSString * keychainDBPassAccount = @"TSDatabasePass"; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedMyManager = [[self alloc] init]; + [sharedMyManager protectDatabaseFile]; }); return sharedMyManager; } @@ -38,34 +43,58 @@ static NSString * keychainDBPassAccount = @"TSDatabasePass"; - (instancetype)init { self = [super init]; - if (self) { - self.database = [self newDatabaseInit]; - self.dbConnection = self.databaseConnection; - } - - return self; -} - -- (YapDatabase*)newDatabaseInit{ YapDatabaseOptions *options = [[YapDatabaseOptions alloc] init]; options.corruptAction = YapDatabaseCorruptAction_Fail; options.passphraseBlock = ^{ return [self databasePassword]; }; - return [[YapDatabase alloc] initWithPath:[self dbPath] - objectSerializer:NULL - objectDeserializer:NULL - metadataSerializer:NULL - metadataDeserializer:NULL - objectSanitizer:NULL - metadataSanitizer:NULL - options:options]; - + _database = [[YapDatabase alloc] initWithPath:[self dbPath] + objectSerializer:NULL + objectDeserializer:NULL + metadataSerializer:NULL + metadataDeserializer:NULL + objectSanitizer:NULL + metadataSanitizer:NULL + options:options]; + _dbConnection = self.newDatabaseConnection; + return self; +} + +- (void)setupDatabase { + [TSDatabaseView registerThreadDatabaseView]; + [TSDatabaseView registerBuddyConversationDatabaseView]; +} + +/** + * Protects the preference and logs file with disk encryption and prevents them to leak to iCloud. + */ + +- (void)protectDatabaseFile{ + + NSDictionary *attrs = @{NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication}; + NSError *error; + + + [NSFileManager.defaultManager setAttributes:attrs ofItemAtPath:[self dbPath] error:&error]; + [[NSURL fileURLWithPath:[self dbPath]] setResourceValue:@YES + forKey:NSURLIsExcludedFromBackupKey + error:&error]; + + if (error) { + DDLogError(@"Error while removing log files from backup: %@", error.description); + UIAlertView *alert = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"WARNING", @"") + message:NSLocalizedString(@"DISABLING_BACKUP_FAILED", @"") + delegate:nil + cancelButtonTitle:NSLocalizedString(@"OK", @"") + otherButtonTitles:nil]; + [alert show]; + return; + } } -- (YapDatabaseConnection *)databaseConnection { +- (YapDatabaseConnection *)newDatabaseConnection { return self.database.newConnection; } @@ -209,8 +238,7 @@ static NSString * keychainDBPassAccount = @"TSDatabasePass"; DDLogError(@"Failed to delete database: %@", error.description); } - self.database = [self newDatabaseInit]; - self.dbConnection = self.databaseConnection; + [self setupDatabase]; } @end diff --git a/Signal/src/textsecure/Storage/TSYapDatabaseObject.m b/Signal/src/textsecure/Storage/TSYapDatabaseObject.m index d18cd11887..bcdf47a0cd 100644 --- a/Signal/src/textsecure/Storage/TSYapDatabaseObject.m +++ b/Signal/src/textsecure/Storage/TSYapDatabaseObject.m @@ -31,7 +31,7 @@ } - (void)save{ - [[TSStorageManager sharedManager].databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self saveWithTransaction:transaction]; }]; } @@ -43,7 +43,7 @@ - (void)remove{ - [[TSStorageManager sharedManager].databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self removeWithTransaction:transaction]; }]; } @@ -62,7 +62,7 @@ + (instancetype) fetchObjectWithUniqueID:(NSString *)uniqueID{ __block id object; - [[TSStorageManager sharedManager].databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + [[TSStorageManager sharedManager].dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { object = [transaction objectForKey:uniqueID inCollection:[self collection]]; }]; diff --git a/Signal/src/textsecure/Util/Cryptography.m b/Signal/src/textsecure/Util/Cryptography.m index 789e113033..f685a978f1 100755 --- a/Signal/src/textsecure/Util/Cryptography.m +++ b/Signal/src/textsecure/Util/Cryptography.m @@ -7,6 +7,7 @@ // #import "Cryptography.h" +#import "Constraints.h" #import #import #import @@ -64,7 +65,7 @@ return output; } -#pragma makr SHA256 +#pragma mark SHA256 +(NSData*) computeSHA256:(NSData *)data truncatedToBytes:(int)truncatedBytes { uint8_t digest[CC_SHA256_DIGEST_LENGTH]; CC_SHA256(data.bytes, (unsigned int)data.length, digest); @@ -147,7 +148,15 @@ -+(NSData*) decryptCBCMode:(NSData*) dataToDecrypt withKey:(NSData*) key withIV:(NSData*) iv withVersion:(NSData*)version withHMACKey:(NSData*) hmacKey withHMACType:(TSMACType)hmacType forHMAC:(NSData *)hmac { ++(NSData*)decryptCBCMode:(NSData*)dataToDecrypt + key:(NSData*)key + IV:(NSData*)iv + version:(NSData*)version + HMACKey:(NSData*) hmacKey + HMACType:(TSMACType)hmacType + matchingHMAC:(NSData *)hmac +{ + /* AES256 CBC encrypt then mac Returns nil if hmac invalid or decryption fails @@ -160,8 +169,8 @@ [dataToHmac appendData:iv]; [dataToHmac appendData:dataToDecrypt]; - // verify hmac NSData* ourHmacData; + if(hmacType == TSHMACSHA1Truncated10Bytes) { ourHmacData = [Cryptography truncatedSHA1HMAC:dataToHmac withHMACKey:hmacKey truncation:10]; } @@ -190,12 +199,13 @@ free(buffer); return nil; - - } #pragma mark methods which use AES CBC -+(NSData*) decryptAppleMessagePayload:(NSData*)payload withSignalingKey:(NSString*)signalingKeyString{ ++(NSData*)decryptAppleMessagePayload:(NSData*)payload withSignalingKey:(NSString*)signalingKeyString{ + require(payload); + require(signalingKeyString); + unsigned char version[1]; unsigned char iv[16]; NSUInteger ciphertext_length = ([payload length]-10-17)*sizeof(char); @@ -209,7 +219,15 @@ NSData* signalingKey = [NSData dataFromBase64String:signalingKeyString]; NSData* signalingKeyAESKeyMaterial = [signalingKey subdataWithRange:NSMakeRange(0, 32)]; NSData* signalingKeyHMACKeyMaterial = [signalingKey subdataWithRange:NSMakeRange(32, 20)]; - return [Cryptography decryptCBCMode:[NSData dataWithBytesNoCopy:ciphertext length:ciphertext_length freeWhenDone:YES] withKey:signalingKeyAESKeyMaterial withIV:[NSData dataWithBytes:iv length:16] withVersion:[NSData dataWithBytes:version length:1] withHMACKey:signalingKeyHMACKeyMaterial withHMACType:TSHMACSHA256Truncated10Bytes forHMAC:[NSData dataWithBytes:mac length:10]]; + return [Cryptography decryptCBCMode:[NSData dataWithBytesNoCopy:ciphertext + length:ciphertext_length + freeWhenDone:YES] + key:signalingKeyAESKeyMaterial + IV:[NSData dataWithBytes:iv length:16] + version:[NSData dataWithBytes:version length:1] + HMACKey:signalingKeyHMACKeyMaterial + HMACType:TSHMACSHA256Truncated10Bytes + matchingHMAC:[NSData dataWithBytes:mac length:10]]; } @@ -221,7 +239,7 @@ NSData *iv = [dataToDecrypt subdataWithRange:NSMakeRange(0, 10)]; NSData *encryptedAttachment = [dataToDecrypt subdataWithRange:NSMakeRange(10, [dataToDecrypt length]-10-10)]; NSData *hmac = [dataToDecrypt subdataWithRange:NSMakeRange([dataToDecrypt length]-10, 10)]; - return [Cryptography decryptCBCMode:encryptedAttachment withKey:encryptionKey withIV:iv withVersion:nil withHMACKey:hmacKey withHMACType:TSHMACSHA256Truncated10Bytes forHMAC:hmac]; + return [Cryptography decryptCBCMode:encryptedAttachment key:encryptionKey IV:iv version:nil HMACKey:hmacKey HMACType:TSHMACSHA256Truncated10Bytes matchingHMAC:hmac]; } diff --git a/Signal/src/view controllers/ActionContactDetailCell.m b/Signal/src/view controllers/ActionContactDetailCell.m index 23061e40d3..00f78ecdcc 100644 --- a/Signal/src/view controllers/ActionContactDetailCell.m +++ b/Signal/src/view controllers/ActionContactDetailCell.m @@ -9,6 +9,7 @@ #import "DJWActionSheet.h" #import "ActionContactDetailCell.h" + @implementation ActionContactDetailCell - (void)awakeFromNib { @@ -22,7 +23,15 @@ } - +-(IBAction)messageButtonTapped:(id)sender +{ + NSLog(@"%s", __PRETTY_FUNCTION__); +} + +-(IBAction)callButtonTapped:(id)sender +{ + NSLog(@"%s", __PRETTY_FUNCTION__); +} @end diff --git a/Signal/src/view controllers/CodeVerificationViewController.m b/Signal/src/view controllers/CodeVerificationViewController.m index 768b85adef..e618535a9d 100644 --- a/Signal/src/view controllers/CodeVerificationViewController.m +++ b/Signal/src/view controllers/CodeVerificationViewController.m @@ -40,14 +40,16 @@ [self registerWithSuccess:^{ [self performSegueWithIdentifier:@"verifiedSegue" sender:self]; - } failure:^{ + } failure:^(NSError *error) { // TODO: Unlock UI NSLog(@"Failed to register"); + + [self showAlertForError:error]; }]; } -- (void)registerWithSuccess:(void(^)())success failure:(void(^)())failure{ +- (void)registerWithSuccess:(void(^)())success failure:(void(^)(NSError *))failure{ //TODO: Refactor this to use futures? Better error handling needed. Good enough for PoC [[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall verifyVerificationCode:_challengeTextField.text] success:^(NSURLSessionDataTask *task, id responseObject) { @@ -56,29 +58,68 @@ [TSAccountManager registerWithRedPhoneToken:signupToken pushToken:pushToken success:^{ success(); - } failure:^(TSRegistrationFailure failureType) { - failure(); + } failure:^(NSError *error) { + failure(error); }]; - } failure:^{ - failure(); + // PushManager shows its own error alerts, so we don't want to show a second one + failure(nil); }]; } failure:^(NSURLSessionDataTask *task, NSError *error) { - NSString *alertTitle = NSLocalizedString(@"REGISTRATION_ERROR", @""); - NSHTTPURLResponse* badResponse = (NSHTTPURLResponse*)task.response; - if (badResponse.statusCode == 401) { - SignalAlertView(alertTitle, REGISTER_CHALLENGE_ALERT_VIEW_BODY); - } else if (badResponse.statusCode == 413){ - SignalAlertView(alertTitle, NSLocalizedString(@"REGISTER_RATE_LIMITING_BODY", @"")); - } else { - NSString *alertBodyString = [NSString stringWithFormat:@"%@ %lu", NSLocalizedString(@"SERVER_CODE", @""),(unsigned long)badResponse.statusCode]; - SignalAlertView (alertTitle, alertBodyString); - } + NSError *responseError = [self errorForResponse:badResponse]; + + failure(responseError); }]; } +// TODO: If useful, this could possibly go in a less-specific class +- (void)showAlertForError:(NSError *)error { + + if (error == nil) { + NSLog(@"%@: Error condition, but no NSError to display", self.class); + return; + } else if (error.localizedDescription.length == 0) { + NSLog(@"%@: Unable to display error because localizedDescription was not set: %@", self.class, error); + return; + } + + NSString *alertBody = nil; + if (error.localizedFailureReason.length > 0) { + alertBody = error.localizedFailureReason; + } else if (error.localizedRecoverySuggestion.length > 0) { + alertBody = error.localizedRecoverySuggestion; + } + + SignalAlertView(error.localizedDescription, alertBody); +} + + +- (NSError *)errorForResponse:(NSHTTPURLResponse *)badResponse { + + NSString *description = NSLocalizedString(@"REGISTRATION_ERROR", @""); + NSString *failureReason = nil; + TSRegistrationFailure failureType; + + if (badResponse.statusCode == 401) { + failureReason = REGISTER_CHALLENGE_ALERT_VIEW_BODY; + failureType = kTSRegistrationFailureAuthentication; + } else if (badResponse.statusCode == 413){ + failureReason = NSLocalizedString(@"REGISTER_RATE_LIMITING_BODY", @""); + failureType = kTSRegistrationFailureRateLimit; + } else { + failureReason = [NSString stringWithFormat:@"%@ %lu", NSLocalizedString(@"SERVER_CODE", @""),(unsigned long)badResponse.statusCode]; + failureType = kTSRegistrationFailureNetwork; + } + + NSDictionary *userInfo = @{NSLocalizedDescriptionKey: description, NSLocalizedFailureReasonErrorKey: failureReason}; + NSError *error = [NSError errorWithDomain:TSRegistrationErrorDomain code:failureType userInfo:userInfo]; + + return error; +} + + #pragma mark - Keyboard notifications - (void)initializeKeyboardHandlers{ diff --git a/Signal/src/view controllers/ContactDetailCell.h b/Signal/src/view controllers/ContactDetailCell.h index ce77b359a3..77a09547b3 100644 --- a/Signal/src/view controllers/ContactDetailCell.h +++ b/Signal/src/view controllers/ContactDetailCell.h @@ -19,5 +19,8 @@ @property (strong, nonatomic) IBOutlet UILabel *contactPhoneNumber; @property (strong, nonatomic) IBOutlet UITextView *contactNotesTextView; +@property(nonatomic, strong) IBOutlet UILabel* contactAnnexNumberLabel; +@property(nonatomic, strong) IBOutlet UILabel* contactEmailLabel; + @end diff --git a/Signal/src/view controllers/ContactDetailTableViewController.m b/Signal/src/view controllers/ContactDetailTableViewController.m index 5b66e06d32..b14698e3a2 100644 --- a/Signal/src/view controllers/ContactDetailTableViewController.m +++ b/Signal/src/view controllers/ContactDetailTableViewController.m @@ -12,18 +12,23 @@ #import "UIUtil.h" #import "DJWActionSheet.h" +#define kImageRadius 50.0f +#define kMinRows 4 +#define kFirstAdaptableCellRow 2 -typedef enum { - kNameMainNumberCellIndexPath = 0, - kActionCellIndexPath = 1, - kShareCellIndexPath = 2, - kEmailCellIndexPath = 3, - kAnnexPhoneNumberCellIndexPath = 4, - kNotesCellIndexPath = 5, -} kCellIndexPath; + +typedef NS_ENUM(NSInteger, CellRow) { + kNameMainNumberCellIndexPath, + kActionCellIndexPath, + kShareCellIndexPath, + kEmailCellIndexPath, + kAnnexPhoneNumberCellIndexPath, + kNotesCellIndexPath, +}; typedef enum { kNameMainNumberCellHeight = 180, + kNoImageCellHeight = 87, kActionCellHeight = 60, kShareCellHeight = 60, kEmailCellHeight = 60, @@ -31,29 +36,26 @@ typedef enum { kNotesCellHeight = 165, } kCellHeight; -static NSString* const kNameMainNumberCell = @"NameMainNumberCell"; -static NSString* const kActionCell = @"ActionCell"; +static NSString* const kNameMainNumberCell = @"NameMainNumberCell"; +static NSString* const kActionCell = @"ActionCell"; +static NSString* const kShareCell = @"ShareCell"; +static NSString* const kEmailCell = @"EmailCell"; +static NSString* const kAnnexPhoneNumberCell = @"AnnexPhoneNumberCell"; +static NSString *const kNotesCell = @"NotesCell"; -//Deprecated -static NSString* const kShareCell = @"ShareCell"; -static NSString* const kEmailCell = @"EmailCell"; -static NSString* const kAnnexPhoneNumberCell = @"AnnexPhoneNumberCell"; -static NSString *const kNotesCell = @"NotesCell"; -// - -static NSString *const kContactDetailSegue = @"DetailSegue"; - - - -@interface ContactDetailTableViewController () +static NSString *const kContactDetailSegue = @"DetailSegue"; +@interface ContactDetailTableViewController () { + BOOL doesImageExist; + NSInteger numberOfRows; +} @end @implementation ContactDetailTableViewController - (void)viewDidLoad { [super viewDidLoad]; - + doesImageExist = YES; self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero]; } @@ -61,6 +63,7 @@ static NSString *const kContactDetailSegue = @"DetailSegue"; [super didReceiveMemoryWarning]; } + #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -68,13 +71,13 @@ static NSString *const kContactDetailSegue = @"DetailSegue"; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 6; + return (NSInteger)[self numberOfRowsForContact:_contact]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell * cell; - + switch (indexPath.row) { case kNameMainNumberCellIndexPath: cell = (ContactDetailCell*)[tableView dequeueReusableCellWithIdentifier:kNameMainNumberCell forIndexPath:indexPath]; @@ -86,48 +89,44 @@ static NSString *const kContactDetailSegue = @"DetailSegue"; case kShareCellIndexPath: cell = [tableView dequeueReusableCellWithIdentifier:kShareCell forIndexPath:indexPath]; break; - case kEmailCellIndexPath: - cell = [tableView dequeueReusableCellWithIdentifier:kEmailCell forIndexPath:indexPath]; - break; - case kAnnexPhoneNumberCellIndexPath: - cell = [tableView dequeueReusableCellWithIdentifier:kAnnexPhoneNumberCell forIndexPath:indexPath]; - break; - case kNotesCellIndexPath: - cell = [tableView dequeueReusableCellWithIdentifier:kNotesCell forIndexPath:indexPath]; - break; - default: + cell = [self adaptableCellAtIndexPath:indexPath]; break; } + return cell; } + -(void)setUpNameMainUserCell:(ContactDetailCell*)cell { Contact* c = self.contact; cell.contactName.text = [c fullName]; - cell.contactPhoneNumber.text = [[c parsedPhoneNumbers] firstObject]; + cell.contactPhoneNumber.text = [[c userTextPhoneNumbers] firstObject]; if (c.image) { cell.contactImageView.image = c.image; + } else { + [cell.contactImageView addConstraint:[NSLayoutConstraint constraintWithItem:cell.contactImageView attribute:NSLayoutAttributeHeight relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:0]]; + doesImageExist = NO; + } - [cell.contactImageView.layer setCornerRadius:50.0f]; + [cell.contactImageView.layer setCornerRadius:kImageRadius]; [cell.contactImageView.layer setMasksToBounds:YES]; - - } + -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat cellHeight = 44.0f; switch (indexPath.row) { case kNameMainNumberCellIndexPath: - cellHeight = kNameMainNumberCellHeight; + cellHeight = doesImageExist ? kNameMainNumberCellHeight : kNoImageCellHeight; break; case kActionCellIndexPath: cellHeight = kActionCellHeight; @@ -135,16 +134,8 @@ static NSString *const kContactDetailSegue = @"DetailSegue"; case kShareCellIndexPath: cellHeight = kShareCellHeight; break; - case kEmailCellIndexPath: - cellHeight = kEmailCellHeight; - break; - case kAnnexPhoneNumberCellIndexPath: - cellHeight = kAnnexPhoneNumberCellHeight; - break; - case kNotesCellIndexPath: - cellHeight = kNotesCellHeight; - break; default: + cellHeight = [self heightForAdaptableCellAtIndexPath:indexPath]; break; } return cellHeight; @@ -176,4 +167,85 @@ static NSString *const kContactDetailSegue = @"DetailSegue"; } } +#pragma mark - Utilities (Adaptable Cells) + +-(NSUInteger)numberOfRowsForContact:(Contact*)contact +{ + NSUInteger numEmails = contact.emails.count; + NSUInteger numPhoneNumbers = contact.userTextPhoneNumbers.count-1; //Don't count main + + return kMinRows + numEmails + numPhoneNumbers; +} + +-(UITableViewCell*)adaptableCellAtIndexPath:(NSIndexPath*)idx +{ + NSInteger emailUpperBound = (NSInteger)(kFirstAdaptableCellRow+_contact.emails.count); + NSInteger phoneNumberUpperBound = emailUpperBound + (NSInteger)_contact.userTextPhoneNumbers.count; + + + ContactDetailCell * cell; + + if (idx.row > kFirstAdaptableCellRow && idx.row <= emailUpperBound) + { + cell = [self.tableView dequeueReusableCellWithIdentifier:kEmailCell forIndexPath:idx]; + + cell.contactEmailLabel.text = [_contact.emails objectAtIndex:(NSUInteger)idx.row-_contact.emails.count]; + + return cell; + } + + else if (idx.row > emailUpperBound && idx.row < phoneNumberUpperBound) + { + cell = [self.tableView dequeueReusableCellWithIdentifier:kAnnexPhoneNumberCell forIndexPath:idx]; + + NSInteger i = idx.row - emailUpperBound ; + + cell.contactAnnexNumberLabel.text = [_contact.userTextPhoneNumbers objectAtIndex:(NSUInteger)i]; + + return cell; + } + + else if (idx.row == (NSInteger)[self numberOfRowsForContact:_contact]-1) + { + return [self.tableView dequeueReusableCellWithIdentifier:kNotesCell forIndexPath:idx]; + + } + + else + { + NSLog(@"%s Problem at IndexPath %@", __PRETTY_FUNCTION__, idx); + return nil; + } +} + +-(CGFloat)heightForAdaptableCellAtIndexPath:(NSIndexPath*)idx +{ + NSInteger emailUpperBound = (NSInteger)(kFirstAdaptableCellRow+_contact.emails.count); + NSInteger phoneNumberUpperBound = emailUpperBound + (NSInteger)_contact.userTextPhoneNumbers.count; + + if (idx.row > kFirstAdaptableCellRow && idx.row <= emailUpperBound) + { + return kEmailCellHeight; + } + + else if (idx.row > emailUpperBound && idx.row < phoneNumberUpperBound) + { + return kAnnexPhoneNumberCellHeight; + } + + else if (idx.row == (NSInteger)[self numberOfRowsForContact:_contact]-1) + { + return kNotesCellHeight; + + } + + else + { + NSLog(@"%s Problem at IndexPath %@", __PRETTY_FUNCTION__, idx); + return 44.0f; + } + +} + + @end diff --git a/Signal/src/view controllers/ContactsTableViewController.m b/Signal/src/view controllers/ContactsTableViewController.m index d9baf3247d..0100cbeff0 100644 --- a/Signal/src/view controllers/ContactsTableViewController.m +++ b/Signal/src/view controllers/ContactsTableViewController.m @@ -121,7 +121,7 @@ static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableView #pragma mark - Contact functions - (void)setupContacts { - ObservableValue *observableContacts = Environment.getCurrent.contactsManager.getObservableWhisperUsers; + ObservableValue *observableContacts = Environment.getCurrent.contactsManager.getObservableRedPhoneUsers; [observableContacts watchLatestValue:^(NSArray *latestContacts) { _latestContacts = latestContacts; [self onSearchOrContactChange:nil]; @@ -219,6 +219,8 @@ static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableView reuseIdentifier:CONTACT_BROWSE_TABLE_CELL_IDENTIFIER]; } + cell.shouldShowContactButtons = YES; + [cell configureWithContact:[self contactForIndexPath:indexPath]]; return cell; @@ -265,6 +267,7 @@ static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableView NSArray *contactSection = [self contactsForSectionIndex:(NSUInteger)indexPath.section]; contact = contactSection[(NSUInteger)indexPath.row]; } + detailvc.contact = contact; } } diff --git a/Signal/src/view controllers/DemoDataModel.m b/Signal/src/view controllers/DemoDataModel.m index 452f564aec..44e26d92b4 100644 --- a/Signal/src/view controllers/DemoDataModel.m +++ b/Signal/src/view controllers/DemoDataModel.m @@ -11,6 +11,8 @@ #import "RecentCall.h" #import "PhoneNumber.h" +#import "JSQCall.h" + enum {kDemoDataModelCase0, kDemoDataModelCase1,kDemoDataModelCase2, kDemoDataModelCase3, kDemoDataModelCase4}; @implementation DemoDataModel @@ -38,30 +40,46 @@ enum {kDemoDataModelCase0, kDemoDataModelCase1,kDemoDataModelCase2, kDemoDataMod * You should have a mutable array or orderedSet, or something. */ self.messages = [[NSMutableArray alloc] initWithObjects: - [[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan + [[JSQMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan senderDisplayName:kJSQDemoAvatarDisplayNameDylan date:[NSDate distantPast] text:@"Welcome to JSQMessages: A messaging UI framework for iOS."], - [[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan + [[JSQMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan senderDisplayName:kJSQDemoAvatarDisplayNameDylan date:[NSDate distantPast] text:@"It even has data detectors. You can call me tonight. My cell number is 123-456-7890. My website is www.hexedbits.com."], - [[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdMoxie + [[JSQMessage alloc] initWithSenderId:kJSQDemoAvatarIdMoxie senderDisplayName:kJSQDemoAvatarDisplayNameMoxie date:[NSDate date] text:@"JSQMessagesViewController is nearly an exact replica of the iOS Messages App. And perhaps, better."], - [[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdFred + [[JSQMessage alloc] initWithSenderId:kJSQDemoAvatarIdFred senderDisplayName:kJSQDemoAvatarDisplayNameFred date:[NSDate date] text:@"It is unit-tested, free, open-source, and documented."], - [[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan + [[JSQMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan senderDisplayName:kJSQDemoAvatarDisplayNameDylan date:[NSDate date] text:@"Now with media messages!"], + [[JSQCall alloc] initWithCallerId:kJSQDemoAvatarIdMoxie + callerDisplayName:kJSQDemoAvatarDisplayNameMoxie + date:[NSDate date] + duration:127 + status:kCallIncoming], + [[JSQCall alloc] initWithCallerId:kJSQDemoAvatarIdFred + callerDisplayName:kJSQDemoAvatarDisplayNameFred + date:[NSDate date] + duration:0 + status:kCallMissed], + [[JSQCall alloc] initWithCallerId:kJSQDemoAvatarIdFred + callerDisplayName:kJSQDemoAvatarDisplayNameFred + date:[NSDate date] + duration:0 + status:kCallFailed], + nil]; } @@ -109,35 +127,6 @@ enum {kDemoDataModelCase0, kDemoDataModelCase1,kDemoDataModelCase2, kDemoDataMod { Contact * _demoContact; - switch (modelNumber) { - case kDemoDataModelCase0: - _demoContact = [Contact contactWithFirstName:@"Dylan" andLastName:@"Bourgeois" andUserTextPhoneNumbers:@[@"954-736-9230"] andEmails:nil andContactID:0]; - _demoContact.isRedPhoneContact = YES; - _demoContact.isTextSecureContact = YES; - break; - case kDemoDataModelCase1: - _demoContact = [Contact contactWithFirstName:@"Frederic" andLastName:@"Jacobs" andUserTextPhoneNumbers:@[@"954-736-9231"] andEmails:nil andContactID:0]; - _demoContact.isRedPhoneContact = YES; - _demoContact.isTextSecureContact = NO; - break; - case kDemoDataModelCase2: - _demoContact = [Contact contactWithFirstName:@"Romain" andLastName:@"Ruetschi" andUserTextPhoneNumbers:@[@"954-736-9233"] andEmails:nil andContactID:0]; - _demoContact.isRedPhoneContact = NO; - _demoContact.isTextSecureContact = NO; - break; - case kDemoDataModelCase3: - _demoContact = [Contact contactWithFirstName:@"Stephen" andLastName:@"Colbert" andUserTextPhoneNumbers:@[@"954-736-9232"] andEmails:nil andContactID:0]; - _demoContact.isRedPhoneContact = NO; - _demoContact.isTextSecureContact = YES; - break; - case kDemoDataModelCase4: - _demoContact = [Contact contactWithFirstName:@"Johnny" andLastName:@"Ramone" andUserTextPhoneNumbers:@[@"954-736-9221"] andEmails:nil andContactID:0]; - _demoContact.isRedPhoneContact = YES; - _demoContact.isTextSecureContact = YES; - break; - default: - break; - } return _demoContact; } diff --git a/Signal/src/view controllers/DialerViewController.m b/Signal/src/view controllers/DialerViewController.m index 26396af919..c3fbeee0d4 100644 --- a/Signal/src/view controllers/DialerViewController.m +++ b/Signal/src/view controllers/DialerViewController.m @@ -34,19 +34,13 @@ [self setupPasteBehaviour]; self.title = KEYPAD_NAV_BAR_TITLE; _currentNumberMutable = [NSMutableString string]; - //[self updateNumberLabel]; + [self updateNumberLabel]; [self.navigationController setNavigationBarHidden:YES animated:NO]; [_callButton setTitle:CALL_BUTTON_TITLE forState:UIControlStateNormal]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - UIBlurEffect * effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; - UIVisualEffectView * viewWithBlurredBackground = - [[UIVisualEffectView alloc] initWithEffect:effect]; - viewWithBlurredBackground.frame = self.view.frame; - - [self.view insertSubview:viewWithBlurredBackground atIndex:0]; if (_phoneNumber) { _currentNumberMutable = _phoneNumber.toE164.mutableCopy; @@ -154,7 +148,6 @@ } - (void)updateNumberLabel { - //DEBUG!!! NSString* numberText = [_currentNumberMutable copy]; _numberLabel.text = [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:numberText]; diff --git a/Signal/src/view controllers/FingerprintViewController.m b/Signal/src/view controllers/FingerprintViewController.m index 2d9dc83e83..21407d1239 100644 --- a/Signal/src/view controllers/FingerprintViewController.m +++ b/Signal/src/view controllers/FingerprintViewController.m @@ -18,11 +18,20 @@ - (void)viewDidLoad { [super viewDidLoad]; - + + [self.view setAlpha:0]; + [self initializeImageViews]; } +-(void)viewWillAppear:(BOOL)animated +{ + [UIView animateWithDuration:0.6 delay:0. options:UIViewAnimationOptionCurveEaseInOut animations:^{ + [self.view setAlpha:1]; + } completion:nil]; +} + - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. @@ -31,13 +40,13 @@ #pragma mark - Initializers -(void)initializeImageViews { - _contactImageView.image = [UIImage imageNamed:@"DefaultContactImage"]; + _contactImageView.image = [UIImage imageNamed:@"defaultConctact_light"]; _contactImageView.layer.cornerRadius = 75.f/2; _contactImageView.layer.masksToBounds = YES; _contactImageView.layer.borderWidth = 2.0f; _contactImageView.layer.borderColor = [[UIColor whiteColor] CGColor]; - _userImageView.image = [UIImage imageNamed:@"DefaultContactImage"]; + _userImageView.image = [UIImage imageNamed:@"defaultConctact_light"]; _userImageView.layer.cornerRadius = 75.f/2; _userImageView.layer.masksToBounds = YES; _userImageView.layer.borderWidth = 2.0f; @@ -47,7 +56,12 @@ #pragma mark - Action -(IBAction)closeButtonAction:(id)sender { - [self dismissViewControllerAnimated:YES completion:nil]; + [UIView animateWithDuration:0.6 delay:0. options:UIViewAnimationOptionCurveEaseInOut animations:^{ + [self.view setAlpha:0]; + } completion:^(BOOL succeeded){ + [self dismissViewControllerAnimated:YES completion:nil]; + }]; + } -(IBAction)shredAndDelete:(id)sender diff --git a/Signal/src/view controllers/FullImageViewController.m b/Signal/src/view controllers/FullImageViewController.m index 3a83ae65c4..36e169b960 100644 --- a/Signal/src/view controllers/FullImageViewController.m +++ b/Signal/src/view controllers/FullImageViewController.m @@ -38,8 +38,8 @@ [_pinchView addGestureRecognizer:doubleTap]; _pinchView.delegate = self; - _pinchView.minimumZoomScale=0.9; - _pinchView.maximumZoomScale=3.0; + _pinchView.minimumZoomScale=0.9f; + _pinchView.maximumZoomScale=3.0f; _pinchView.showsVerticalScrollIndicator = NO; _pinchView.showsHorizontalScrollIndicator = NO; _pinchView.contentSize=CGSizeMake(CGRectGetWidth(_fullImageView.frame), CGRectGetHeight(_fullImageView.frame)); diff --git a/Signal/src/view controllers/InCallViewController.h b/Signal/src/view controllers/InCallViewController.h index 5e749cba3c..7ad6178414 100644 --- a/Signal/src/view controllers/InCallViewController.h +++ b/Signal/src/view controllers/InCallViewController.h @@ -17,12 +17,17 @@ @property (nonatomic, strong) IBOutlet UIView *callStateImageContainerView; @property (nonatomic, strong) IBOutlet UIButton *muteButton; +@property (nonatomic, strong) IBOutlet UILabel* muteLabel; @property (nonatomic, strong) IBOutlet UIButton *speakerButton; +@property (nonatomic, strong) IBOutlet UILabel* speakerLabel; @property (nonatomic, strong) IBOutlet UIButton *answerButton; +@property (nonatomic, strong) IBOutlet UILabel *answerLabel; @property (nonatomic, strong) IBOutlet UIButton *rejectButton; +@property (nonatomic, strong) IBOutlet UILabel *rejectLabel; @property (nonatomic, strong) IBOutlet UIButton *endButton; +@property (nonatomic, strong) IBOutlet UILabel *endLabel; @property (nonatomic, readonly) CallState *callState; @property (nonatomic, readonly) Contact *potentiallyKnownContact; diff --git a/Signal/src/view controllers/InCallViewController.m b/Signal/src/view controllers/InCallViewController.m index 97e1b288b9..be54cfd461 100644 --- a/Signal/src/view controllers/InCallViewController.m +++ b/Signal/src/view controllers/InCallViewController.m @@ -52,9 +52,17 @@ static NSInteger connectingFlashCounter = 0; [self showCallState]; [self setupButtonBorders]; [self localizeButtons]; + [self linkActions]; + [UIDevice.currentDevice setProximityMonitoringEnabled:YES]; } +-(void)linkActions +{ + [_muteButton addTarget:self action:@selector(muteButtonTapped) forControlEvents:UIControlEventTouchUpInside]; + [_speakerButton addTarget:self action:@selector(speakerButtonTapped) forControlEvents:UIControlEventTouchUpInside]; +} + - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self startConnectingFlashAnimation]; @@ -245,14 +253,23 @@ static NSInteger connectingFlashCounter = 0; - (void)muteButtonTapped { _muteButton.selected = [Environment.phoneManager toggleMute]; - NSString* newImageName = _muteButton.selected ? @"mute_on" : @"mute_off"; - [_muteButton.imageView setImage:[UIImage imageNamed:newImageName]]; + if (_muteButton.isSelected) + { + _muteLabel.text = @"Mute On"; + } else { + _muteLabel.text = @"Mute Off"; + } } - (void)speakerButtonTapped { _speakerButton.selected = [AppAudioManager.sharedInstance toggleSpeakerPhone]; - NSString* newImageName = _speakerButton.selected ? @"speaker_on" : @"speaker_off"; - [_speakerButton.imageView setImage:[UIImage imageNamed:newImageName]]; + + if (_speakerButton.isSelected) + { + _speakerLabel.text = @"Speaker On"; + } else { + _speakerLabel.text = @"Speaker Off"; + } } - (void)answerButtonTapped { @@ -274,7 +291,6 @@ static NSInteger connectingFlashCounter = 0; message = [message stringByAppendingString:[serverMessage text]]; } - _endButton.backgroundColor = [UIColor grayColor]; _callStatusLabel.textColor = [UIColor redColor]; [self showConnectingError]; @@ -297,11 +313,14 @@ static NSInteger connectingFlashCounter = 0; -(void) displayAcceptRejectButtons:(BOOL) enable{ - //TODO: if NO, animate reject button -> end call button - _answerButton.hidden = !enable; _rejectButton.hidden = !enable; - _endButton.hidden = enable; + _endButton.hidden = enable; + + _answerLabel.hidden = !enable; + _rejectLabel.hidden = !enable; + _endLabel.hidden = enable; + if (_vibrateTimer && enable == false) { [_vibrateTimer invalidate]; } diff --git a/Signal/src/view controllers/InboxTableViewCell.h b/Signal/src/view controllers/InboxTableViewCell.h index 2a20f8e615..569d716466 100644 --- a/Signal/src/view controllers/InboxTableViewCell.h +++ b/Signal/src/view controllers/InboxTableViewCell.h @@ -9,6 +9,7 @@ #import #import "DemoDataModel.h" #import "NextResponderScrollView.h" +#import "TSThread.h" typedef enum : NSUInteger { kArchiveState, @@ -41,7 +42,7 @@ typedef enum : NSUInteger { @property (nonatomic, strong) IBOutlet UIImageView *archiveImageView; @property (nonatomic, assign) id delegate; --(void)configureWithTestMessage:(DemoDataModel*)testMessage; +-(void)configureWithThread:(TSThread*)thread; -(void)configureForState:(CellState)state; -(void)animateDisappear; diff --git a/Signal/src/view controllers/InboxTableViewCell.m b/Signal/src/view controllers/InboxTableViewCell.m index 0881be1255..abbeae48a1 100644 --- a/Signal/src/view controllers/InboxTableViewCell.m +++ b/Signal/src/view controllers/InboxTableViewCell.m @@ -41,15 +41,14 @@ return NSStringFromClass(self.class); } --(void)configureWithTestMessage:(DemoDataModel*)testMessage { - _nameLabel.text = testMessage._sender; - _snippetLabel.text = testMessage._snippet; +-(void)configureWithThread:(TSThread*)thread { + _nameLabel.text = thread.name; + _snippetLabel.text = @"Missing implementation"; _contactPictureView.image = nil; - _timeLabel.attributedText = [self dateArrributedString:[NSDate date]]; + _timeLabel.attributedText = [self dateAttributedString:thread.lastMessageDate]; self.separatorInset = UIEdgeInsetsMake(0,_contactPictureView.frame.size.width*1.5f, 0, 0); - [self setUpLastAction:testMessage.lastActionString]; - + [self setUpLastAction:@"read"]; // TODO: Change } -(void)configureForState:(CellState)state @@ -89,7 +88,7 @@ #pragma mark - Date formatting -- (NSAttributedString *)dateArrributedString:(NSDate *)date { +- (NSAttributedString *)dateAttributedString:(NSDate *)date { NSString *timeString = [[DateUtil timeFormatter] stringFromDate:date]; diff --git a/Signal/src/view controllers/InboxTableViewCell.xib b/Signal/src/view controllers/InboxTableViewCell.xib index 4880c67a70..6fcada75e3 100644 --- a/Signal/src/view controllers/InboxTableViewCell.xib +++ b/Signal/src/view controllers/InboxTableViewCell.xib @@ -1,5 +1,5 @@ - + @@ -7,7 +7,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -91,7 +91,7 @@ - + diff --git a/Signal/src/view controllers/MessageComposeTableViewController.m b/Signal/src/view controllers/MessageComposeTableViewController.m index 0747945f32..6ac5b9858d 100644 --- a/Signal/src/view controllers/MessageComposeTableViewController.m +++ b/Signal/src/view controllers/MessageComposeTableViewController.m @@ -6,6 +6,8 @@ // // +#import "Environment.h" +#import "Contact.h" #import "MessageComposeTableViewController.h" #import "MessagesViewController.h" #import "SignalsViewController.h" @@ -24,14 +26,12 @@ @implementation MessageComposeTableViewController - - - (void)viewDidLoad { [super viewDidLoad]; [self initializeSearch]; - contacts = [DemoDataFactory makeFakeContacts]; + contacts = [[Environment getCurrent] contactsManager].textSecureContacts; searchResults = contacts; self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero]; @@ -104,7 +104,6 @@ } else { return (NSInteger)[contacts count]; } - } @@ -115,6 +114,8 @@ cell = [[ContactTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ContactTableViewCell"]; } + cell.shouldShowContactButtons = NO; + [cell configureWithContact:[self contactForIndexPath:indexPath]]; tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; @@ -180,4 +181,5 @@ } + @end diff --git a/Signal/src/view controllers/MessagesViewController.h b/Signal/src/view controllers/MessagesViewController.h index 09fae497e5..3c73dea423 100644 --- a/Signal/src/view controllers/MessagesViewController.h +++ b/Signal/src/view controllers/MessagesViewController.h @@ -11,13 +11,14 @@ #import "DemoDataModel.h" +@class TSThread; @interface MessagesViewController : JSQMessagesViewController -@property (strong, nonatomic) DemoDataModel *demoData; -@property (strong, nonatomic) NSString* _senderTitleString; +@property (strong, nonatomic) NSString* senderTitleString; +@property DemoDataModel *demoData; --(void)initWithGroup:(NSArray*)group; +- (void)setupWithThread:(TSThread*)thread; @end diff --git a/Signal/src/view controllers/MessagesViewController.m b/Signal/src/view controllers/MessagesViewController.m index 4163496f00..8405e32f0e 100644 --- a/Signal/src/view controllers/MessagesViewController.m +++ b/Signal/src/view controllers/MessagesViewController.m @@ -11,6 +11,9 @@ #import "MessagesViewController.h" #import "FullImageViewController.h" +#import "JSQCallCollectionViewCell.h" +#import "JSQCall.h" + #import "DJWActionSheet.h" #import #import @@ -37,11 +40,14 @@ typedef enum : NSUInteger { self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"lock.png"] style:UIBarButtonItemStylePlain target:self action:@selector(showFingerprint)]; [self.collectionView.collectionViewLayout setMessageBubbleFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:16.0f]]; + + self.collectionView.showsVerticalScrollIndicator = NO; + self.collectionView.showsHorizontalScrollIndicator = NO; //DEBUG: isGroupConversation = NO; - self.title = self._senderTitleString; + self.title = self.senderTitleString; self.senderId = kJSQDemoAvatarIdDylan; self.senderDisplayName = kJSQDemoAvatarDisplayNameDylan; @@ -131,7 +137,7 @@ typedef enum : NSUInteger { } else if (text.length > 0) { [JSQSystemSoundPlayer jsq_playMessageSentSound]; - JSQTextMessage *message = [[JSQTextMessage alloc] initWithSenderId:senderId + JSQMessage *message = [[JSQMessage alloc] initWithSenderId:senderId senderDisplayName:senderDisplayName date:date text:text]; @@ -235,25 +241,29 @@ typedef enum : NSUInteger { /** * Override point for customizing cells */ - JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath]; - - JSQMessage *msg = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item]; - if ([msg isKindOfClass:[JSQTextMessage class]]) { - - if ([msg.senderId isEqualToString:self.senderId]) { - cell.textView.textColor = [UIColor whiteColor]; - } - else { - cell.textView.textColor = [UIColor blackColor]; + if ([msg isKindOfClass:[JSQMessage class]]) + { + JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath]; + if (!msg.isMediaMessage) { + if ([msg.senderId isEqualToString:self.senderId]) { + cell.textView.textColor = [UIColor whiteColor]; + } + else { + cell.textView.textColor = [UIColor blackColor]; + } + + cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor, + NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) }; } - cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor, - NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) }; + return cell; + + } else { + JSQCallCollectionViewCell *cell = (JSQCallCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath]; + return cell; } - - return cell; } #pragma mark - Adjusting cell label heights @@ -447,10 +457,10 @@ typedef enum : NSUInteger { NSError *err = NULL; CMTime time = CMTimeMake(2, 1); CGImageRef snapshotRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err]; - UIImage *snapshot = [[UIImage alloc] initWithCGImage:snapshotRef]; + __unused UIImage *snapshot = [[UIImage alloc] initWithCGImage:snapshotRef]; JSQVideoMediaItem * videoItem = [[JSQVideoMediaItem alloc] initWithFileURL:videoURL isReadyToPlay:YES]; - JSQMediaMessage * videoMessage = [JSQMediaMessage messageWithSenderId:kJSQDemoAvatarIdDylan + JSQMessage * videoMessage = [JSQMessage messageWithSenderId:kJSQDemoAvatarIdDylan displayName:kJSQDemoAvatarDisplayNameDylan media:videoItem]; [self.demoData.messages addObject:videoMessage]; @@ -460,7 +470,7 @@ typedef enum : NSUInteger { //Is a photo JSQPhotoMediaItem *photoItem = [[JSQPhotoMediaItem alloc] initWithImage:picture_camera]; - JSQMediaMessage *photoMessage = [JSQMediaMessage messageWithSenderId:kJSQDemoAvatarIdDylan + JSQMessage *photoMessage = [JSQMessage messageWithSenderId:kJSQDemoAvatarIdDylan displayName:kJSQDemoAvatarDisplayNameDylan media:photoItem]; [self.demoData.messages addObject:photoMessage]; diff --git a/Signal/src/view controllers/NewGroupViewController.m b/Signal/src/view controllers/NewGroupViewController.m index 77a73d992a..e28f88364b 100644 --- a/Signal/src/view controllers/NewGroupViewController.m +++ b/Signal/src/view controllers/NewGroupViewController.m @@ -8,6 +8,9 @@ #import "NewGroupViewController.h" #import "SignalsViewController.h" +#import "Contact.h" +#import "ContactsManager.h" +#import "Environment.h" #import "Contact.h" #import "DemoDataFactory.h" @@ -32,7 +35,7 @@ self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Create" style:UIBarButtonItemStylePlain target:self action:@selector(createGroup)]; self.navigationItem.title = @"New Group"; - contacts = [DemoDataFactory makeFakeContacts]; + contacts = [Environment getCurrent].contactsManager.textSecureContacts; [self initializeDelegates]; [self initializeTableView]; @@ -41,7 +44,6 @@ - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. } #pragma mark - Initializers @@ -135,7 +137,6 @@ picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *)kUTTypeImage, nil]; [self presentViewController:picker animated:YES completion:NULL]; } - } -(void)chooseFromLibrary @@ -202,7 +203,7 @@ NSUInteger row = (NSUInteger)indexPath.row; Contact* contact = contacts[row-1]; - cell.textLabel.text = contact.fullName; + cell.textLabel.attributedText = [self attributedStringForContact:contact inCell:cell]; } else { cell.textLabel.text = @"Add People:"; @@ -236,6 +237,27 @@ return NO; } +#pragma mark - Cell Utility + +- (NSAttributedString *)attributedStringForContact:(Contact *)contact inCell:(UITableViewCell*)cell { + NSMutableAttributedString *fullNameAttributedString = [[NSMutableAttributedString alloc] initWithString:contact.fullName]; + + UIFont *firstNameFont; + UIFont *lastNameFont; + + if (ABPersonGetSortOrdering() == kABPersonCompositeNameFormatFirstNameFirst) { + firstNameFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:cell.textLabel.font.pointSize]; + lastNameFont = [UIFont systemFontOfSize:cell.textLabel.font.pointSize]; + } else{ + firstNameFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:cell.textLabel.font.pointSize]; + lastNameFont = [UIFont systemFontOfSize:cell.textLabel.font.pointSize]; + } + [fullNameAttributedString addAttribute:NSFontAttributeName value:firstNameFont range:NSMakeRange(0, contact.firstName.length)]; + [fullNameAttributedString addAttribute:NSFontAttributeName value:lastNameFont range:NSMakeRange(contact.firstName.length + 1, contact.lastName.length)]; + + [fullNameAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, contact.fullName.length)]; + return fullNameAttributedString; +} /* #pragma mark - Navigation diff --git a/Signal/src/view controllers/SettingsTableViewCell.h b/Signal/src/view controllers/SettingsTableViewCell.h index eae4967418..97dbd91750 100644 --- a/Signal/src/view controllers/SettingsTableViewCell.h +++ b/Signal/src/view controllers/SettingsTableViewCell.h @@ -14,8 +14,5 @@ @property(nonatomic, strong) IBOutlet UISwitch* toggle; @property(nonatomic, strong) IBOutlet UILabel* state; -//Header cell -@property(nonatomic, strong) IBOutlet UIImageView* profileImageView; -@property(nonatomic, strong) IBOutlet UIButton * changeProfileImageViewButton; @end diff --git a/Signal/src/view controllers/SettingsTableViewCell.m b/Signal/src/view controllers/SettingsTableViewCell.m index 923dbf8b18..f00ad29ed2 100644 --- a/Signal/src/view controllers/SettingsTableViewCell.m +++ b/Signal/src/view controllers/SettingsTableViewCell.m @@ -14,11 +14,7 @@ // Initialization code [self.toggle addTarget:self action:@selector(toggleSetting:) forControlEvents:UIControlEventValueChanged]; - - [self.profileImageView.layer setCornerRadius:50.0f]; - [self.profileImageView.layer setMasksToBounds:YES]; - - [self.changeProfileImageViewButton addTarget:self action:@selector(changeImageView:) forControlEvents:UIControlEventTouchUpInside]; + } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { @@ -37,11 +33,5 @@ } } -#pragma mark - Editing Profile --(void)changeImageView:(id)sender -{ - NSLog(@"hi"); - -} @end diff --git a/Signal/src/view controllers/SettingsTableViewController.m b/Signal/src/view controllers/SettingsTableViewController.m index 4aced198b8..70c7a996cd 100644 --- a/Signal/src/view controllers/SettingsTableViewController.m +++ b/Signal/src/view controllers/SettingsTableViewController.m @@ -10,13 +10,13 @@ #import "DJWActionSheet.h" #import "SettingsTableViewCell.h" -#define kProfileCellHeight 180.0f -#define kStandardCellHeight 60.0f +#define kProfileCellHeight 87.0f +#define kStandardCellHeight 60.0f -#define kNumberOfSections 2 +#define kNumberOfSections 2 #define kClearHistoryLogCellRow 4 -#define kSendDebugLogCellRow 6 +#define kSendDebugLogCellRow 6 typedef enum { @@ -114,16 +114,6 @@ typedef enum { break; } } - - else if (indexPath.section==kProfileSection) - { - //FIXME: self is to nil after this call o_x so can't show button - SettingsTableViewCell* profileCell = (SettingsTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath]; - profileCell.changeProfileImageViewButton.hidden = !profileCell.changeProfileImageViewButton.hidden; - profileCell.changeProfileImageViewButton.userInteractionEnabled = !profileCell.changeProfileImageViewButton.userInteractionEnabled; - NSLog(@"hello"); - - } } diff --git a/Signal/src/view controllers/SignalsNavigationController.m b/Signal/src/view controllers/SignalsNavigationController.m index d36d5e375d..c022e568cf 100644 --- a/Signal/src/view controllers/SignalsNavigationController.m +++ b/Signal/src/view controllers/SignalsNavigationController.m @@ -37,6 +37,14 @@ [self.navigationBar addSubview:_socketStatusView]; } +-(void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:SocketOpenedNotification]; + [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:SocketClosedNotification]; + [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:SocketConnectingNotification]; + +} + #pragma mark - Socket Status Notifications -(void)initializeObserver diff --git a/Signal/src/view controllers/UITests/SignalsViewController.h b/Signal/src/view controllers/UITests/SignalsViewController.h index 3676f6de5d..935bc92ae7 100644 --- a/Signal/src/view controllers/UITests/SignalsViewController.h +++ b/Signal/src/view controllers/UITests/SignalsViewController.h @@ -11,15 +11,13 @@ #import "GroupModel.h" - @interface SignalsViewController : UIViewController -@property (nonatomic) Contact* contactFromCompose; -@property (nonatomic) GroupModel* groupFromCompose; +@property (nonatomic) Contact *contactFromCompose; +@property (nonatomic) GroupModel *groupFromCompose; -@property (nonatomic,strong) IBOutlet UITableView* _tableView; - -@property (strong, nonatomic) IBOutlet UISegmentedControl * segmentedControl; +@property (nonatomic, retain) IBOutlet UITableView *tableView; +@property (nonatomic, retain) IBOutlet UISegmentedControl *segmentedControl; @end diff --git a/Signal/src/view controllers/UITests/SignalsViewController.m b/Signal/src/view controllers/UITests/SignalsViewController.m index 479921abd3..43307279b2 100644 --- a/Signal/src/view controllers/UITests/SignalsViewController.m +++ b/Signal/src/view controllers/UITests/SignalsViewController.m @@ -6,20 +6,28 @@ // Copyright (c) 2014 Open Whisper Systems. All rights reserved. // -#import "AppDelegate.h" #import "DemoDataFactory.h" #import "InboxTableViewCell.h" #import "MessagesViewController.h" #import "SignalsViewController.h" +#import "TSStorageManager.h" +#import "TSDatabaseView.h" #import "TSSocketManager.h" -#define CELL_HEIGHT 71.0f +#import +#import "YapDatabaseViewTransaction.h" +#import "YapDatabaseViewMappings.h" +#import "YapDatabaseViewConnection.h" +#import "YapDatabaseFullTextSearch.h" +#import "YapDatabase.h" + +#define CELL_HEIGHT 71.0f #define HEADER_HEIGHT 44.0f -static NSString *const kCellNibName = @"TableViewCell"; -static NSString *const kSegueIndentifier = @"showSegue"; +static NSString *const inboxTableViewCell = @"inBoxTableViewCell"; +static NSString *const kSegueIndentifier = @"showSegue"; @interface SignalsViewController () { @@ -28,20 +36,33 @@ static NSString *const kSegueIndentifier = @"showSegue"; } @property (strong, nonatomic) DemoDataModel *demoData; +@property (nonatomic, strong) YapDatabaseConnection *uiDatabaseConnection; +@property (nonatomic, strong) YapDatabaseViewMappings *threadMappings; @end @implementation SignalsViewController -- (void)viewDidAppear:(BOOL)animated{ - [TSSocketManager becomeActive]; -} - - (void)viewDidLoad { [super viewDidLoad]; - _dataArray = [DemoDataFactory data]; - numberOfCells = _dataArray.count; + [self tableViewSetUp]; + + [self.uiDatabaseConnection beginLongLivedReadTransaction]; + + self.threadMappings = [[YapDatabaseViewMappings alloc] initWithGroups:@[TSThreadGroup] + view:TSThreadDatabaseViewExtensionName]; + + [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction){ + [self.threadMappings updateWithTransaction:transaction]; + }]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(yapDatabaseModified:) + name:TSUIDatabaseConnectionDidUpdateNotification + object:nil]; + + [TSSocketManager becomeActive]; } - (void)didReceiveMemoryWarning { @@ -51,47 +72,51 @@ static NSString *const kSegueIndentifier = @"showSegue"; -(void)tableViewSetUp { - self._tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; + self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; + return (NSInteger)[self.threadMappings numberOfSections]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return (NSInteger)numberOfCells; + return (NSInteger)[self.threadMappings numberOfItemsInSection:(NSUInteger)section]; } -- (InboxTableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - return [self inboxFeedCellForIndexPath:indexPath]; - } +- (InboxTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { + + InboxTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:inboxTableViewCell]; + TSThread *thread = [self threadForIndexPath:indexPath]; + + if (!cell) { + cell = [[InboxTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:inboxTableViewCell]; + cell.delegate = self; + } + + [cell configureWithThread:thread]; + [cell configureForState:_segmentedControl.selectedSegmentIndex == 0 ? kInboxState : kArchiveState]; + + return cell; +} + +- (TSThread*)threadForIndexPath:(NSIndexPath*)indexPath { + + __block TSThread *thread = nil; + [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + thread = [[transaction extension:TSThreadDatabaseViewExtensionName] objectAtIndexPath:indexPath withMappings:self.threadMappings]; + }]; + + return thread; +} - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return CELL_HEIGHT; } --(InboxTableViewCell*)inboxFeedCellForIndexPath:(NSIndexPath *)indexPath { - - InboxTableViewCell *cell = [self._tableView dequeueReusableCellWithIdentifier:kCellNibName]; - - - if (!cell) { - cell = [[InboxTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault - reuseIdentifier:kCellNibName]; - cell.delegate = self; - } - - DemoDataModel *recent = _dataArray[(NSUInteger)indexPath.row]; - [cell configureWithTestMessage:recent]; - [cell configureForState:_segmentedControl.selectedSegmentIndex == 0 ? kInboxState : kArchiveState]; - return cell; - -} - - #pragma mark - HomeFeedTableViewCellDelegate - (void)tableViewCellTappedDelete:(InboxTableViewCell*)cell { @@ -117,15 +142,15 @@ static NSString *const kSegueIndentifier = @"showSegue"; if ([segue.identifier isEqualToString:kSegueIndentifier]) { MessagesViewController * vc = [segue destinationViewController]; - NSIndexPath *selectedIndexPath = [self._tableView indexPathForSelectedRow]; + NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; if (selectedIndexPath) { - vc._senderTitleString = ((DemoDataModel*)_dataArray[(NSUInteger)selectedIndexPath.row])._sender; + vc.senderTitleString = ((DemoDataModel*)_dataArray[(NSUInteger)selectedIndexPath.row])._sender; } else if (_contactFromCompose) { - vc._senderTitleString = _contactFromCompose.fullName; + vc.senderTitleString = _contactFromCompose.fullName; } else if (_groupFromCompose) { - vc._senderTitleString = _groupFromCompose.groupName; + vc.senderTitleString = _groupFromCompose.groupName; } - + } } @@ -136,14 +161,106 @@ static NSString *const kSegueIndentifier = @"showSegue"; switch (_segmentedControl.selectedSegmentIndex) { case 0: numberOfCells=5; - [self._tableView reloadData]; + [self.tableView reloadData]; break; case 1: numberOfCells=3; - [self._tableView reloadData]; + [self.tableView reloadData]; break; } } + +#pragma mark Database delegates + +- (YapDatabaseConnection *)uiDatabaseConnection { + NSAssert([NSThread isMainThread], @"Must access uiDatabaseConnection on main thread!"); + if (!_uiDatabaseConnection) { + YapDatabase *database = TSStorageManager.sharedManager.database; + _uiDatabaseConnection = [database newConnection]; + [_uiDatabaseConnection beginLongLivedReadTransaction]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(yapDatabaseModified:) + name:YapDatabaseModifiedNotification + object:database]; + } + return _uiDatabaseConnection; +} + +- (void)yapDatabaseModified:(NSNotification *)notification { + NSArray *notifications = notification.userInfo[@"notifications"]; + + NSArray *sectionChanges = nil; + NSArray *rowChanges = nil; + + [[self.uiDatabaseConnection ext:TSThreadDatabaseViewExtensionName] getSectionChanges:§ionChanges + rowChanges:&rowChanges + forNotifications:notifications + withMappings:self.threadMappings]; + + if ([sectionChanges count] == 0 && [rowChanges count] == 0){ + + return; + } + + [self.tableView beginUpdates]; + + for (YapDatabaseViewSectionChange *sectionChange in sectionChanges) + { + switch (sectionChange.type) + { + case YapDatabaseViewChangeDelete : + { + [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionChange.index] + withRowAnimation:UITableViewRowAnimationAutomatic]; + break; + } + case YapDatabaseViewChangeInsert : + { + [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionChange.index] + withRowAnimation:UITableViewRowAnimationAutomatic]; + break; + } + case YapDatabaseViewChangeUpdate: + case YapDatabaseViewChangeMove: + break; + } + } + + for (YapDatabaseViewRowChange *rowChange in rowChanges) + { + switch (rowChange.type) + { + case YapDatabaseViewChangeDelete : + { + [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ] + withRowAnimation:UITableViewRowAnimationAutomatic]; + break; + } + case YapDatabaseViewChangeInsert : + { + [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ] + withRowAnimation:UITableViewRowAnimationAutomatic]; + break; + } + case YapDatabaseViewChangeMove : + { + [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ] + withRowAnimation:UITableViewRowAnimationAutomatic]; + [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ] + withRowAnimation:UITableViewRowAnimationAutomatic]; + break; + } + case YapDatabaseViewChangeUpdate : + { + [self.tableView reloadRowsAtIndexPaths:@[ rowChange.indexPath ] + withRowAnimation:UITableViewRowAnimationNone]; + break; + } + } + } + + [self.tableView endUpdates]; +} @end diff --git a/Signal/src/view controllers/xibs/DialerViewController.xib b/Signal/src/view controllers/xibs/DialerViewController.xib index 09aadf0c96..60e3ff98d0 100755 --- a/Signal/src/view controllers/xibs/DialerViewController.xib +++ b/Signal/src/view controllers/xibs/DialerViewController.xib @@ -1,5 +1,5 @@ - + @@ -77,39 +77,39 @@ - + - + - - + + - + - + + @@ -108,7 +129,7 @@ - + @@ -118,7 +139,7 @@ - + @@ -128,7 +149,7 @@ - + @@ -137,10 +158,20 @@ - + + @@ -151,6 +182,7 @@ + @@ -160,6 +192,8 @@ + + @@ -170,6 +204,7 @@ + diff --git a/Signal/src/views/ContactTableViewCell.h b/Signal/src/views/ContactTableViewCell.h index 6c1f30b430..3069854c5d 100644 --- a/Signal/src/views/ContactTableViewCell.h +++ b/Signal/src/views/ContactTableViewCell.h @@ -14,6 +14,9 @@ @property (nonatomic, strong) IBOutlet UIButton *callButton ; @property (nonatomic, strong) IBOutlet UIButton *messageButton; +@property BOOL shouldShowContactButtons; + - (void)configureWithContact:(Contact *)contact; + @end diff --git a/Signal/src/views/ContactTableViewCell.m b/Signal/src/views/ContactTableViewCell.m index 05b9c67f96..8762aa9111 100644 --- a/Signal/src/views/ContactTableViewCell.m +++ b/Signal/src/views/ContactTableViewCell.m @@ -14,6 +14,16 @@ self = [NSBundle.mainBundle loadNibNamed:NSStringFromClass(self.class) owner:self options:nil][0]; _contactPictureView.layer.borderColor = [[UIColor lightGrayColor] CGColor]; _contactPictureView.layer.masksToBounds = YES; + self.selectionStyle = UITableViewCellSelectionStyleGray; + + if (!_shouldShowContactButtons) + { + _callButton.hidden = YES; + _callButton.enabled = NO; + _messageButton.hidden = YES; + _callButton.enabled = NO; + } + return self; } @@ -22,7 +32,7 @@ } - (void)configureWithContact:(Contact *)contact { - + _associatedContact = contact; _nameLabel.attributedText = [self attributedStringForContact:contact]; @@ -38,14 +48,14 @@ [_contactPictureView addConstraint:[NSLayoutConstraint constraintWithItem:_contactPictureView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:0]]; } - if (contact.isRedPhoneContact) + if (contact.isRedPhoneContact && _shouldShowContactButtons) { _callButton.imageView.image = [UIImage imageNamed:@"call_dark"]; } else { [_callButton addConstraint:[NSLayoutConstraint constraintWithItem:_callButton attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:0]]; } - if (contact.isTextSecureContact) + if (contact.isTextSecureContact && _shouldShowContactButtons) { _messageButton.imageView.image = [UIImage imageNamed:@"signal"]; } else { diff --git a/Signal/src/views/DialerButtonView.m b/Signal/src/views/DialerButtonView.m index fb05893c8b..51ddac5b8a 100644 --- a/Signal/src/views/DialerButtonView.m +++ b/Signal/src/views/DialerButtonView.m @@ -16,8 +16,15 @@ - (void)setSelected:(BOOL)isSelected { if (isSelected) { - //self.backgroundColor = [UIUtil transparentLightGrayColor]; - //self.layer.borderWidth = 0.5f; + + UIColor *color = [UIColor blackColor]; + self.layer.shadowColor = [color CGColor]; + self.layer.shadowRadius = 15.0f; + self.layer.shadowOpacity = 1.0f; + self.layer.shadowOffset = CGSizeZero; + self.layer.masksToBounds = NO; + + } else { self.backgroundColor = [UIColor clearColor]; self.layer.borderWidth = 0.0f; diff --git a/Signal/test/textsecure/CryptographyTests.mm b/Signal/test/textsecure/CryptographyTests.mm index c5ed7e2e75..6a3e3d2d29 100644 --- a/Signal/test/textsecure/CryptographyTests.mm +++ b/Signal/test/textsecure/CryptographyTests.mm @@ -19,7 +19,14 @@ @interface Cryptography (Test) +(NSData*) truncatedSHA256HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey truncation:(int)bytes; +(NSData*)encryptCBCMode:(NSData*) dataToEncrypt withKey:(NSData*) key withIV:(NSData*) iv withVersion:(NSData*)version withHMACKey:(NSData*) hmacKey withHMACType:(TSMACType)hmacType computedHMAC:(NSData**)hmac; -+(NSData*) decryptCBCMode:(NSData*) dataToDecrypt withKey:(NSData*) key withIV:(NSData*) iv withVersion:(NSData*)version withHMACKey:(NSData*) hmacKey withHMACType:(TSMACType)hmacType forHMAC:(NSData *)hmac; + ++(NSData*)decryptCBCMode:(NSData*)dataToDecrypt + key:(NSData*)key + IV:(NSData*)iv + version:(NSData*)version + HMACKey:(NSData*) hmacKey + HMACType:(TSMACType)hmacType + matchingHMAC:(NSData *)hmac; @end @implementation CryptographyTests @@ -48,7 +55,7 @@ XCTAssertTrue([mac isEqualToData:expectedHmac], @"Hmac of encrypted data %@, not equal to expected hmac %@", [mac base64EncodedString], [expectedHmac base64EncodedString]); - NSData* decryption=[Cryptography decryptCBCMode:encryption withKey:signalingKeyAESKeyMaterial withIV:iv withVersion:version withHMACKey:signalingKeyHMACKeyMaterial withHMACType:TSHMACSHA1Truncated10Bytes forHMAC:mac]; + NSData* decryption=[Cryptography decryptCBCMode:encryption key:signalingKeyAESKeyMaterial IV:iv version:version HMACKey:signalingKeyHMACKeyMaterial HMACType:TSHMACSHA1Truncated10Bytes matchingHMAC:mac]; NSString* decryptedMessage = [[NSString alloc] initWithData:decryption encoding:NSUTF8StringEncoding]; XCTAssertTrue([decryptedMessage isEqualToString:originalMessage], @"Decrypted message: %@ is not equal to original: %@",decryptedMessage,originalMessage); diff --git a/Signal/test/textsecure/TSMessageStorageTests.m b/Signal/test/textsecure/TSMessageStorageTests.m index ba7397b395..542aee3aa1 100644 --- a/Signal/test/textsecure/TSMessageStorageTests.m +++ b/Signal/test/textsecure/TSMessageStorageTests.m @@ -34,9 +34,11 @@ - (void)setUp { [super setUp]; - self.thread = [TSContactThread threadWithContactId:@"aStupidId"]; - - [self.thread save]; + [[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + self.thread = [TSContactThread threadWithContactId:@"aStupidId" transaction:transaction]; + + [self.thread saveWithTransaction:transaction]; + }]; TSStorageManager *manager = [TSStorageManager sharedManager]; [manager purgeCollection:[TSMessage collection]]; @@ -82,7 +84,7 @@ - [[TSStorageManager sharedManager].databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (uint64_t i = timestamp; i<100; i++) { TSIncomingMessage *fetchedMessage = [TSIncomingMessage fetchObjectWithUniqueID:[TSInteraction stringFromTimeStamp:timestamp] transaction:transaction]; @@ -97,7 +99,7 @@ [self.thread remove]; - [[TSStorageManager sharedManager].databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (uint64_t i = timestamp; i<1000; i++) { TSIncomingMessage *fetchedMessage = [TSIncomingMessage fetchObjectWithUniqueID:[TSInteraction stringFromTimeStamp:timestamp] transaction:transaction]; NSAssert(fetchedMessage == nil, @"Message should be deleted!");