From 9e8ba913045503e31890d0508b318a0a7fc98274 Mon Sep 17 00:00:00 2001 From: Frederic Jacobs Date: Fri, 16 Jan 2015 15:28:41 +0100 Subject: [PATCH] Settings refactoring. - Renames GroupModel to TSGroupModel for TextSecureKit consistency. - Refactors the settings into categories (joint work with @dtsbourg) - Removes settings and logic for background push. --- Signal.xcodeproj/project.pbxproj | 54 +- .../notification_no_preview_no_name@2x.png | Bin 30991 -> 0 bytes .../notification_no_preview_with_name@2x.png | Bin 32397 -> 0 bytes .../Images/notification_with_preview@2x.png | Bin 30179 -> 0 bytes Signal/src/AppDelegate.m | 9 +- Signal/src/Storyboard/Storyboard.storyboard | 1016 +++++------------ Signal/src/environment/Environment.h | 4 +- Signal/src/environment/Environment.m | 2 +- .../Contacts/Threads/TSGroupThread.h | 8 +- .../Contacts/Threads/TSGroupThread.m | 6 +- .../Messages/TSMessagesManager+attachments.m | 2 +- .../textsecure/Messages/TSMessagesManager.m | 32 +- .../AboutTableViewController.h | 13 + .../AboutTableViewController.m | 159 +++ .../AdvancedSettingsTableViewController.h | 13 + .../AdvancedSettingsTableViewController.m | 116 ++ .../MediaSettingsTableViewController.h | 13 + .../MediaSettingsTableViewController.m | 144 +++ .../view controllers/MessagesViewController.h | 4 +- .../view controllers/MessagesViewController.m | 6 +- .../view controllers/NewGroupViewController.h | 4 +- .../view controllers/NewGroupViewController.m | 10 +- .../NotificationPreviewViewController.h | 13 - .../NotificationPreviewViewController.m | 118 -- .../PrivacySettingsTableViewController.h | 13 + .../PrivacySettingsTableViewController.m | 202 ++++ .../SettingsTableViewController.h | 1 + .../SettingsTableViewController.m | 256 +++-- .../ShowGroupMembersViewController.h | 2 +- .../ShowGroupMembersViewController.m | 2 +- .../{GroupModel.h => TSGroupModel.h} | 10 +- .../{GroupModel.m => TSGroupModel.m} | 20 +- .../UITests/SignalsViewController.h | 4 +- 33 files changed, 1186 insertions(+), 1070 deletions(-) delete mode 100644 Signal/Images/notification_no_preview_no_name@2x.png delete mode 100644 Signal/Images/notification_no_preview_with_name@2x.png delete mode 100644 Signal/Images/notification_with_preview@2x.png create mode 100644 Signal/src/view controllers/AboutTableViewController.h create mode 100644 Signal/src/view controllers/AboutTableViewController.m create mode 100644 Signal/src/view controllers/AdvancedSettingsTableViewController.h create mode 100644 Signal/src/view controllers/AdvancedSettingsTableViewController.m create mode 100644 Signal/src/view controllers/MediaSettingsTableViewController.h create mode 100644 Signal/src/view controllers/MediaSettingsTableViewController.m delete mode 100644 Signal/src/view controllers/NotificationPreviewViewController.h delete mode 100644 Signal/src/view controllers/NotificationPreviewViewController.m create mode 100644 Signal/src/view controllers/PrivacySettingsTableViewController.h create mode 100644 Signal/src/view controllers/PrivacySettingsTableViewController.m rename Signal/src/view controllers/{GroupModel.h => TSGroupModel.h} (56%) rename Signal/src/view controllers/{GroupModel.m => TSGroupModel.m} (89%) diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 4bb7eecf8..fd8c954d2 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -357,7 +357,7 @@ B68B0E8A1A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = B68B0E891A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m */; }; B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; }; B6A3EB4B1A423B3800B2236B /* TSAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A3EB4A1A423B3800B2236B /* TSAttachmentAdapter.m */; }; - B6AE33BD1A1EB121003DF39D /* GroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B6AE33BC1A1EB121003DF39D /* GroupModel.m */; }; + B6AE33BD1A1EB121003DF39D /* TSGroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B6AE33BC1A1EB121003DF39D /* TSGroupModel.m */; }; B6B095E41A1D25C5008BFAA6 /* CryptographyTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = B6B095DE1A1D25C5008BFAA6 /* CryptographyTests.mm */; }; B6B095E51A1D25C5008BFAA6 /* TextSecureKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095DF1A1D25C5008BFAA6 /* TextSecureKitTests.m */; }; B6B095E61A1D25C5008BFAA6 /* TSMessageStorageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095E01A1D25C5008BFAA6 /* TSMessageStorageTests.m */; }; @@ -486,10 +486,6 @@ 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 */; }; - FC1615181A37935600F1761D /* NotificationPreviewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC1615171A37935600F1761D /* NotificationPreviewViewController.m */; }; - FC16151C1A37945D00F1761D /* notification_no_preview_with_name@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC1615191A37945D00F1761D /* notification_no_preview_with_name@2x.png */; }; - FC16151D1A37945D00F1761D /* notification_no_preview_no_name@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC16151A1A37945D00F1761D /* notification_no_preview_no_name@2x.png */; }; - FC16151E1A37945D00F1761D /* notification_with_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC16151B1A37945D00F1761D /* notification_with_preview@2x.png */; }; FC18803C1A31D94D0044CE86 /* SignalTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC18803B1A31D94D0044CE86 /* SignalTabBarController.m */; }; 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 */; }; @@ -533,6 +529,10 @@ FCB626B61A3B067900FDB504 /* ArrowBottom@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCB626B21A3B067900FDB504 /* ArrowBottom@3x.png */; }; FCB626B71A3B067900FDB504 /* ArrowTop@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCB626B31A3B067900FDB504 /* ArrowTop@3x.png */; }; FCC81A981A44558300DFEC7D /* UIDevice+TSHardwareVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = FCC81A971A44558300DFEC7D /* UIDevice+TSHardwareVersion.m */; }; + FCD274E21A5AFD8000202277 /* PrivacySettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCD274E11A5AFD8000202277 /* PrivacySettingsTableViewController.m */; }; + FCD274E51A5AFDB800202277 /* MediaSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCD274E41A5AFDB800202277 /* MediaSettingsTableViewController.m */; }; + FCD274E81A5AFDC900202277 /* AdvancedSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCD274E71A5AFDC900202277 /* AdvancedSettingsTableViewController.m */; }; + FCD274EB1A5AFDDB00202277 /* AboutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCD274EA1A5AFDDB00202277 /* AboutTableViewController.m */; }; FCF72A081A01A765006BC849 /* ContactsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCF72A071A01A765006BC849 /* ContactsTableViewController.m */; }; FCF72A131A02D27F006BC849 /* ContactDetailTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCF72A111A02D27F006BC849 /* ContactDetailTableViewController.m */; }; FCFA64B41A24F3880007FB87 /* UIColor+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFA64B31A24F3880007FB87 /* UIColor+OWS.m */; }; @@ -996,8 +996,8 @@ B69CD25019773E79005CE69A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; B6A3EB491A423B3800B2236B /* TSAttachmentAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAttachmentAdapter.h; sourceTree = ""; }; B6A3EB4A1A423B3800B2236B /* TSAttachmentAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachmentAdapter.m; sourceTree = ""; }; - B6AE33BB1A1EB121003DF39D /* GroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupModel.h; sourceTree = ""; }; - B6AE33BC1A1EB121003DF39D /* GroupModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupModel.m; sourceTree = ""; }; + B6AE33BB1A1EB121003DF39D /* TSGroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSGroupModel.h; path = "../../view controllers/TSGroupModel.h"; sourceTree = ""; }; + B6AE33BC1A1EB121003DF39D /* TSGroupModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSGroupModel.m; path = "../../view controllers/TSGroupModel.m"; sourceTree = ""; }; B6B095DE1A1D25C5008BFAA6 /* CryptographyTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CryptographyTests.mm; sourceTree = ""; }; B6B095DF1A1D25C5008BFAA6 /* TextSecureKitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextSecureKitTests.m; sourceTree = ""; }; B6B095E01A1D25C5008BFAA6 /* TSMessageStorageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSMessageStorageTests.m; sourceTree = ""; }; @@ -1187,11 +1187,6 @@ 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 = ""; }; - FC1615161A37935600F1761D /* NotificationPreviewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationPreviewViewController.h; sourceTree = ""; }; - FC1615171A37935600F1761D /* NotificationPreviewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationPreviewViewController.m; sourceTree = ""; }; - FC1615191A37945D00F1761D /* notification_no_preview_with_name@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "notification_no_preview_with_name@2x.png"; sourceTree = ""; }; - FC16151A1A37945D00F1761D /* notification_no_preview_no_name@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "notification_no_preview_no_name@2x.png"; sourceTree = ""; }; - FC16151B1A37945D00F1761D /* notification_with_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "notification_with_preview@2x.png"; sourceTree = ""; }; FC18803A1A31D94D0044CE86 /* SignalTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalTabBarController.h; sourceTree = ""; }; FC18803B1A31D94D0044CE86 /* SignalTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalTabBarController.m; sourceTree = ""; }; FC1F90BF1A22342B004F8253 /* group_photo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "group_photo@2x.png"; sourceTree = ""; }; @@ -1249,6 +1244,14 @@ FCB626B31A3B067900FDB504 /* ArrowTop@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ArrowTop@3x.png"; sourceTree = ""; }; FCC81A961A44558300DFEC7D /* UIDevice+TSHardwareVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIDevice+TSHardwareVersion.h"; sourceTree = ""; }; FCC81A971A44558300DFEC7D /* UIDevice+TSHardwareVersion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIDevice+TSHardwareVersion.m"; sourceTree = ""; }; + FCD274E01A5AFD8000202277 /* PrivacySettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivacySettingsTableViewController.h; sourceTree = ""; }; + FCD274E11A5AFD8000202277 /* PrivacySettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrivacySettingsTableViewController.m; sourceTree = ""; }; + FCD274E31A5AFDB800202277 /* MediaSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSettingsTableViewController.h; sourceTree = ""; }; + FCD274E41A5AFDB800202277 /* MediaSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MediaSettingsTableViewController.m; sourceTree = ""; }; + FCD274E61A5AFDC900202277 /* AdvancedSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedSettingsTableViewController.h; sourceTree = ""; }; + FCD274E71A5AFDC900202277 /* AdvancedSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AdvancedSettingsTableViewController.m; sourceTree = ""; }; + FCD274E91A5AFDDB00202277 /* AboutTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutTableViewController.h; sourceTree = ""; }; + FCD274EA1A5AFDDB00202277 /* AboutTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutTableViewController.m; sourceTree = ""; }; FCF72A061A01A765006BC849 /* ContactsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTableViewController.h; sourceTree = ""; }; FCF72A071A01A765006BC849 /* ContactsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsTableViewController.m; sourceTree = ""; }; FCF72A111A02D27F006BC849 /* ContactDetailTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailTableViewController.m; sourceTree = ""; }; @@ -2204,9 +2207,6 @@ FCA52AE41A2B676C00CCADFA /* message_error@2x.png */, B633C5411A1D190B0059AC12 /* mute_off@2x.png */, B633C5421A1D190B0059AC12 /* mute_on@2x.png */, - FC16151A1A37945D00F1761D /* notification_no_preview_no_name@2x.png */, - FC1615191A37945D00F1761D /* notification_no_preview_with_name@2x.png */, - FC16151B1A37945D00F1761D /* notification_with_preview@2x.png */, B633C54B1A1D190B0059AC12 /* photo@2x.png */, FC9120421A39F9E00074545C /* qr_scan_fingerprint@2x.png */, FC91203F1A39EFB70074545C /* qr@2x.png */, @@ -2306,8 +2306,6 @@ B6AE33B41A1EB0A0003DF39D /* temp */ = { isa = PBXGroup; children = ( - B6AE33BB1A1EB121003DF39D /* GroupModel.h */, - B6AE33BC1A1EB121003DF39D /* GroupModel.m */, ); name = temp; sourceTree = ""; @@ -2395,6 +2393,8 @@ B6B0960E1A1D25ED008BFAA6 /* TSInfoMessage.m */, B6B0960F1A1D25ED008BFAA6 /* TSInteraction.h */, B6B096101A1D25ED008BFAA6 /* TSInteraction.m */, + B6AE33BB1A1EB121003DF39D /* TSGroupModel.h */, + B6AE33BC1A1EB121003DF39D /* TSGroupModel.m */, B6B096111A1D25ED008BFAA6 /* TSMessage.h */, B6B096121A1D25ED008BFAA6 /* TSMessage.m */, B6B50AA91A4192C500F8F607 /* TSMessagesManager+attachments.h */, @@ -2686,8 +2686,14 @@ children = ( FC31962E1A0814130094C78E /* SettingsTableViewController.h */, FC31962F1A0814130094C78E /* SettingsTableViewController.m */, - FC1615161A37935600F1761D /* NotificationPreviewViewController.h */, - FC1615171A37935600F1761D /* NotificationPreviewViewController.m */, + FCD274E01A5AFD8000202277 /* PrivacySettingsTableViewController.h */, + FCD274E11A5AFD8000202277 /* PrivacySettingsTableViewController.m */, + FCD274E31A5AFDB800202277 /* MediaSettingsTableViewController.h */, + FCD274E41A5AFDB800202277 /* MediaSettingsTableViewController.m */, + FCD274E61A5AFDC900202277 /* AdvancedSettingsTableViewController.h */, + FCD274E71A5AFDC900202277 /* AdvancedSettingsTableViewController.m */, + FCD274E91A5AFDDB00202277 /* AboutTableViewController.h */, + FCD274EA1A5AFDDB00202277 /* AboutTableViewController.m */, ); name = Settings; sourceTree = ""; @@ -2951,9 +2957,7 @@ B633C5CE1A1D190B0059AC12 /* quit@2x.png in Resources */, E148750A18A06966002CC4F3 /* InCallViewController.xib in Resources */, FCA52AEB1A2B676C00CCADFA /* checkmark_light@2x.png in Resources */, - FC16151C1A37945D00F1761D /* notification_no_preview_with_name@2x.png in Resources */, B633C5D01A1D190B0059AC12 /* red-delete@2x.png in Resources */, - FC16151E1A37945D00F1761D /* notification_with_preview@2x.png in Resources */, B633C59D1A1D190B0059AC12 /* endcall@2x.png in Resources */, B633C5B41A1D190B0059AC12 /* keypad@2x.png in Resources */, B633C5DA1A1D190B0059AC12 /* settings_dark@2x.png in Resources */, @@ -2976,7 +2980,6 @@ B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */, FCA52AE71A2B676C00CCADFA /* call_failed@2x.png in Resources */, 70B8FEE21909FE360042E3F0 /* 171756__nenadsimic__picked-coin-echo-2.wav in Resources */, - FC16151D1A37945D00F1761D /* notification_no_preview_no_name@2x.png in Resources */, B633C5801A1D190B0059AC12 /* archive@2x.png in Resources */, FC1F90C71A223991004F8253 /* signals_tab@2x.png in Resources */, FCB626B51A3B067900FDB504 /* ArrowBottom@2x.png in Resources */, @@ -3170,6 +3173,7 @@ B63AF5C91A1F757900D01AAD /* TSRecipientPrekeyRequest.m in Sources */, 7095B7B018F46D35002C66E2 /* PhoneNumberUtil.m in Sources */, B63AF5D81A1F889500D01AAD /* SubProtocol.pb.m in Sources */, + FCD274EB1A5AFDDB00202277 /* AboutTableViewController.m in Sources */, E197B61618BBEC1A00F073E5 /* StretchFactorController.m in Sources */, FCFD257F1A154B2C00F4C644 /* RegistrationViewController.m in Sources */, 76EB065018170B34006006FC /* DialerViewController.m in Sources */, @@ -3201,7 +3205,7 @@ 76EB065A18170B34006006FC /* NextResponderScrollView.m in Sources */, 76EB062618170B33006006FC /* Queue.m in Sources */, D221A09A169C9E5E00537ABF /* main.m in Sources */, - B6AE33BD1A1EB121003DF39D /* GroupModel.m in Sources */, + B6AE33BD1A1EB121003DF39D /* TSGroupModel.m in Sources */, 76EB061618170B33006006FC /* AnonymousOccurrenceLogger.m in Sources */, 76EB063018170B33006006FC /* Conversions.m in Sources */, FCAFC33F1A0F948F00AE5136 /* ActionContactDetailCell.m in Sources */, @@ -3225,7 +3229,6 @@ 76EB058218170B33006006FC /* Environment.m in Sources */, 76EB064418170B33006006FC /* ThreadManager.m in Sources */, E197B61E18BBEC6D00F073E5 /* AudioRouter.m in Sources */, - FC1615181A37935600F1761D /* NotificationPreviewViewController.m in Sources */, E197B60D18BBEC1A00F073E5 /* AudioSocket.m in Sources */, FCF72A081A01A765006BC849 /* ContactsTableViewController.m in Sources */, A5D0699B1A50E9CB004CB540 /* ShowGroupMembersViewController.m in Sources */, @@ -3260,6 +3263,7 @@ 76EB063218170B33006006FC /* Crc32.m in Sources */, E197B62418BBF5BB00F073E5 /* SoundPlayer.m in Sources */, E197B61018BBEC1A00F073E5 /* EncodedAudioPacket.m in Sources */, + FCD274E51A5AFDB800202277 /* MediaSettingsTableViewController.m in Sources */, 76EB063618170B33006006FC /* DataUtil.m in Sources */, E197B60C18BBEC1A00F073E5 /* AudioPacker.m in Sources */, E197B61218BBEC1A00F073E5 /* AudioStretcher.m in Sources */, @@ -3275,6 +3279,7 @@ 76EB057418170B33006006FC /* RecentCallManager.m in Sources */, B60FB9A71A46F099006A5A66 /* TSAllocAttachmentRequest.m in Sources */, 76EB061C18170B33006006FC /* ArrayUtil.m in Sources */, + FCD274E81A5AFDC900202277 /* AdvancedSettingsTableViewController.m in Sources */, 76EB05C418170B33006006FC /* HandshakePacket.m in Sources */, 76EB05AA18170B33006006FC /* SequenceCounter.m in Sources */, 7038632718F70C0700D4A43F /* CryptoTools.m in Sources */, @@ -3327,6 +3332,7 @@ FCB11D8A1A1284BB002F93FB /* SettingsTableViewCell.m in Sources */, 76EB05C818170B33006006FC /* HelloPacket.m in Sources */, BFB074C719A5611000F2947C /* FutureUtil.m in Sources */, + FCD274E21A5AFD8000202277 /* PrivacySettingsTableViewController.m in Sources */, 76EB057218170B33006006FC /* RecentCall.m in Sources */, 76EB060418170B33006006FC /* PhoneNumberDirectoryFilter.m in Sources */, B97CBFA818860EA3008E0DE9 /* CountryCodeViewController.m in Sources */, diff --git a/Signal/Images/notification_no_preview_no_name@2x.png b/Signal/Images/notification_no_preview_no_name@2x.png deleted file mode 100644 index 4ba66759abb662eaae6582c18030332b81f4cb5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30991 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 diff --git a/Signal/Images/notification_no_preview_with_name@2x.png b/Signal/Images/notification_no_preview_with_name@2x.png deleted file mode 100644 index bd00e898f2ea94dfdfbfc8e820f9d3afa276be86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32397 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 diff --git a/Signal/Images/notification_with_preview@2x.png b/Signal/Images/notification_with_preview@2x.png deleted file mode 100644 index 515c9a99fc1063029f97b19ca50f33990f519583..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30179 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 DRxDmi diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index d1f7f0012..dee506ba3 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -212,6 +212,7 @@ } else { [TSSocketManager becomeActive]; } + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ completionHandler(UIBackgroundFetchResultNewData); @@ -261,13 +262,9 @@ dispatch_get_main_queue(), ^{ completionHandler(); }); - } else if ([identifier isEqualToString:Signal_Message_MarkAsRead_Identifier]){ - //TODO - } else if ([identifier isEqualToString:Signal_Message_View_Identifier]){ - //TODO + } else{ + completionHandler(); } - - completionHandler(); } - (void)applicationDidEnterBackground:(UIApplication *)application{ diff --git a/Signal/src/Storyboard/Storyboard.storyboard b/Signal/src/Storyboard/Storyboard.storyboard index f2a23abd8..646bf7344 100755 --- a/Signal/src/Storyboard/Storyboard.storyboard +++ b/Signal/src/Storyboard/Storyboard.storyboard @@ -21,8 +21,6 @@ - - @@ -2632,70 +2630,18 @@ A0 09 9A FF A8 8A 09 99 - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -2775,88 +2721,18 @@ Licensed under the GPLv3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + - - - - + + + + + + + - + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3365,216 +3159,14 @@ Licensed under the GPLv3 - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3866,9 +3458,6 @@ Licensed under the GPLv3 - - - @@ -3876,10 +3465,9 @@ Licensed under the GPLv3 - + - diff --git a/Signal/src/environment/Environment.h b/Signal/src/environment/Environment.h index 1e2ab63c5..6e7283a3b 100644 --- a/Signal/src/environment/Environment.h +++ b/Signal/src/environment/Environment.h @@ -3,7 +3,7 @@ #import "PropertyListPreferences.h" #import "PacketHandler.h" #import "SecureEndPoint.h" -#import "GroupModel.h" +#import "TSGroupModel.h" /** * * Environment is a data and data accessor class. @@ -84,6 +84,6 @@ andCurrentRegionCodeForPhoneNumbers:(NSString*)currentRegionCodeForPhoneNumbers - (void)setSignUpFlowNavigationController:(UINavigationController *)signUpFlowNavigationController; + (void)messageIdentifier:(NSString*)identifier; -+ (void)groupModel:(GroupModel*)model; ++ (void)groupModel:(TSGroupModel*)model; @end diff --git a/Signal/src/environment/Environment.m b/Signal/src/environment/Environment.m index e626e28e7..e057a91b2 100644 --- a/Signal/src/environment/Environment.m +++ b/Signal/src/environment/Environment.m @@ -187,7 +187,7 @@ phoneDirectoryManager; } } -+ (void)groupModel:(GroupModel*)model { ++ (void)groupModel:(TSGroupModel*)model { Environment *env = [self getCurrent]; SignalsViewController *vc = env.signalsViewController; diff --git a/Signal/src/textsecure/Contacts/Threads/TSGroupThread.h b/Signal/src/textsecure/Contacts/Threads/TSGroupThread.h index 957908b5d..5d52d5460 100644 --- a/Signal/src/textsecure/Contacts/Threads/TSGroupThread.h +++ b/Signal/src/textsecure/Contacts/Threads/TSGroupThread.h @@ -7,13 +7,13 @@ // #import "TSThread.h" -#import "GroupModel.h" +#import "TSGroupModel.h" @interface TSGroupThread : TSThread -@property (nonatomic,strong) GroupModel* groupModel; -+ (instancetype)getOrCreateThreadWithGroupModel:(GroupModel *)groupModel transaction:(YapDatabaseReadWriteTransaction*)transaction; +@property (nonatomic,strong) TSGroupModel* groupModel; ++ (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel transaction:(YapDatabaseReadWriteTransaction*)transaction; -+ (instancetype)threadWithGroupModel:(GroupModel *)groupModel transaction:(YapDatabaseReadTransaction*)transaction; ++ (instancetype)threadWithGroupModel:(TSGroupModel *)groupModel transaction:(YapDatabaseReadTransaction*)transaction; - (NSData*)groupId; - (NSArray *)recipientsWithTransaction:(YapDatabaseReadTransaction*)transaction; diff --git a/Signal/src/textsecure/Contacts/Threads/TSGroupThread.m b/Signal/src/textsecure/Contacts/Threads/TSGroupThread.m index fb3a2dc4f..c2f7ee269 100644 --- a/Signal/src/textsecure/Contacts/Threads/TSGroupThread.m +++ b/Signal/src/textsecure/Contacts/Threads/TSGroupThread.m @@ -14,7 +14,7 @@ #define TSGroupThreadPrefix @"g" -- (instancetype)initWithGroupModel:(GroupModel *)groupModel{ +- (instancetype)initWithGroupModel:(TSGroupModel *)groupModel{ NSString *uniqueIdentifier = [[self class] threadIdFromGroupId:groupModel.groupId]; @@ -24,11 +24,11 @@ } -+ (instancetype)threadWithGroupModel:(GroupModel *)groupModel transaction:(YapDatabaseReadTransaction*)transaction { ++ (instancetype)threadWithGroupModel:(TSGroupModel *)groupModel transaction:(YapDatabaseReadTransaction*)transaction { return [self fetchObjectWithUniqueID:[self threadIdFromGroupId:groupModel.groupId] transaction:transaction]; } -+ (instancetype)getOrCreateThreadWithGroupModel:(GroupModel *)groupModel transaction:(YapDatabaseReadWriteTransaction*)transaction{ ++ (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel transaction:(YapDatabaseReadWriteTransaction*)transaction{ TSGroupThread *thread = [self fetchObjectWithUniqueID:[self threadIdFromGroupId:groupModel.groupId] transaction:transaction]; if (!thread) { diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m b/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m index c17f70fe1..8160fbe58 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m +++ b/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m @@ -147,7 +147,7 @@ dispatch_queue_t attachmentsQueue() { [stream saveWithTransaction:transaction]; if([attachment.avatarOfGroupId length]!=0) { - GroupModel *emptyModelToFillOutId = [[GroupModel alloc] initWithTitle:nil memberIds:nil image:nil groupId:attachment.avatarOfGroupId]; // TODO refactor the TSGroupThread to just take in an ID (as it is all that it uses). Should not take in more than it uses + TSGroupModel *emptyModelToFillOutId = [[TSGroupModel alloc] initWithTitle:nil memberIds:nil image:nil groupId:attachment.avatarOfGroupId]; // TODO refactor the TSGroupThread to just take in an ID (as it is all that it uses). Should not take in more than it uses TSGroupThread* gThread = [TSGroupThread getOrCreateThreadWithGroupModel:emptyModelToFillOutId transaction:transaction]; gThread.groupModel.groupImage=[stream image]; [gThread saveWithTransaction:transaction]; diff --git a/Signal/src/textsecure/Messages/TSMessagesManager.m b/Signal/src/textsecure/Messages/TSMessagesManager.m index a2d8deae3..f46fc0952 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager.m +++ b/Signal/src/textsecure/Messages/TSMessagesManager.m @@ -186,7 +186,7 @@ if(content.hasGroup) { __block BOOL ignoreMessage = NO; [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - GroupModel *emptyModelToFillOutId = [[GroupModel alloc] initWithTitle:nil memberIds:nil image:nil groupId:content.group.id]; // TODO refactor the TSGroupThread to just take in an ID (as it is all that it uses). Should not take in more than it uses + TSGroupModel *emptyModelToFillOutId = [[TSGroupModel alloc] initWithTitle:nil memberIds:nil image:nil groupId:content.group.id]; // TODO refactor the TSGroupThread to just take in an ID (as it is all that it uses). Should not take in more than it uses TSGroupThread *gThread = [TSGroupThread threadWithGroupModel:emptyModelToFillOutId transaction:transaction]; if(gThread==nil && content.group.type != PushMessageContentGroupContextTypeUpdate) { ignoreMessage = YES; @@ -247,7 +247,7 @@ TSIncomingMessage *incomingMessage; TSThread *thread; if (groupId) { - GroupModel *model = [[GroupModel alloc] initWithTitle:content.group.name memberIds:[[NSMutableArray alloc ] initWithArray:content.group.members] image:nil groupId:content.group.id]; + TSGroupModel *model = [[TSGroupModel alloc] initWithTitle:content.group.name memberIds:[[NSMutableArray alloc ] initWithArray:content.group.members] image:nil groupId:content.group.id]; TSGroupThread *gThread = [TSGroupThread getOrCreateThreadWithGroupModel:model transaction:transaction]; [gThread saveWithTransaction:transaction]; if(content.group.type==PushMessageContentGroupContextTypeUpdate) { @@ -324,7 +324,6 @@ [errorMessage saveWithTransaction:transaction]; }]; - } - (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message{ @@ -339,32 +338,7 @@ } - (void)notifyUserForIncomingMessage:(TSIncomingMessage*)message from:(NSString*)name{ - UILocalNotification *notification = [[UILocalNotification alloc] init]; - - notification.alertBody = [self alertBodyForNotificationSetting:[Environment.preferences notificationPreviewType] withMessage:message from:name]; - notification.soundName = @"default"; - notification.category = Signal_Message_Category; - - [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; -} - --(NSString*)alertBodyForNotificationSetting:(NotificationType)setting withMessage:(TSIncomingMessage*)message from:(NSString*)name -{ - switch (setting) { - case NotificationNoNameNoPreview: - return @"New message"; - break; - case NotificationNamePreview: - if (message.body) { - return [NSString stringWithFormat:@"%@ : %@", name, message.body]; - } - case NotificationNameNoPreview: - return [NSString stringWithFormat:@"New message from %@", name]; - - default: - DDLogWarn(@"Unexpected notification type %lu", setting); - break; - } + //TODO: Warn user when message is received? } @end diff --git a/Signal/src/view controllers/AboutTableViewController.h b/Signal/src/view controllers/AboutTableViewController.h new file mode 100644 index 000000000..226aa9030 --- /dev/null +++ b/Signal/src/view controllers/AboutTableViewController.h @@ -0,0 +1,13 @@ +// +// AboutTableViewController.h +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import + +@interface AboutTableViewController : UITableViewController + +@end diff --git a/Signal/src/view controllers/AboutTableViewController.m b/Signal/src/view controllers/AboutTableViewController.m new file mode 100644 index 000000000..b852b0cd3 --- /dev/null +++ b/Signal/src/view controllers/AboutTableViewController.m @@ -0,0 +1,159 @@ +// +// AboutTableViewController.m +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import "AboutTableViewController.h" +#import +#import "UIUtil.h" + +@interface AboutTableViewController () + +@property (strong, nonatomic) UITableViewCell *versionCell; +@property (strong, nonatomic) UITableViewCell *supportCell; +@property (strong, nonatomic) UITableViewCell *twitterInviteCell; + +@property (strong, nonatomic) UILabel *versionLabel; + +@property (strong, nonatomic) UILabel *footerView; + +@end + +@implementation AboutTableViewController + +-(instancetype)init { + return [super initWithStyle:UITableViewStyleGrouped]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero]; +} + +-(void)loadView +{ + [super loadView]; + + self.title = @"About"; + + //Version + self.versionCell = [[UITableViewCell alloc]init]; + self.versionCell.textLabel.text = @"Version"; + + self.versionLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 75, 30)]; + self.versionLabel.text = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; + self.versionLabel.textColor = [UIColor lightGrayColor]; + self.versionLabel.font = [UIFont ows_lightFontWithSize:16.0f]; + self.versionLabel.textAlignment = NSTextAlignmentRight; + + self.versionCell.accessoryView = self.versionLabel; + self.versionCell.userInteractionEnabled = NO; + + //Support + self.supportCell = [[UITableViewCell alloc]init]; + self.supportCell.textLabel.text = @"Support"; + self.supportCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + //Footer + self.footerView = [[UILabel alloc]init]; + self.footerView.text = @"Copyright Open Whisper Systems \n Licensed under the GPLv3"; + self.footerView.textColor = [UIColor darkGrayColor]; + self.footerView.font = [UIFont ows_lightFontWithSize:15.0f]; + self.footerView.numberOfLines = 2; + self.footerView.textAlignment = NSTextAlignmentCenter; + + + //Twitter Invite + self.twitterInviteCell = [[UITableViewCell alloc]init]; + self.twitterInviteCell.textLabel.text = @"Share install link"; + + UIImageView* twitterImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"twitter"]]; + [twitterImageView setFrame:CGRectMake(0, 0, 34, 34)]; + twitterImageView.contentMode = UIViewContentModeScaleAspectFit; + + self.twitterInviteCell.accessoryView = twitterImageView; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 3; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + switch (section) { + case 0: return 1; + case 1: return 1; + case 2: return 1; + default: return 0; + } +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + switch (section) { + case 0: return @"Information"; + case 1: return @"Invite"; + case 2: return @"Help"; + + default: return nil; + } +} + +-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + switch (indexPath.section) { + case 0: return self.versionCell; + case 1: return self.twitterInviteCell; + case 2: return self.supportCell; + } + + return nil; +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + switch (indexPath.section) { + case 1: + [self tappedInviteTwitter]; + break; + case 2: + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://support.whispersystems.org"]]; + break; + + default: + break; + } +} + +- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { + return section == 2 ? self.footerView : nil; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { + return section == 2 ? 60.0f : 0; +} + +- (void)tappedInviteTwitter { + + if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) + { + SLComposeViewController *tweetSheet = [SLComposeViewController + composeViewControllerForServiceType:SLServiceTypeTwitter]; + + NSString *tweetString = [NSString stringWithFormat:@"You can reach me on @whispersystems Signal, get it now."]; + [tweetSheet setInitialText:tweetString]; + [tweetSheet addURL:[NSURL URLWithString:@"https://whispersystems.org/signal/install/"]]; + tweetSheet.completionHandler = ^(SLComposeViewControllerResult result) { + }; + [self presentViewController:tweetSheet animated:YES completion:nil]; + } + +} + +@end diff --git a/Signal/src/view controllers/AdvancedSettingsTableViewController.h b/Signal/src/view controllers/AdvancedSettingsTableViewController.h new file mode 100644 index 000000000..c27e58a46 --- /dev/null +++ b/Signal/src/view controllers/AdvancedSettingsTableViewController.h @@ -0,0 +1,13 @@ +// +// AdvancedSettingsTableViewController.h +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import + +@interface AdvancedSettingsTableViewController : UITableViewController + +@end diff --git a/Signal/src/view controllers/AdvancedSettingsTableViewController.m b/Signal/src/view controllers/AdvancedSettingsTableViewController.m new file mode 100644 index 000000000..1bcc90ef3 --- /dev/null +++ b/Signal/src/view controllers/AdvancedSettingsTableViewController.m @@ -0,0 +1,116 @@ +// +// AdvancedSettingsTableViewController.m +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import "AdvancedSettingsTableViewController.h" + +#import +#import "Environment.h" +#import "PreferencesUtil.h" +#import "DebugLogger.h" + + +@interface AdvancedSettingsTableViewController () + +@property (strong, nonatomic) UITableViewCell * enableLogCell; +@property (strong, nonatomic) UITableViewCell * submitLogCell; + +@property (strong, nonatomic) UISwitch * enableLogSwitch; +@end + +@implementation AdvancedSettingsTableViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero]; +} + +-(instancetype)init { + return [super initWithStyle:UITableViewStyleGrouped]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; +} + +-(void)loadView +{ + [super loadView]; + + self.title = @"Advanced"; + + //Enable Log + self.enableLogCell = [[UITableViewCell alloc]init]; + self.enableLogCell.textLabel.text = @"Enable Debug Log"; + self.enableLogCell.userInteractionEnabled = YES; + + self.enableLogSwitch = [[UISwitch alloc]initWithFrame:CGRectZero]; + [self.enableLogSwitch setOn:[Environment.preferences loggingIsEnabled]]; + [self.enableLogSwitch addTarget:self action:@selector(didToggleSwitch:) forControlEvents:UIControlEventTouchUpInside]; + + self.enableLogCell.accessoryView = self.enableLogSwitch; + + + //Send Log + self.submitLogCell = [[UITableViewCell alloc]init]; + self.submitLogCell.textLabel.text = @"Submit Debug Log"; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.enableLogSwitch.isOn ? 2 : 1; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return @"Logging"; +} + +-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + switch (indexPath.row) { + case 0: return self.enableLogCell; + case 1: return self.submitLogCell; + } + + NSAssert(false, @"No Cell configured"); + + return nil; +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + if (indexPath.row == 1) + { + [Pastelog submitLogs]; + } +} + +#pragma mark - Actions + +-(void)didToggleSwitch:(UISwitch*)sender +{ + if (!sender.isOn) { + [DebugLogger.sharedInstance disableFileLogging]; + [DebugLogger.sharedInstance wipeLogs]; + } else { + [DebugLogger.sharedInstance enableFileLogging]; + } + + [Environment.preferences setLoggingEnabled:sender.isOn]; + [self.tableView reloadData]; +} + +@end diff --git a/Signal/src/view controllers/MediaSettingsTableViewController.h b/Signal/src/view controllers/MediaSettingsTableViewController.h new file mode 100644 index 000000000..4e8e8f300 --- /dev/null +++ b/Signal/src/view controllers/MediaSettingsTableViewController.h @@ -0,0 +1,13 @@ +// +// MediaSettingsTableViewController.h +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import + +@interface MediaSettingsTableViewController : UITableViewController + +@end diff --git a/Signal/src/view controllers/MediaSettingsTableViewController.m b/Signal/src/view controllers/MediaSettingsTableViewController.m new file mode 100644 index 000000000..29c526870 --- /dev/null +++ b/Signal/src/view controllers/MediaSettingsTableViewController.m @@ -0,0 +1,144 @@ +// +// MediaSettingsTableViewController.m +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import "MediaSettingsTableViewController.h" + +#import "Environment.h" +#import "PreferencesUtil.h" + +@interface MediaSettingsTableViewController () + +@property (strong, nonatomic) UITableViewCell * uncroppedQualityCell; +@property (strong, nonatomic) UITableViewCell * highQualityCell; +@property (strong, nonatomic) UITableViewCell * averageQualityCell; +@property (strong, nonatomic) UITableViewCell * lowQualityCell; + +@property (strong, nonatomic) NSIndexPath * lastIndexPath; + +@end + +@implementation MediaSettingsTableViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero]; + [self showCheckmarkOnDefaultSetting:YES]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; +} + +-(instancetype)init +{ + return [super initWithStyle:UITableViewStyleGrouped]; +} + +-(void)loadView { + [super loadView]; + + self.title = @"Media"; + + //Uncropped + self.uncroppedQualityCell = [[UITableViewCell alloc]init]; + self.uncroppedQualityCell.textLabel.text = @"Uncropped"; + self.uncroppedQualityCell.selectionStyle = UITableViewCellSelectionStyleNone; + + //High + self.highQualityCell = [[UITableViewCell alloc]init]; + self.highQualityCell.textLabel.text = @"High"; + self.highQualityCell.selectionStyle = UITableViewCellSelectionStyleNone; + + //Average + self.averageQualityCell = [[UITableViewCell alloc]init]; + self.averageQualityCell.textLabel.text = @"Average"; + self.averageQualityCell.selectionStyle = UITableViewCellSelectionStyleNone; + + //Low + self.lowQualityCell = [[UITableViewCell alloc]init]; + self.lowQualityCell.textLabel.text = @"Low"; + self.lowQualityCell.selectionStyle = UITableViewCellSelectionStyleNone; + +} +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return 4; +} + +-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + switch (indexPath.row) { + case 0: return self.uncroppedQualityCell; + case 1: return self.highQualityCell; + case 2: return self.averageQualityCell; + case 3: return self.lowQualityCell; + default: return nil; + } +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return @"Image upload quality"; +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [self showCheckmarkOnDefaultSetting:NO]; + [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; + [self updateSettingWithSelectedIndexPath:indexPath]; +} + +-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; +} + +#pragma mark - Setting + +-(void)updateSettingWithSelectedIndexPath:(NSIndexPath*)indexPath +{ + switch (indexPath.row) { + case 0: + [Environment.preferences setImageUploadQuality:TSImageQualityUncropped]; + break; + case 1: + [Environment.preferences setImageUploadQuality:TSImageQualityHigh]; + break; + case 2: + [Environment.preferences setImageUploadQuality:TSImageQualityMedium]; + break; + case 3: + [Environment.preferences setImageUploadQuality:TSImageQualityLow]; + break; + default: + break; + } +} + +-(NSIndexPath*)indexPathForSetting:(TSImageQuality)setting +{ + switch (setting) { + case TSImageQualityUncropped: return [NSIndexPath indexPathForRow:0 inSection:0]; + case TSImageQualityHigh: return [NSIndexPath indexPathForRow:1 inSection:0]; + case TSImageQualityMedium: return [NSIndexPath indexPathForRow:2 inSection:0]; + case TSImageQualityLow: return [NSIndexPath indexPathForRow:3 inSection:0]; + } +} + +-(void)showCheckmarkOnDefaultSetting:(BOOL)show +{ + NSIndexPath * defaultIndexPath = [self indexPathForSetting:[Environment.preferences imageUploadQuality]]; + [self.tableView cellForRowAtIndexPath:defaultIndexPath].accessoryType = show ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; +} + +@end diff --git a/Signal/src/view controllers/MessagesViewController.h b/Signal/src/view controllers/MessagesViewController.h index adbfa6431..3772d923d 100644 --- a/Signal/src/view controllers/MessagesViewController.h +++ b/Signal/src/view controllers/MessagesViewController.h @@ -8,7 +8,7 @@ #import "JSQMessagesViewController.h" #import "JSQMessages.h" -#import "GroupModel.h" +#import "TSGroupModel.h" @class TSThread; @interface MessagesViewController : JSQMessagesViewController #import "TSGroupThread.h" -#import "GroupModel.h" +#import "TSGroupModel.h" @interface NewGroupViewController : UIViewController @@ -17,6 +17,6 @@ @property(nonatomic, strong) IBOutlet UITextField* nameGroupTextField; @property(nonatomic, strong) IBOutlet UIButton* groupImageButton; @property(nonatomic, strong) IBOutlet UIView* tapToDismissView; -@property(nonatomic, strong) GroupModel* groupModel; +@property(nonatomic, strong) TSGroupModel* groupModel; @end diff --git a/Signal/src/view controllers/NewGroupViewController.m b/Signal/src/view controllers/NewGroupViewController.m index 45b06eac9..472670c69 100644 --- a/Signal/src/view controllers/NewGroupViewController.m +++ b/Signal/src/view controllers/NewGroupViewController.m @@ -15,7 +15,7 @@ #import "Contact.h" -#import "GroupModel.h" +#import "TSGroupModel.h" #import "SecurityUtils.h" #import "SignalKeyingStorage.h" @@ -121,7 +121,7 @@ static NSString* const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue" #pragma mark - Actions -(void)createGroup { - GroupModel* model = [self makeGroup]; + TSGroupModel* model = [self makeGroup]; [Environment groupModel:model]; } @@ -132,13 +132,13 @@ static NSString* const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue" [mut addObjectsFromArray:[[contacts objectAtIndex:(NSUInteger)idx.row-1] textSecureIdentifiers]]; } [mut addObject:[SignalKeyingStorage.localNumber toE164]]; // Also add the originator - _groupModel = [[GroupModel alloc] initWithTitle:_nameGroupTextField.text memberIds:[NSMutableArray arrayWithArray:[[NSSet setWithArray:mut] allObjects]] image:_thread.groupModel.groupImage groupId:_thread.groupModel.groupId]; + _groupModel = [[TSGroupModel alloc] initWithTitle:_nameGroupTextField.text memberIds:[NSMutableArray arrayWithArray:[[NSSet setWithArray:mut] allObjects]] image:_thread.groupModel.groupImage groupId:_thread.groupModel.groupId]; [self performSegueWithIdentifier:kUnwindToMessagesViewSegue sender:self]; } --(GroupModel*)makeGroup { +-(TSGroupModel*)makeGroup { NSString* title = _nameGroupTextField.text; UIImage* img = _thread.groupModel.groupImage; NSMutableArray* mut = [[NSMutableArray alloc]init]; @@ -150,7 +150,7 @@ static NSString* const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue" [mut addObject:[SignalKeyingStorage.localNumber toE164]]; NSData* groupId = [SecurityUtils generateRandomBytes:16]; - return [[GroupModel alloc] initWithTitle:title memberIds:mut image:img groupId:groupId]; + return [[TSGroupModel alloc] initWithTitle:title memberIds:mut image:img groupId:groupId]; } -(IBAction)addGroupPhoto:(id)sender diff --git a/Signal/src/view controllers/NotificationPreviewViewController.h b/Signal/src/view controllers/NotificationPreviewViewController.h deleted file mode 100644 index d9e435316..000000000 --- a/Signal/src/view controllers/NotificationPreviewViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NotificationPreviewViewController.h -// Signal -// -// Created by Dylan Bourgeois on 09/12/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. -// - -#import - -@interface NotificationPreviewViewController : UITableViewController - -@end diff --git a/Signal/src/view controllers/NotificationPreviewViewController.m b/Signal/src/view controllers/NotificationPreviewViewController.m deleted file mode 100644 index 3e7e40967..000000000 --- a/Signal/src/view controllers/NotificationPreviewViewController.m +++ /dev/null @@ -1,118 +0,0 @@ -// -// NotificationPreviewViewController.m -// Signal -// -// Created by Dylan Bourgeois on 09/12/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. -// - -#import "NotificationPreviewViewController.h" -#import "UIUtil.h" - -#import "PreferencesUtil.h" -#import "Environment.h" - -@interface NotificationPreviewViewController () -@property (nonatomic) NSIndexPath *defaultSelectedIndexPath; -@end - -@implementation NotificationPreviewViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - self.navigationItem.title = @"Notification Style"; - self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; - self.clearsSelectionOnViewWillAppear = NO; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - NSInteger currentSetting = (NSInteger)[Environment.preferences notificationPreviewType]; - _defaultSelectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:currentSetting + 1]; - [self selectRowAtIndexPath:_defaultSelectedIndexPath]; -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return 4; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return 1; -} - -- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section -{ - UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view; - [header.textLabel setTextColor:[UIColor blackColor]]; - if (SYSTEM_VERSION_GREATER_THAN(_iOS_8_0_2)) { - [header.textLabel setFont:[UIFont ows_thinFontWithSize:14.0f]]; - } -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (_defaultSelectedIndexPath != nil && ![_defaultSelectedIndexPath isEqual:indexPath]) { - [self deselectRowAtIndexPath:_defaultSelectedIndexPath]; - _defaultSelectedIndexPath = nil; - } - - UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; - cell.accessoryType = UITableViewCellAccessoryCheckmark; - - switch (indexPath.section) { - case 1: - [Environment.preferences setNotificationPreviewType:NotificationNoNameNoPreview]; - break; - - case 2: - [Environment.preferences setNotificationPreviewType:NotificationNameNoPreview]; - break; - - case 3: - [Environment.preferences setNotificationPreviewType:NotificationNamePreview]; - break; - - default: - break; - } -} - -- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; - cell.accessoryType = UITableViewCellAccessoryNone; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (indexPath.section == 0) { - return 120.0f; - } else { - return 80.0f; - } -} - -#pragma mark - Cell selection proxy - -- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [self.tableView.delegate tableView:self.tableView didSelectRowAtIndexPath:indexPath]; -} - -- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [self.tableView.delegate tableView:self.tableView didDeselectRowAtIndexPath:indexPath]; -} - -@end diff --git a/Signal/src/view controllers/PrivacySettingsTableViewController.h b/Signal/src/view controllers/PrivacySettingsTableViewController.h new file mode 100644 index 000000000..7cd519e33 --- /dev/null +++ b/Signal/src/view controllers/PrivacySettingsTableViewController.h @@ -0,0 +1,13 @@ +// +// PrivacySettingsTableViewController.h +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import + +@interface PrivacySettingsTableViewController : UITableViewController + +@end diff --git a/Signal/src/view controllers/PrivacySettingsTableViewController.m b/Signal/src/view controllers/PrivacySettingsTableViewController.m new file mode 100644 index 000000000..9471b77a4 --- /dev/null +++ b/Signal/src/view controllers/PrivacySettingsTableViewController.m @@ -0,0 +1,202 @@ +// +// PrivacySettingsTableViewController.m +// Signal +// +// Created by Dylan Bourgeois on 05/01/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import "PrivacySettingsTableViewController.h" + +#import <25519/Curve25519.h> +#import "DJWActionSheet.h" +#import "Environment.h" +#import "PreferencesUtil.h" +#import "TSFingerprintGenerator.h" +#import "TSStorageManager+IdentityKeyStore.h" +#import "UIUtil.h" + +@interface PrivacySettingsTableViewController () + +@property (nonatomic, strong) UITableViewCell * enableScreenSecurityCell; +@property (nonatomic, strong) UITableViewCell * clearHistoryLogCell; +@property (nonatomic, strong) UITableViewCell * fingerprintCell; +@property (nonatomic, strong) UITableViewCell * shareFingerprintCell; + +@property (nonatomic, strong) UISwitch * enableScreenSecuritySwitch; + +@property (nonatomic, strong) UILabel * fingerprintLabel; + +@property (nonatomic, strong) NSTimer * copiedTimer; + +@end + +@implementation PrivacySettingsTableViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero]; +} + +-(instancetype)init +{ + return [super initWithStyle:UITableViewStyleGrouped]; +} + +-(void)loadView +{ + [super loadView]; + + self.title = @"Privacy"; + + //Enable Screen Security Cell + self.enableScreenSecurityCell = [[UITableViewCell alloc]init]; + self.enableScreenSecurityCell.textLabel.text = @"Enable Screen Security"; + + self.enableScreenSecuritySwitch = [[UISwitch alloc]initWithFrame:CGRectZero]; + + self.enableScreenSecurityCell.accessoryView = self.enableScreenSecuritySwitch; + self.enableScreenSecurityCell.userInteractionEnabled = YES; + + //Clear History Log Cell + self.clearHistoryLogCell = [[UITableViewCell alloc]init]; + self.clearHistoryLogCell.textLabel.text = @"Clear History Logs"; + self.clearHistoryLogCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + //Fingerprint Cell + self.fingerprintCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Identifier"]; + self.fingerprintCell.textLabel.text = @"Fingerprint"; + self.fingerprintCell.detailTextLabel.text = @"Tap to copy"; + self.fingerprintCell.detailTextLabel.textColor = [UIColor lightGrayColor]; + + self.fingerprintLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 150, 25)]; + self.fingerprintLabel.textColor = [UIColor lightGrayColor]; + self.fingerprintLabel.font = [UIFont ows_lightFontWithSize:16.0f]; + self.fingerprintLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + + self.fingerprintCell.accessoryView = self.fingerprintLabel; + + [self setValues]; + [self subsribeToEvents]; + +} + +-(void)subsribeToEvents +{ + [self.enableScreenSecuritySwitch addTarget:self action:@selector(didToggleSwitch:) forControlEvents:UIControlEventTouchUpInside]; +} + +-(void)setValues +{ + [self.enableScreenSecuritySwitch setOn:[Environment.preferences screenSecurityIsEnabled]]; + self.fingerprintLabel.text = [TSFingerprintGenerator getFingerprintForDisplay:[[TSStorageManager sharedManager]identityKeyPair].publicKey]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 3; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + switch (section) { + case 0: return 1; + case 1: return 1; + case 2: return 1; + default: return 0; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + switch (indexPath.section) { + case 0: return self.enableScreenSecurityCell; + case 1: return self.clearHistoryLogCell; + case 2: + switch (indexPath.row) { + case 0: return self.fingerprintCell; + case 1: return self.shareFingerprintCell; + } + } + + return nil; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + switch (section) { + case 0: return @"Screen Security"; + case 1: return @"History Log"; + case 2: return @"Fingerprint"; + default: return nil; + } +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + switch (indexPath.section) { + case 1: + { + [DJWActionSheet showInView:self.tabBarController.view + withTitle:@"Are you sure you want to delete all your history (messages, attachments, call history ...) ? This action cannot be reverted." + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:@"I'm sure." + otherButtonTitles:@[] + tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) { + [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (tappedButtonIndex == actionSheet.cancelButtonIndex) { + NSLog(@"User Cancelled"); + + } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex){ + [[TSStorageManager sharedManager] deleteThreadsAndMessages]; + } else { + NSLog(@"The user tapped button at index: %li", (long)tappedButtonIndex); + } + }]; + + break; + } + + case 2: + switch (indexPath.row) { + case 0: + { + //Timer to change label to copied (NSTextAttachment checkmark) + if (self.copiedTimer == nil) { + self.copiedTimer = [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(endTimer:) userInfo:nil repeats:NO]; + self.fingerprintCell.detailTextLabel.text = @"Copied !"; + } else { + self.fingerprintCell.detailTextLabel.text = @"Tap to copy"; + } + [[UIPasteboard generalPasteboard] setString:self.fingerprintLabel.text]; + break; + } + + default: + break; + } + break; + default: + break; + } +} + +#pragma mark - Toggle + +-(void)didToggleSwitch:(UISwitch*)sender +{ + [Environment.preferences setScreenSecurity:self.enableScreenSecuritySwitch.isOn]; +} + +#pragma mark - Timer + +-(void)endTimer:(id)sender +{ + self.fingerprintCell.detailTextLabel.text = @"Tap to copy"; + [self.copiedTimer invalidate]; + self.copiedTimer = nil; +} + +@end diff --git a/Signal/src/view controllers/SettingsTableViewController.h b/Signal/src/view controllers/SettingsTableViewController.h index cd0d277fd..a41cbcc24 100644 --- a/Signal/src/view controllers/SettingsTableViewController.h +++ b/Signal/src/view controllers/SettingsTableViewController.h @@ -11,5 +11,6 @@ @interface SettingsTableViewController : UITableViewController @property IBOutlet UILabel *registeredNumber; +@property IBOutlet UILabel *networkStatusLabel; @end diff --git a/Signal/src/view controllers/SettingsTableViewController.m b/Signal/src/view controllers/SettingsTableViewController.m index cc537a758..11bfe657a 100644 --- a/Signal/src/view controllers/SettingsTableViewController.m +++ b/Signal/src/view controllers/SettingsTableViewController.m @@ -14,10 +14,13 @@ #import "TSStorageManager.h" #import "Environment.h" #import "PreferencesUtil.h" +#import "UIUtil.h" #import #import "RPServerRequestsManager.h" +#import "TSSocketManager.h" + #import #import "Cryptography.h" @@ -27,29 +30,39 @@ #import "TSStorageManager.h" #import "TSStorageManager+IdentityKeyStore.h" +#import "PrivacySettingsTableViewController.h" +#import "MediaSettingsTableViewController.h" +#import "AdvancedSettingsTableViewController.h" +#import "AboutTableViewController.h" + #define kProfileCellHeight 87.0f -#define kStandardCellHeight 60.0f +#define kStandardCellHeight 44.0f -#define kNumberOfSections 2 +#define kNumberOfSections 4 -#define kMessageDisplayCellRow 1 -#define kImageQualitySettingRow 2 -#define kClearHistoryLogCellRow 3 -#define kShareFingerpintCellRow 4 -#define kSendDebugLogCellRow 6 -#define kUnregisterCell 7 +#define kRegisteredNumberRow 0 +#define kPrivacyRow 0 +#define kMediaRow 1 +#define kAdvancedRow 2 +#define kAboutRow 3 +#define kNetworkRow 0 +#define kUnregisterRow 0 typedef enum { - kProfileRows = 1, - kSecurityRows = 8, + kRegisteredRows = 1, + kGeneralRows = 4, + kNetworkStatusRows = 1, + kUnregisterRows = 1, } kRowsForSection; typedef enum { - kProfileSection, - kSecuritySection, + kRegisteredNumberSection, + kGeneralSection, + kNetworkStatusSection, + kUnregisterSection, } kSection; -@interface SettingsTableViewController () +@interface SettingsTableViewController () @end @@ -59,13 +72,16 @@ typedef enum { [super viewDidLoad]; self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero]; self.registeredNumber.text = [TSAccountManager registeredNumber]; + [self initializeObserver]; + [TSSocketManager sendNotification]; } -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; +-(void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:SocketOpenedNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:SocketClosedNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:SocketConnectingNotification object:nil]; } - #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -75,131 +91,101 @@ typedef enum { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { switch (section) { - case kProfileSection: - return kProfileRows; - break; - case kSecuritySection: - return kSecurityRows; - break; + case kRegisteredNumberSection: + return kRegisteredRows; + case kGeneralSection: + return kGeneralRows; + case kNetworkStatusSection: + return kNetworkStatusRows; + case kUnregisterSection: + return kUnregisterRows; default: return 0; - break; } } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { switch (indexPath.section) { - case kProfileSection: + case kRegisteredNumberSection: return kProfileCellHeight; - break; - default: return kStandardCellHeight; - break; } } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.section==kSecuritySection) - { - switch (indexPath.row) { - case kClearHistoryLogCellRow: - { - //Present more info - [DJWActionSheet showInView:self.tabBarController.view - withTitle:@"Are you sure you want to delete all your history (messages, attachments, call history ...)? This action cannot be reverted." - cancelButtonTitle:@"Cancel" - destructiveButtonTitle:@"I'm sure." - otherButtonTitles:@[] - tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) { - [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (tappedButtonIndex == actionSheet.cancelButtonIndex) { - NSLog(@"User Cancelled"); - - } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex){ - [[TSStorageManager sharedManager] deleteThreadsAndMessages]; - } else { - NSLog(@"The user tapped button at index: %li", (long)tappedButtonIndex); - } - }]; - - break; + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + switch (indexPath.section) { + case kGeneralSection: + { + switch (indexPath.row) { + case kPrivacyRow: + { + PrivacySettingsTableViewController * vc = [[PrivacySettingsTableViewController alloc]init]; + NSAssert(self.navigationController != nil, @"Navigation controller must not be nil"); + NSAssert(vc != nil, @"Privacy Settings View Controller must not be nil"); + [self.navigationController pushViewController:vc animated:YES]; + break; + } + case kMediaRow: + { + MediaSettingsTableViewController * vc = [[MediaSettingsTableViewController alloc]init]; + NSAssert(self.navigationController != nil, @"Navigation controller must not be nil"); + NSAssert(vc != nil, @"Media Settings View Controller must not be nil"); + [self.navigationController pushViewController:vc animated:YES]; + break; + } + case kAdvancedRow: + { + AdvancedSettingsTableViewController * vc = [[AdvancedSettingsTableViewController alloc]init]; + NSAssert(self.navigationController != nil, @"Navigation controller must not be nil"); + NSAssert(vc != nil, @"Advanced Settings View Controller must not be nil"); + [self.navigationController pushViewController:vc animated:YES]; + break; + } + case kAboutRow: + { + AboutTableViewController * vc = [[AboutTableViewController alloc]init]; + NSAssert(self.navigationController != nil, @"Navigation controller must not be nil"); + NSAssert(vc != nil, @"About View Controller must not be nil"); + [self.navigationController pushViewController:vc animated:YES]; + break; + } + default: + break; } - case kImageQualitySettingRow: - { - [DJWActionSheet showInView:self.tabBarController.view - withTitle:nil - cancelButtonTitle:@"Cancel" - destructiveButtonTitle:nil - otherButtonTitles:@[@"Uncompressed", @"High", @"Medium", @"Low"] - tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) { - [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (tappedButtonIndex == actionSheet.cancelButtonIndex) { - DDLogVerbose(@"User Cancelled <%s>", __PRETTY_FUNCTION__); - - } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) { - DDLogVerbose(@"Destructive button tapped <%s>", __PRETTY_FUNCTION__); - }else { - switch (tappedButtonIndex) { - case 0: - [Environment.preferences setImageUploadQuality:TSImageQualityUncropped]; - break; - case 1: - [Environment.preferences setImageUploadQuality:TSImageQualityHigh]; - break; - case 2: - [Environment.preferences setImageUploadQuality:TSImageQualityMedium]; - break; - case 3: - [Environment.preferences setImageUploadQuality:TSImageQualityLow]; - break; - default: - DDLogWarn(@"Illegal Image Quality Tapped in <%s>", __PRETTY_FUNCTION__); - break; - } - - SettingsTableViewCell * cell = (SettingsTableViewCell*)[tableView cellForRowAtIndexPath:indexPath]; - [cell updateImageQualityLabel]; - } - }]; - break; - } - case kShareFingerpintCellRow: { - if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) - { - SLComposeViewController *tweetSheet = [SLComposeViewController - composeViewControllerForServiceType:SLServiceTypeTwitter]; - NSData *myPublicKey = [[TSStorageManager sharedManager] identityKeyPair].publicKey; - NSString * tweetString = [NSString stringWithFormat:@"Verifying myself on Signal : %@", [self getFingerprintForTweet:myPublicKey]]; - [tweetSheet setInitialText:tweetString]; - [tweetSheet addURL:[NSURL URLWithString:@"https://whispersystems.org/signal/install/"]]; - tweetSheet.completionHandler = ^(SLComposeViewControllerResult result) { - if (result == SLComposeViewControllerResultCancelled) { - [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - } - }; - [self presentViewController:tweetSheet animated:YES completion:nil]; - } - break; - } - case kSendDebugLogCellRow: - [Pastelog submitLogs]; - break; - - case kUnregisterCell: - [TSAccountManager unregisterTextSecureWithSuccess:^{ - [[TSStorageManager sharedManager] wipe]; - exit(0); - } failure:^(NSError *error) { - SignalAlertView(@"Failed to unregister", @""); - }]; - break; - - default: - break; + break; } + + case kNetworkStatusSection: + { + break; + } + + case kUnregisterSection: + { + [TSAccountManager unregisterTextSecureWithSuccess:^{ + [[TSStorageManager sharedManager] wipe]; + exit(0); + } failure:^(NSError *error) { + SignalAlertView(@"Failed to unregister", @""); + }]; + break; + } + + default: + break; + } +} + +-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == kNetworkStatusSection) { + UIAlertView * info = [[UIAlertView alloc]initWithTitle:@"Network Status" message:@"You can check your network status by looking at the colored bar above your inbox." delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [info show]; } } @@ -224,5 +210,29 @@ typedef enum { return formattedFingerprint; } +#pragma mark - Socket Status Notifications + +-(void)initializeObserver +{ + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(socketDidOpen) name:SocketOpenedNotification object:nil]; + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(socketDidClose) name:SocketClosedNotification object:nil]; + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(socketIsConnecting) name:SocketConnectingNotification object:nil]; +} + +-(void)socketDidOpen { + self.networkStatusLabel.text = @"Connected"; + self.networkStatusLabel.textColor = [UIColor ows_greenColor]; +} + +-(void)socketDidClose { + self.networkStatusLabel.text = @"Offline"; + self.networkStatusLabel.textColor = [UIColor ows_redColor]; +} + +-(void)socketIsConnecting { + self.networkStatusLabel.text = @"Connecting"; + self.networkStatusLabel.textColor = [UIColor ows_yellowColor]; +} + @end diff --git a/Signal/src/view controllers/ShowGroupMembersViewController.h b/Signal/src/view controllers/ShowGroupMembersViewController.h index 6fc3213ab..12737d4ba 100644 --- a/Signal/src/view controllers/ShowGroupMembersViewController.h +++ b/Signal/src/view controllers/ShowGroupMembersViewController.h @@ -8,7 +8,7 @@ #import #import "TSGroupThread.h" -#import "GroupModel.h" +#import "TSGroupModel.h" @interface ShowGroupMembersViewController : UITableViewController diff --git a/Signal/src/view controllers/ShowGroupMembersViewController.m b/Signal/src/view controllers/ShowGroupMembersViewController.m index f44f3b827..4cd5cb71d 100644 --- a/Signal/src/view controllers/ShowGroupMembersViewController.m +++ b/Signal/src/view controllers/ShowGroupMembersViewController.m @@ -16,7 +16,7 @@ #import "Contact.h" -#import "GroupModel.h" +#import "TSGroupModel.h" #import "SecurityUtils.h" #import "SignalKeyingStorage.h" diff --git a/Signal/src/view controllers/GroupModel.h b/Signal/src/view controllers/TSGroupModel.h similarity index 56% rename from Signal/src/view controllers/GroupModel.h rename to Signal/src/view controllers/TSGroupModel.h index 9d85e57ee..5d98f2539 100644 --- a/Signal/src/view controllers/GroupModel.h +++ b/Signal/src/view controllers/TSGroupModel.h @@ -2,7 +2,7 @@ // GroupModel.h // Signal // -// Created by Dylan Bourgeois on 13/11/14. +// Created by Frederic Jacobs. // Copyright (c) 2014 Open Whisper Systems. All rights reserved. // @@ -11,17 +11,17 @@ -@interface GroupModel : TSYapDatabaseObject +@interface TSGroupModel : TSYapDatabaseObject @property (nonatomic, strong) NSMutableArray *groupMemberIds; @property (nonatomic, strong) UIImage *groupImage; @property (nonatomic, strong) NSString *groupName; @property (nonatomic, strong) NSData* groupId; --(instancetype)initWithTitle:(NSString*)title memberIds:(NSMutableArray*)members image:(UIImage*)image groupId:(NSData*)groupId; +- (instancetype)initWithTitle:(NSString*)title memberIds:(NSMutableArray*)members image:(UIImage*)image groupId:(NSData*)groupId; - (BOOL)isEqual:(id)other; -- (BOOL)isEqualToGroupModel:(GroupModel *)model; -- (NSString*) getInfoStringAboutUpdateTo:(GroupModel*)model; +- (BOOL)isEqualToGroupModel:(TSGroupModel *)model; +- (NSString*) getInfoStringAboutUpdateTo:(TSGroupModel*)model; @end diff --git a/Signal/src/view controllers/GroupModel.m b/Signal/src/view controllers/TSGroupModel.m similarity index 89% rename from Signal/src/view controllers/GroupModel.m rename to Signal/src/view controllers/TSGroupModel.m index 442e88c39..0b0a306a9 100644 --- a/Signal/src/view controllers/GroupModel.m +++ b/Signal/src/view controllers/TSGroupModel.m @@ -2,20 +2,20 @@ // GroupModel.m // Signal // -// Created by Dylan Bourgeois on 13/11/14. +// Created by Frederic Jacobs on 13/11/14. // Copyright (c) 2014 Open Whisper Systems. All rights reserved. // -#import "GroupModel.h" +#import "TSGroupModel.h" -@implementation GroupModel +@implementation TSGroupModel -(instancetype)initWithTitle:(NSString*)title memberIds:(NSMutableArray*)memberIds image:(UIImage*)image groupId:(NSData *)groupId{ - _groupName=title; + _groupName = title; _groupMemberIds = [memberIds copy]; - _groupImage = image; - _groupId = groupId; - + _groupImage = image; + _groupId = groupId; + return self; } @@ -29,7 +29,7 @@ return [self isEqualToGroupModel:other]; } -- (BOOL)isEqualToGroupModel:(GroupModel *)other { +- (BOOL)isEqualToGroupModel:(TSGroupModel *)other { if (self == other) return YES; if(![_groupId isEqualToData:other.groupId] ) { @@ -49,7 +49,7 @@ return YES; } -- (NSString*) getInfoStringAboutUpdateTo:(GroupModel*)newModel { +- (NSString*) getInfoStringAboutUpdateTo:(TSGroupModel*)newModel { NSString* updatedGroupInfoString = @"Group updated. "; if (self == newModel) { return updatedGroupInfoString; @@ -81,6 +81,4 @@ return updatedGroupInfoString; } - - @end diff --git a/Signal/src/view controllers/UITests/SignalsViewController.h b/Signal/src/view controllers/UITests/SignalsViewController.h index 1e46d29b2..6f2cf19ca 100644 --- a/Signal/src/view controllers/UITests/SignalsViewController.h +++ b/Signal/src/view controllers/UITests/SignalsViewController.h @@ -10,12 +10,12 @@ #import #import "Contact.h" -#import "GroupModel.h" +#import "TSGroupModel.h" @interface SignalsViewController : UIViewController @property (nonatomic) NSString *contactIdentifierFromCompose; -@property (nonatomic) GroupModel *groupFromCompose; +@property (nonatomic) TSGroupModel *groupFromCompose; @property (nonatomic, retain) IBOutlet UITableView *tableView; @property (nonatomic, retain) IBOutlet UISegmentedControl *inboxArchiveSwitch;