Initial Message UI
2
Podfile
|
@ -10,3 +10,5 @@ pod 'libPhoneNumber-iOS', '~> 0.7'
|
|||
pod 'PastelogKit', '~> 1.2'
|
||||
pod 'AFNetworking', '~> 2.4.1'
|
||||
pod 'TwistedOakCollapsingFutures','~> 1.0'
|
||||
pod 'JSQMessagesViewController', :git => 'https://github.com/dtsbourg/JSQMessagesViewController', :branch => 'JSignalQ'
|
||||
pod 'DJWActionSheet'
|
||||
|
|
12
Podfile.lock
|
@ -25,6 +25,10 @@ PODS:
|
|||
- CocoaLumberjack/Core (1.9.2)
|
||||
- CocoaLumberjack/Extensions (1.9.2):
|
||||
- CocoaLumberjack/Core
|
||||
- DJWActionSheet (1.0.4)
|
||||
- JSQMessagesViewController (6.0-beta6):
|
||||
- JSQSystemSoundPlayer (~> 2.0.0)
|
||||
- JSQSystemSoundPlayer (2.0.0)
|
||||
- libPhoneNumber-iOS (0.7.3)
|
||||
- MMDrawerController (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
|
@ -48,6 +52,8 @@ PODS:
|
|||
|
||||
DEPENDENCIES:
|
||||
- AFNetworking (~> 2.4.1)
|
||||
- DJWActionSheet
|
||||
- JSQMessagesViewController (from `https://github.com/dtsbourg/JSQMessagesViewController`, branch `JSignalQ`)
|
||||
- libPhoneNumber-iOS (~> 0.7)
|
||||
- MMDrawerController (~> 0.5.7)
|
||||
- OpenSSL (~> 1.0.109)
|
||||
|
@ -56,12 +62,18 @@ DEPENDENCIES:
|
|||
- UICKeyChainStore (from `Podspecs/UICKeyChainStore.podspec`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
JSQMessagesViewController:
|
||||
:branch: JSignalQ
|
||||
:git: https://github.com/dtsbourg/JSQMessagesViewController
|
||||
UICKeyChainStore:
|
||||
:podspec: Podspecs/UICKeyChainStore.podspec
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AFNetworking: 0aabc6fae66d6e5d039eeb21c315843c7aae51ab
|
||||
CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817
|
||||
DJWActionSheet: d88b302d7c29523e1e9fb9b62cfac46f59bb90d9
|
||||
JSQMessagesViewController: 960a09d11978bea52d1a676e97980838f8d98652
|
||||
JSQSystemSoundPlayer: c98443b1cbb3b45db09d0d3d6c2355cf78294981
|
||||
libPhoneNumber-iOS: 98fc07d70c8fdb5e6a8e3442c37e97353065c20e
|
||||
MMDrawerController: c3ab7a318ddc7e2bcd133139c3161af08c6e1197
|
||||
OpenSSL: 4810adf5c99b0e2cd20670a11a987c805e8a521c
|
||||
|
|
|
@ -406,7 +406,6 @@
|
|||
D2179CFE16BB0B480006F3AB /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2179CFD16BB0B480006F3AB /* SystemConfiguration.framework */; };
|
||||
D221A08E169C9E5E00537ABF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D221A08D169C9E5E00537ABF /* UIKit.framework */; };
|
||||
D221A090169C9E5E00537ABF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D221A08F169C9E5E00537ABF /* Foundation.framework */; };
|
||||
D221A092169C9E5E00537ABF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D221A091169C9E5E00537ABF /* CoreGraphics.framework */; };
|
||||
D221A09A169C9E5E00537ABF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D221A099169C9E5E00537ABF /* main.m */; };
|
||||
D221A0AD169C9E5F00537ABF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D221A08D169C9E5E00537ABF /* UIKit.framework */; };
|
||||
D221A0AE169C9E5F00537ABF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D221A08F169C9E5E00537ABF /* Foundation.framework */; };
|
||||
|
@ -576,6 +575,61 @@
|
|||
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 */; };
|
||||
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 */; };
|
||||
FC4F9FE51A16258C00DA100A /* logo_intro@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FE41A16258C00DA100A /* logo_intro@2x.png */; };
|
||||
FC4F9FED1A1658EE00DA100A /* call@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FEC1A1658EE00DA100A /* call@2x.png */; };
|
||||
FC4F9FF31A1664EA00DA100A /* mute_off@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FEE1A1664EA00DA100A /* mute_off@2x.png */; };
|
||||
FC4F9FF41A1664EA00DA100A /* speaker_off@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FEF1A1664EA00DA100A /* speaker_off@2x.png */; };
|
||||
FC4F9FF51A1664EA00DA100A /* speaker_on@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FF01A1664EA00DA100A /* speaker_on@2x.png */; };
|
||||
FC4F9FF61A1664EA00DA100A /* mute_on@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FF11A1664EA00DA100A /* mute_on@2x.png */; };
|
||||
FC4F9FF71A1664EA00DA100A /* endcall@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FF21A1664EA00DA100A /* endcall@2x.png */; };
|
||||
FC4F9FFD1A179FCF00DA100A /* lock@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FFC1A179FCF00DA100A /* lock@2x.png */; };
|
||||
FC4F9FFF1A17A39E00DA100A /* photo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4F9FFE1A17A39E00DA100A /* photo@2x.png */; };
|
||||
FC4FA0071A18BDAE00DA100A /* info@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4FA0061A18BDAE00DA100A /* info@2x.png */; };
|
||||
FC4FA0091A18BF3100DA100A /* lock_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4FA0081A18BF3100DA100A /* lock_white@2x.png */; };
|
||||
FC4FA00D1A18CC4300DA100A /* shred@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4FA00C1A18CC4300DA100A /* shred@2x.png */; };
|
||||
FC4FA0171A1A180D00DA100A /* red-delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4FA0131A1A180D00DA100A /* red-delete@2x.png */; };
|
||||
FC4FA0181A1A180D00DA100A /* delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4FA0141A1A180D00DA100A /* delete@2x.png */; };
|
||||
FC4FA0191A1A180D00DA100A /* archive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4FA0151A1A180D00DA100A /* archive@2x.png */; };
|
||||
FC4FA01A1A1A180D00DA100A /* blue-archive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC4FA0161A1A180D00DA100A /* blue-archive@2x.png */; };
|
||||
FC4FA0231A1B8A8D00DA100A /* Socket.m in Sources */ = {isa = PBXBuildFile; fileRef = FC4FA0221A1B8A8D00DA100A /* Socket.m */; };
|
||||
FC4FA0261A1B9DC600DA100A /* SignalsNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC4FA0251A1B9DC600DA100A /* SignalsNavigationController.m */; };
|
||||
FCAC963519FEF4E20046DFC5 /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FCAC963419FEF4E20046DFC5 /* Storyboard.storyboard */; };
|
||||
FCAC963C19FEF9280046DFC5 /* SignalsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC963B19FEF9280046DFC5 /* SignalsViewController.m */; };
|
||||
FCAC964019FEF99A0046DFC5 /* TableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC963E19FEF99A0046DFC5 /* TableViewCell.m */; };
|
||||
FCAC964119FEF99A0046DFC5 /* TableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FCAC963F19FEF99A0046DFC5 /* TableViewCell.xib */; };
|
||||
FCAC964419FEFD8B0046DFC5 /* DemoDataFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC964319FEFD8B0046DFC5 /* DemoDataFactory.m */; };
|
||||
FCAC964719FEFE1A0046DFC5 /* DemoDataModel.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC964619FEFE1A0046DFC5 /* DemoDataModel.m */; };
|
||||
FCAC965119FF0A6E0046DFC5 /* MessagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC965019FF0A6E0046DFC5 /* MessagesViewController.m */; };
|
||||
FCAFC2EC1A0C469C00AE5136 /* checkmark.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC2EB1A0C469C00AE5136 /* checkmark.png */; };
|
||||
FCAFC2EE1A0C472200AE5136 /* reply.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC2ED1A0C472200AE5136 /* reply.png */; };
|
||||
FCAFC2F11A0C4ACF00AE5136 /* received.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC2EF1A0C4ACF00AE5136 /* received.png */; };
|
||||
FCAFC2F21A0C4ACF00AE5136 /* missed.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC2F01A0C4ACF00AE5136 /* missed.png */; };
|
||||
FCAFC30C1A0C560E00AE5136 /* signals.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC3091A0C560E00AE5136 /* signals.png */; };
|
||||
FCAFC30D1A0C560E00AE5136 /* settings.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC30A1A0C560E00AE5136 /* settings.png */; };
|
||||
FCAFC3211A0D394300AE5136 /* favourite.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC3201A0D394300AE5136 /* favourite.png */; };
|
||||
FCAFC3281A0D466F00AE5136 /* delete_history@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC3251A0D466F00AE5136 /* delete_history@2x.png */; };
|
||||
FCAFC3291A0D466F00AE5136 /* signal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC3261A0D466F00AE5136 /* signal@2x.png */; };
|
||||
FCAFC32A1A0D466F00AE5136 /* call_dark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC3271A0D466F00AE5136 /* call_dark@2x.png */; };
|
||||
FCAFC32E1A0D46D500AE5136 /* settings_dark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC32D1A0D46D500AE5136 /* settings_dark@2x.png */; };
|
||||
FCAFC3301A0D5E3000AE5136 /* share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC32F1A0D5E3000AE5136 /* share@2x.png */; };
|
||||
FCAFC3341A0D656100AE5136 /* contacts_tab@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC3331A0D656100AE5136 /* contacts_tab@2x.png */; };
|
||||
FCAFC3361A0D680100AE5136 /* keypad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCAFC3351A0D680100AE5136 /* keypad@2x.png */; };
|
||||
FCAFC33F1A0F948F00AE5136 /* ActionContactDetailCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAFC33E1A0F948F00AE5136 /* ActionContactDetailCell.m */; };
|
||||
FCB11D8A1A1284BB002F93FB /* SettingsTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FCB11D891A1284BB002F93FB /* SettingsTableViewCell.m */; };
|
||||
FCB11D8C1A129A76002F93FB /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCB11D8B1A129A76002F93FB /* CoreMedia.framework */; };
|
||||
FCB11D8F1A12A388002F93FB /* savephoto@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCB11D8D1A12A388002F93FB /* savephoto@2x.png */; };
|
||||
FCB11D901A12A388002F93FB /* quit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCB11D8E1A12A388002F93FB /* quit@2x.png */; };
|
||||
FCB11D931A12A4AA002F93FB /* FullImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCB11D921A12A4AA002F93FB /* FullImageViewController.m */; };
|
||||
FCF72A081A01A765006BC849 /* ContactsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCF72A071A01A765006BC849 /* ContactsTableViewController.m */; };
|
||||
FCF72A131A02D27F006BC849 /* ContactDetailTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCF72A111A02D27F006BC849 /* ContactDetailTableViewController.m */; };
|
||||
FCF72A161A02D2BB006BC849 /* ContactDetailCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FCF72A151A02D2BB006BC849 /* ContactDetailCell.m */; };
|
||||
FCFD256F1A151BCB00F4C644 /* NewGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFD256E1A151BCB00F4C644 /* NewGroupViewController.m */; };
|
||||
FCFD25721A1524DB00F4C644 /* GroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFD25711A1524DB00F4C644 /* GroupModel.m */; };
|
||||
FCFD257F1A154B2C00F4C644 /* RegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFD257E1A154B2C00F4C644 /* RegistrationViewController.m */; };
|
||||
FCFD25821A154B3800F4C644 /* CodeVerificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCFD25811A154B3800F4C644 /* CodeVerificationViewController.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -1287,6 +1341,81 @@
|
|||
E1C407C117F0C246007BEE65 /* whisperReal.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperReal.cer; sourceTree = "<group>"; };
|
||||
E1CD329418BCFF9900B1A496 /* SoundInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoundInstance.h; sourceTree = "<group>"; };
|
||||
E1CD329518BCFF9900B1A496 /* SoundInstance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SoundInstance.m; sourceTree = "<group>"; };
|
||||
FC3196281A067D8F0094C78E /* MessageComposeTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageComposeTableViewController.h; sourceTree = "<group>"; };
|
||||
FC3196291A067D8F0094C78E /* MessageComposeTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageComposeTableViewController.m; sourceTree = "<group>"; };
|
||||
FC31962B1A06A2190094C78E /* FingerprintViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerprintViewController.h; sourceTree = "<group>"; };
|
||||
FC31962C1A06A2190094C78E /* FingerprintViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FingerprintViewController.m; sourceTree = "<group>"; };
|
||||
FC31962E1A0814130094C78E /* SettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsTableViewController.h; sourceTree = "<group>"; };
|
||||
FC31962F1A0814130094C78E /* SettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsTableViewController.m; sourceTree = "<group>"; };
|
||||
FC4F9FE41A16258C00DA100A /* logo_intro@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo_intro@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FEC1A1658EE00DA100A /* call@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FEE1A1664EA00DA100A /* mute_off@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mute_off@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FEF1A1664EA00DA100A /* speaker_off@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_off@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FF01A1664EA00DA100A /* speaker_on@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_on@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FF11A1664EA00DA100A /* mute_on@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mute_on@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FF21A1664EA00DA100A /* endcall@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "endcall@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FFC1A179FCF00DA100A /* lock@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lock@2x.png"; sourceTree = "<group>"; };
|
||||
FC4F9FFE1A17A39E00DA100A /* photo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "photo@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA0061A18BDAE00DA100A /* info@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA0081A18BF3100DA100A /* lock_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lock_white@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA00C1A18CC4300DA100A /* shred@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shred@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA0131A1A180D00DA100A /* red-delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "red-delete@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA0141A1A180D00DA100A /* delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA0151A1A180D00DA100A /* archive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "archive@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA0161A1A180D00DA100A /* blue-archive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blue-archive@2x.png"; sourceTree = "<group>"; };
|
||||
FC4FA0211A1B8A8D00DA100A /* Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Socket.h; sourceTree = "<group>"; };
|
||||
FC4FA0221A1B8A8D00DA100A /* Socket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Socket.m; sourceTree = "<group>"; };
|
||||
FC4FA0241A1B9DC600DA100A /* SignalsNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalsNavigationController.h; sourceTree = "<group>"; };
|
||||
FC4FA0251A1B9DC600DA100A /* SignalsNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsNavigationController.m; sourceTree = "<group>"; };
|
||||
FCAC963419FEF4E20046DFC5 /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Storyboard.storyboard; path = Signal/src/Storyboard/Storyboard.storyboard; sourceTree = SOURCE_ROOT; };
|
||||
FCAC963A19FEF9280046DFC5 /* SignalsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SignalsViewController.h; path = UITests/SignalsViewController.h; sourceTree = "<group>"; };
|
||||
FCAC963B19FEF9280046DFC5 /* SignalsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SignalsViewController.m; path = UITests/SignalsViewController.m; sourceTree = "<group>"; };
|
||||
FCAC963D19FEF99A0046DFC5 /* TableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewCell.h; sourceTree = "<group>"; };
|
||||
FCAC963E19FEF99A0046DFC5 /* TableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewCell.m; sourceTree = "<group>"; };
|
||||
FCAC963F19FEF99A0046DFC5 /* TableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TableViewCell.xib; sourceTree = "<group>"; };
|
||||
FCAC964219FEFD8B0046DFC5 /* DemoDataFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoDataFactory.h; sourceTree = "<group>"; };
|
||||
FCAC964319FEFD8B0046DFC5 /* DemoDataFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoDataFactory.m; sourceTree = "<group>"; };
|
||||
FCAC964519FEFE1A0046DFC5 /* DemoDataModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoDataModel.h; sourceTree = "<group>"; };
|
||||
FCAC964619FEFE1A0046DFC5 /* DemoDataModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoDataModel.m; sourceTree = "<group>"; };
|
||||
FCAC964F19FF0A6E0046DFC5 /* MessagesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagesViewController.h; sourceTree = "<group>"; };
|
||||
FCAC965019FF0A6E0046DFC5 /* MessagesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessagesViewController.m; sourceTree = "<group>"; };
|
||||
FCAFC2EB1A0C469C00AE5136 /* checkmark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkmark.png; sourceTree = "<group>"; };
|
||||
FCAFC2ED1A0C472200AE5136 /* reply.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = reply.png; sourceTree = "<group>"; };
|
||||
FCAFC2EF1A0C4ACF00AE5136 /* received.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = received.png; sourceTree = "<group>"; };
|
||||
FCAFC2F01A0C4ACF00AE5136 /* missed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = missed.png; sourceTree = "<group>"; };
|
||||
FCAFC3091A0C560E00AE5136 /* signals.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = signals.png; sourceTree = "<group>"; };
|
||||
FCAFC30A1A0C560E00AE5136 /* settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = settings.png; sourceTree = "<group>"; };
|
||||
FCAFC3201A0D394300AE5136 /* favourite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = favourite.png; sourceTree = "<group>"; };
|
||||
FCAFC3251A0D466F00AE5136 /* delete_history@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete_history@2x.png"; sourceTree = "<group>"; };
|
||||
FCAFC3261A0D466F00AE5136 /* signal@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "signal@2x.png"; sourceTree = "<group>"; };
|
||||
FCAFC3271A0D466F00AE5136 /* call_dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_dark@2x.png"; sourceTree = "<group>"; };
|
||||
FCAFC32D1A0D46D500AE5136 /* settings_dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings_dark@2x.png"; sourceTree = "<group>"; };
|
||||
FCAFC32F1A0D5E3000AE5136 /* share@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "share@2x.png"; sourceTree = "<group>"; };
|
||||
FCAFC3331A0D656100AE5136 /* contacts_tab@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_tab@2x.png"; sourceTree = "<group>"; };
|
||||
FCAFC3351A0D680100AE5136 /* keypad@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keypad@2x.png"; sourceTree = "<group>"; };
|
||||
FCAFC33D1A0F948F00AE5136 /* ActionContactDetailCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActionContactDetailCell.h; sourceTree = "<group>"; };
|
||||
FCAFC33E1A0F948F00AE5136 /* ActionContactDetailCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ActionContactDetailCell.m; sourceTree = "<group>"; };
|
||||
FCB11D881A1284BB002F93FB /* SettingsTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsTableViewCell.h; sourceTree = "<group>"; };
|
||||
FCB11D891A1284BB002F93FB /* SettingsTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsTableViewCell.m; sourceTree = "<group>"; };
|
||||
FCB11D8B1A129A76002F93FB /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
|
||||
FCB11D8D1A12A388002F93FB /* savephoto@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "savephoto@2x.png"; sourceTree = "<group>"; };
|
||||
FCB11D8E1A12A388002F93FB /* quit@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quit@2x.png"; sourceTree = "<group>"; };
|
||||
FCB11D911A12A4AA002F93FB /* FullImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullImageViewController.h; sourceTree = "<group>"; };
|
||||
FCB11D921A12A4AA002F93FB /* FullImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FullImageViewController.m; sourceTree = "<group>"; };
|
||||
FCF72A061A01A765006BC849 /* ContactsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTableViewController.h; sourceTree = "<group>"; };
|
||||
FCF72A071A01A765006BC849 /* ContactsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsTableViewController.m; sourceTree = "<group>"; };
|
||||
FCF72A111A02D27F006BC849 /* ContactDetailTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailTableViewController.m; sourceTree = "<group>"; };
|
||||
FCF72A121A02D27F006BC849 /* ContactDetailTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailTableViewController.h; sourceTree = "<group>"; };
|
||||
FCF72A141A02D2BB006BC849 /* ContactDetailCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailCell.h; sourceTree = "<group>"; };
|
||||
FCF72A151A02D2BB006BC849 /* ContactDetailCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailCell.m; sourceTree = "<group>"; };
|
||||
FCFD256D1A151BCB00F4C644 /* NewGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewGroupViewController.h; sourceTree = "<group>"; };
|
||||
FCFD256E1A151BCB00F4C644 /* NewGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewGroupViewController.m; sourceTree = "<group>"; };
|
||||
FCFD25701A1524DB00F4C644 /* GroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupModel.h; sourceTree = "<group>"; };
|
||||
FCFD25711A1524DB00F4C644 /* GroupModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupModel.m; sourceTree = "<group>"; };
|
||||
FCFD257D1A154B2C00F4C644 /* RegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationViewController.h; sourceTree = "<group>"; };
|
||||
FCFD257E1A154B2C00F4C644 /* RegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationViewController.m; sourceTree = "<group>"; };
|
||||
FCFD25801A154B3800F4C644 /* CodeVerificationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeVerificationViewController.h; sourceTree = "<group>"; };
|
||||
FCFD25811A154B3800F4C644 /* CodeVerificationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeVerificationViewController.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -1294,6 +1423,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FCB11D8C1A129A76002F93FB /* CoreMedia.framework in Frameworks */,
|
||||
70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */,
|
||||
70B800AF190C548D0042E3F0 /* libspeex.a in Frameworks */,
|
||||
70B800A6190C53180042E3F0 /* libspandsp.a in Frameworks */,
|
||||
|
@ -1309,7 +1439,6 @@
|
|||
D2179CFC16BB0B3A0006F3AB /* CoreTelephony.framework in Frameworks */,
|
||||
D221A08E169C9E5E00537ABF /* UIKit.framework in Frameworks */,
|
||||
D221A090169C9E5E00537ABF /* Foundation.framework in Frameworks */,
|
||||
D221A092169C9E5E00537ABF /* CoreGraphics.framework in Frameworks */,
|
||||
D221A0E8169DFFC500537ABF /* AVFoundation.framework in Frameworks */,
|
||||
D24B5BD5169F568C00681372 /* AudioToolbox.framework in Frameworks */,
|
||||
F995AC2FFD6D4442B012604A /* libPods.a in Frameworks */,
|
||||
|
@ -1556,6 +1685,8 @@
|
|||
76EB03C118170B33006006FC /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCAC963419FEF4E20046DFC5 /* Storyboard.storyboard */,
|
||||
FCAC963919FEF8A00046DFC5 /* UI Tests */,
|
||||
76EB03C218170B33006006FC /* AppDelegate.h */,
|
||||
76EB03C318170B33006006FC /* AppDelegate.m */,
|
||||
76EB03D918170B33006006FC /* audio */,
|
||||
|
@ -2800,7 +2931,7 @@
|
|||
D221A08C169C9E5E00537ABF /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B60EDE031A05A01700D73516 /* AudioToolbox.framework */,
|
||||
FCB11D8B1A129A76002F93FB /* CoreMedia.framework */,
|
||||
B69CD25019773E79005CE69A /* XCTest.framework */,
|
||||
70377AAA1918450100CAF501 /* MobileCoreServices.framework */,
|
||||
B9EB5ABC1884C002007CBB57 /* MessageUI.framework */,
|
||||
|
@ -2843,6 +2974,7 @@
|
|||
D221A094169C9E5E00537ABF /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCAFC2F91A0C4E1700AE5136 /* icons8 */,
|
||||
B6B6C3C419193F5B00C0B76B /* Translations */,
|
||||
E18AB40618A05754001A532A /* AudioFiles */,
|
||||
E1370BDA18A066F600826894 /* Default-568h@2x.png */,
|
||||
|
@ -2954,6 +3086,150 @@
|
|||
path = utilities;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FC3196311A08141D0094C78E /* Settings */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FC31962E1A0814130094C78E /* SettingsTableViewController.h */,
|
||||
FC31962F1A0814130094C78E /* SettingsTableViewController.m */,
|
||||
);
|
||||
name = Settings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FC3196321A08142D0094C78E /* Signals */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FC3196281A067D8F0094C78E /* MessageComposeTableViewController.h */,
|
||||
FC3196291A067D8F0094C78E /* MessageComposeTableViewController.m */,
|
||||
FCAC963A19FEF9280046DFC5 /* SignalsViewController.h */,
|
||||
FCAC963B19FEF9280046DFC5 /* SignalsViewController.m */,
|
||||
FCAC964F19FF0A6E0046DFC5 /* MessagesViewController.h */,
|
||||
FCAC965019FF0A6E0046DFC5 /* MessagesViewController.m */,
|
||||
FC31962B1A06A2190094C78E /* FingerprintViewController.h */,
|
||||
FC31962C1A06A2190094C78E /* FingerprintViewController.m */,
|
||||
FCB11D911A12A4AA002F93FB /* FullImageViewController.h */,
|
||||
FCB11D921A12A4AA002F93FB /* FullImageViewController.m */,
|
||||
FCFD256D1A151BCB00F4C644 /* NewGroupViewController.h */,
|
||||
FCFD256E1A151BCB00F4C644 /* NewGroupViewController.m */,
|
||||
FC4FA0241A1B9DC600DA100A /* SignalsNavigationController.h */,
|
||||
FC4FA0251A1B9DC600DA100A /* SignalsNavigationController.m */,
|
||||
);
|
||||
name = Signals;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FC3196331A0814360094C78E /* Contacts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCF72A121A02D27F006BC849 /* ContactDetailTableViewController.h */,
|
||||
FCF72A111A02D27F006BC849 /* ContactDetailTableViewController.m */,
|
||||
FCF72A061A01A765006BC849 /* ContactsTableViewController.h */,
|
||||
FCF72A071A01A765006BC849 /* ContactsTableViewController.m */,
|
||||
);
|
||||
name = Contacts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FCAC963919FEF8A00046DFC5 /* UI Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCAC964819FEFE210046DFC5 /* DemoData */,
|
||||
FCAC964E19FF061C0046DFC5 /* ViewControllers */,
|
||||
FCAC964D19FF06110046DFC5 /* Views */,
|
||||
);
|
||||
name = "UI Tests";
|
||||
path = "view controllers";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FCAC964819FEFE210046DFC5 /* DemoData */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCAC964219FEFD8B0046DFC5 /* DemoDataFactory.h */,
|
||||
FCAC964319FEFD8B0046DFC5 /* DemoDataFactory.m */,
|
||||
FCAC964519FEFE1A0046DFC5 /* DemoDataModel.h */,
|
||||
FCAC964619FEFE1A0046DFC5 /* DemoDataModel.m */,
|
||||
FCFD25701A1524DB00F4C644 /* GroupModel.h */,
|
||||
FCFD25711A1524DB00F4C644 /* GroupModel.m */,
|
||||
FC4FA0211A1B8A8D00DA100A /* Socket.h */,
|
||||
FC4FA0221A1B8A8D00DA100A /* Socket.m */,
|
||||
);
|
||||
name = DemoData;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FCAC964D19FF06110046DFC5 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCF72A141A02D2BB006BC849 /* ContactDetailCell.h */,
|
||||
FCF72A151A02D2BB006BC849 /* ContactDetailCell.m */,
|
||||
FCAC963D19FEF99A0046DFC5 /* TableViewCell.h */,
|
||||
FCAC963E19FEF99A0046DFC5 /* TableViewCell.m */,
|
||||
FCAC963F19FEF99A0046DFC5 /* TableViewCell.xib */,
|
||||
FCAFC33D1A0F948F00AE5136 /* ActionContactDetailCell.h */,
|
||||
FCAFC33E1A0F948F00AE5136 /* ActionContactDetailCell.m */,
|
||||
FCB11D881A1284BB002F93FB /* SettingsTableViewCell.h */,
|
||||
FCB11D891A1284BB002F93FB /* SettingsTableViewCell.m */,
|
||||
);
|
||||
name = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FCAC964E19FF061C0046DFC5 /* ViewControllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCFD25791A1543D500F4C644 /* Signup */,
|
||||
FC3196321A08142D0094C78E /* Signals */,
|
||||
FC3196331A0814360094C78E /* Contacts */,
|
||||
FC3196311A08141D0094C78E /* Settings */,
|
||||
);
|
||||
name = ViewControllers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FCAFC2F91A0C4E1700AE5136 /* icons8 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FC4FA0131A1A180D00DA100A /* red-delete@2x.png */,
|
||||
FC4FA0141A1A180D00DA100A /* delete@2x.png */,
|
||||
FC4FA0151A1A180D00DA100A /* archive@2x.png */,
|
||||
FC4FA0161A1A180D00DA100A /* blue-archive@2x.png */,
|
||||
FC4FA00C1A18CC4300DA100A /* shred@2x.png */,
|
||||
FC4FA0081A18BF3100DA100A /* lock_white@2x.png */,
|
||||
FC4FA0061A18BDAE00DA100A /* info@2x.png */,
|
||||
FC4F9FFE1A17A39E00DA100A /* photo@2x.png */,
|
||||
FC4F9FFC1A179FCF00DA100A /* lock@2x.png */,
|
||||
FC4F9FEE1A1664EA00DA100A /* mute_off@2x.png */,
|
||||
FC4F9FEF1A1664EA00DA100A /* speaker_off@2x.png */,
|
||||
FC4F9FF01A1664EA00DA100A /* speaker_on@2x.png */,
|
||||
FC4F9FF11A1664EA00DA100A /* mute_on@2x.png */,
|
||||
FC4F9FF21A1664EA00DA100A /* endcall@2x.png */,
|
||||
FC4F9FEC1A1658EE00DA100A /* call@2x.png */,
|
||||
FC4F9FE41A16258C00DA100A /* logo_intro@2x.png */,
|
||||
FCB11D8D1A12A388002F93FB /* savephoto@2x.png */,
|
||||
FCB11D8E1A12A388002F93FB /* quit@2x.png */,
|
||||
FCAFC3351A0D680100AE5136 /* keypad@2x.png */,
|
||||
FCAFC3331A0D656100AE5136 /* contacts_tab@2x.png */,
|
||||
FCAFC32F1A0D5E3000AE5136 /* share@2x.png */,
|
||||
FCAFC32D1A0D46D500AE5136 /* settings_dark@2x.png */,
|
||||
FCAFC3251A0D466F00AE5136 /* delete_history@2x.png */,
|
||||
FCAFC3261A0D466F00AE5136 /* signal@2x.png */,
|
||||
FCAFC3271A0D466F00AE5136 /* call_dark@2x.png */,
|
||||
FCAFC3201A0D394300AE5136 /* favourite.png */,
|
||||
FCAFC3091A0C560E00AE5136 /* signals.png */,
|
||||
FCAFC30A1A0C560E00AE5136 /* settings.png */,
|
||||
FCAFC2EF1A0C4ACF00AE5136 /* received.png */,
|
||||
FCAFC2F01A0C4ACF00AE5136 /* missed.png */,
|
||||
FCAFC2ED1A0C472200AE5136 /* reply.png */,
|
||||
FCAFC2EB1A0C469C00AE5136 /* checkmark.png */,
|
||||
);
|
||||
name = icons8;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FCFD25791A1543D500F4C644 /* Signup */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FCFD257D1A154B2C00F4C644 /* RegistrationViewController.h */,
|
||||
FCFD257E1A154B2C00F4C644 /* RegistrationViewController.m */,
|
||||
FCFD25801A154B3800F4C644 /* CodeVerificationViewController.h */,
|
||||
FCFD25811A154B3800F4C644 /* CodeVerificationViewController.m */,
|
||||
);
|
||||
name = Signup;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -3010,7 +3286,7 @@
|
|||
ORGANIZATIONNAME = "Open Whisper Systems";
|
||||
TargetAttributes = {
|
||||
D221A088169C9E5E00537ABF = {
|
||||
DevelopmentTeam = U68MSDN6DR;
|
||||
DevelopmentTeam = DRXTS3ZU8M;
|
||||
SystemCapabilities = {
|
||||
com.apple.DataProtection = {
|
||||
enabled = 1;
|
||||
|
@ -3126,15 +3402,22 @@
|
|||
E148750118A06966002CC4F3 /* CallLogViewController.xib in Resources */,
|
||||
E148750218A06966002CC4F3 /* ContactBrowseViewController.xib in Resources */,
|
||||
E148750318A06966002CC4F3 /* ContactDetailTableViewCell.xib in Resources */,
|
||||
FCAFC3341A0D656100AE5136 /* contacts_tab@2x.png in Resources */,
|
||||
E148750418A06966002CC4F3 /* ContactDetailViewController.xib in Resources */,
|
||||
E148750518A06966002CC4F3 /* CountryCodeViewController.xib in Resources */,
|
||||
E148750618A06966002CC4F3 /* DialerViewController.xib in Resources */,
|
||||
E148750818A06966002CC4F3 /* FavouritesViewController.xib in Resources */,
|
||||
E148750918A06966002CC4F3 /* InboxFeedViewController.xib in Resources */,
|
||||
E148750A18A06966002CC4F3 /* InCallViewController.xib in Resources */,
|
||||
FCAFC32E1A0D46D500AE5136 /* settings_dark@2x.png in Resources */,
|
||||
B6416FD2199A0478003C5699 /* Localizable.strings in Resources */,
|
||||
E148750B18A06966002CC4F3 /* InviteContactsViewController.xib in Resources */,
|
||||
FCB11D901A12A388002F93FB /* quit@2x.png in Resources */,
|
||||
FC4FA00D1A18CC4300DA100A /* shred@2x.png in Resources */,
|
||||
E148750C18A06966002CC4F3 /* LeftSideMenuViewController.xib in Resources */,
|
||||
E148750D18A06966002CC4F3 /* PreferenceListViewController.xib in Resources */,
|
||||
FCAFC3301A0D5E3000AE5136 /* share@2x.png in Resources */,
|
||||
FC4F9FE51A16258C00DA100A /* logo_intro@2x.png in Resources */,
|
||||
E148750E18A06966002CC4F3 /* RegisterViewController.xib in Resources */,
|
||||
E148750F18A06966002CC4F3 /* SettingsViewController.xib in Resources */,
|
||||
E148751018A06966002CC4F3 /* TabBarParentViewController.xib in Resources */,
|
||||
|
@ -3142,12 +3425,15 @@
|
|||
E14874F818A06951002CC4F3 /* ContactTableViewCell.xib in Resources */,
|
||||
E14874F918A06951002CC4F3 /* CountryCodeTableViewCell.xib in Resources */,
|
||||
E14874FA18A06951002CC4F3 /* FavouriteTableViewCell.xib in Resources */,
|
||||
FCAFC2EE1A0C472200AE5136 /* reply.png in Resources */,
|
||||
E14874FB18A06951002CC4F3 /* InboxFeedFooterCell.xib in Resources */,
|
||||
E14874FC18A06951002CC4F3 /* InboxFeedTableViewCell.xib in Resources */,
|
||||
E14874FD18A06951002CC4F3 /* LeftSideMenuCell.xib in Resources */,
|
||||
E14874FE18A06951002CC4F3 /* PreferenceListTableViewCell.xib in Resources */,
|
||||
E14874FF18A06951002CC4F3 /* UnseenWhisperUserCell.xib in Resources */,
|
||||
FC4F9FFF1A17A39E00DA100A /* photo@2x.png in Resources */,
|
||||
E14874A218A0692F002CC4F3 /* archive_icon.png in Resources */,
|
||||
FCAFC32A1A0D466F00AE5136 /* call_dark@2x.png in Resources */,
|
||||
E14874A318A0692F002CC4F3 /* archive_icon@2x.png in Resources */,
|
||||
E14874A418A0692F002CC4F3 /* backspace.png in Resources */,
|
||||
E14874A518A0692F002CC4F3 /* backspace@2x.png in Resources */,
|
||||
|
@ -3162,6 +3448,9 @@
|
|||
E14874AE18A0692F002CC4F3 /* dismiss_notification_icon.png in Resources */,
|
||||
E14874AF18A0692F002CC4F3 /* dismiss_notification_icon@2x.png in Resources */,
|
||||
E14874B018A0692F002CC4F3 /* drop_down_arrow_icon.png in Resources */,
|
||||
FC4F9FF61A1664EA00DA100A /* mute_on@2x.png in Resources */,
|
||||
FCAFC2F21A0C4ACF00AE5136 /* missed.png in Resources */,
|
||||
FC4F9FF31A1664EA00DA100A /* mute_off@2x.png in Resources */,
|
||||
E14874B118A0692F002CC4F3 /* drop_down_arrow_icon@2x.png in Resources */,
|
||||
E14874B218A0692F002CC4F3 /* expanded_cell_icon.png in Resources */,
|
||||
E14874B318A0692F002CC4F3 /* expanded_cell_icon@2x.png in Resources */,
|
||||
|
@ -3169,10 +3458,15 @@
|
|||
E14874B518A0692F002CC4F3 /* favourite_false_icon@2x.png in Resources */,
|
||||
E14874B618A0692F002CC4F3 /* favourite_true_icon.png in Resources */,
|
||||
E14874B718A0692F002CC4F3 /* favourite_true_icon@2x.png in Resources */,
|
||||
FCAFC3211A0D394300AE5136 /* favourite.png in Resources */,
|
||||
E14874B818A0692F002CC4F3 /* forward_button.png in Resources */,
|
||||
B6416FD4199A0478003C5699 /* Localizable.strings in Resources */,
|
||||
FCAFC2EC1A0C469C00AE5136 /* checkmark.png in Resources */,
|
||||
E14874B918A0692F002CC4F3 /* forward_button@2x.png in Resources */,
|
||||
FCAFC3281A0D466F00AE5136 /* delete_history@2x.png in Resources */,
|
||||
E14874BA18A0692F002CC4F3 /* home_icon.png in Resources */,
|
||||
E14874BB18A0692F002CC4F3 /* icon_contacts.png in Resources */,
|
||||
FC4FA0071A18BDAE00DA100A /* info@2x.png in Resources */,
|
||||
E14874BC18A0692F002CC4F3 /* icon_favourites.png in Resources */,
|
||||
E14874BD18A0692F002CC4F3 /* icon_keypad.png in Resources */,
|
||||
E14874BE18A0692F002CC4F3 /* icon_recents.png in Resources */,
|
||||
|
@ -3182,6 +3476,7 @@
|
|||
E16E5C1518AEDB5A00B7C403 /* phone_icon.png in Resources */,
|
||||
E14874C218A0692F002CC4F3 /* in_call_phrase_icon@2x.png in Resources */,
|
||||
E14874C318A0692F002CC4F3 /* incoming_call_icon.png in Resources */,
|
||||
FC4F9FF51A1664EA00DA100A /* speaker_on@2x.png in Resources */,
|
||||
E14874C418A0692F002CC4F3 /* incoming_call_icon@2x.png in Resources */,
|
||||
E14874C518A0692F002CC4F3 /* menu_icon.png in Resources */,
|
||||
E14874C618A0692F002CC4F3 /* menu_icon@2x.png in Resources */,
|
||||
|
@ -3201,27 +3496,36 @@
|
|||
E14874D318A0692F002CC4F3 /* search_cancel.png in Resources */,
|
||||
E14874D418A0692F002CC4F3 /* search_cancel@2x.png in Resources */,
|
||||
E14874D518A0692F002CC4F3 /* search_icon.png in Resources */,
|
||||
FC4F9FFD1A179FCF00DA100A /* lock@2x.png in Resources */,
|
||||
E14874D618A0692F002CC4F3 /* search_icon@2x.png in Resources */,
|
||||
E14874D718A0692F002CC4F3 /* send_code_icon.png in Resources */,
|
||||
B6416FC8199A0478003C5699 /* Localizable.strings in Resources */,
|
||||
FCAFC3361A0D680100AE5136 /* keypad@2x.png in Resources */,
|
||||
E14874D818A0692F002CC4F3 /* send_code_icon@2x.png in Resources */,
|
||||
E14874D918A0692F002CC4F3 /* speaker_icon_selected.png in Resources */,
|
||||
FC4FA0191A1A180D00DA100A /* archive@2x.png in Resources */,
|
||||
E14874DA18A0692F002CC4F3 /* speaker_icon_selected@2x.png in Resources */,
|
||||
E14874DB18A0692F002CC4F3 /* speaker_icon.png in Resources */,
|
||||
FC4FA0171A1A180D00DA100A /* red-delete@2x.png in Resources */,
|
||||
E14874DC18A0692F002CC4F3 /* speaker_icon@2x.png in Resources */,
|
||||
E14874DD18A0692F002CC4F3 /* spinner_connecting_flash.png in Resources */,
|
||||
E14874DE18A0692F002CC4F3 /* spinner_connecting_flash@2x.png in Resources */,
|
||||
E14874DF18A06930002CC4F3 /* spinner_connecting.png in Resources */,
|
||||
E14874E018A06930002CC4F3 /* spinner_connecting@2x.png in Resources */,
|
||||
E14874E118A06930002CC4F3 /* spinner_error.png in Resources */,
|
||||
FCAC964119FEF99A0046DFC5 /* TableViewCell.xib in Resources */,
|
||||
B6416FBF199A0478003C5699 /* Localizable.strings in Resources */,
|
||||
B6416FB7199A0478003C5699 /* Localizable.strings in Resources */,
|
||||
B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */,
|
||||
E14874E218A06930002CC4F3 /* spinner_error@2x.png in Resources */,
|
||||
E14874E318A06930002CC4F3 /* spinner_ringing.png in Resources */,
|
||||
E14874E418A06930002CC4F3 /* spinner_ringing@2x.png in Resources */,
|
||||
E14874E518A06930002CC4F3 /* tab_icon_contacts.png in Resources */,
|
||||
E14874E618A06930002CC4F3 /* tab_icon_contacts@2x.png in Resources */,
|
||||
FCAFC3291A0D466F00AE5136 /* signal@2x.png in Resources */,
|
||||
E14874E718A06930002CC4F3 /* tab_icon_favourites.png in Resources */,
|
||||
FCAFC30C1A0C560E00AE5136 /* signals.png in Resources */,
|
||||
E14874E818A06930002CC4F3 /* tab_icon_favourites@2x.png in Resources */,
|
||||
E14874E918A06930002CC4F3 /* tab_icon_inbox.png in Resources */,
|
||||
FC4FA01A1A1A180D00DA100A /* blue-archive@2x.png in Resources */,
|
||||
E14874EA18A06930002CC4F3 /* tab_icon_inbox@2x.png in Resources */,
|
||||
E14874EB18A06930002CC4F3 /* tab_icon_keypad.png in Resources */,
|
||||
E14874EC18A06930002CC4F3 /* tab_icon_keypad@2x.png in Resources */,
|
||||
|
@ -3232,6 +3536,7 @@
|
|||
E14874F118A06930002CC4F3 /* volume_high.png in Resources */,
|
||||
E14874F218A06930002CC4F3 /* volume_high@2x.png in Resources */,
|
||||
70B8FEE21909FE360042E3F0 /* 171756__nenadsimic__picked-coin-echo-2.wav in Resources */,
|
||||
FC4F9FF71A1664EA00DA100A /* endcall@2x.png in Resources */,
|
||||
E14874F318A06930002CC4F3 /* volume_low.png in Resources */,
|
||||
E14874F418A06930002CC4F3 /* volume_low@2x.png in Resources */,
|
||||
E14874F518A06930002CC4F3 /* whisper_notification_icon.png in Resources */,
|
||||
|
@ -3243,18 +3548,27 @@
|
|||
E1370BEE18A0689000826894 /* AppIcon40x40@2x.png in Resources */,
|
||||
E16E5C1418AEDB5A00B7C403 /* message_icon.png in Resources */,
|
||||
E1370BEF18A0689000826894 /* AppIcon60x60.png in Resources */,
|
||||
FC4F9FED1A1658EE00DA100A /* call@2x.png in Resources */,
|
||||
E1370BF018A0689000826894 /* AppIcon60x60@2x.png in Resources */,
|
||||
FC4FA0181A1A180D00DA100A /* delete@2x.png in Resources */,
|
||||
FC4FA0091A18BF3100DA100A /* lock_white@2x.png in Resources */,
|
||||
E1370BF118A0689000826894 /* AppIcon76x76.png in Resources */,
|
||||
E1370BF218A0689000826894 /* AppIcon76x76@2x.png in Resources */,
|
||||
E1370BE718A0688300826894 /* Default-568h@2x.png in Resources */,
|
||||
E1370BE818A0688300826894 /* Default.png in Resources */,
|
||||
FCAFC30D1A0C560E00AE5136 /* settings.png in Resources */,
|
||||
E1370BE918A0688300826894 /* Default@2x.png in Resources */,
|
||||
E1370BE018A0686600826894 /* busy.mp3 in Resources */,
|
||||
E1370BE118A0686C00826894 /* completed.mp3 in Resources */,
|
||||
E1370BE218A0686C00826894 /* failure.mp3 in Resources */,
|
||||
FCAFC2F11A0C4ACF00AE5136 /* received.png in Resources */,
|
||||
E1370BE318A0686C00826894 /* handshake.mp3 in Resources */,
|
||||
B6416FCA199A0478003C5699 /* Localizable.strings in Resources */,
|
||||
FCAC963519FEF4E20046DFC5 /* Storyboard.storyboard in Resources */,
|
||||
B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */,
|
||||
E1370BE418A0686C00826894 /* outring.mp3 in Resources */,
|
||||
FC4F9FF41A1664EA00DA100A /* speaker_off@2x.png in Resources */,
|
||||
FCB11D8F1A12A388002F93FB /* savephoto@2x.png in Resources */,
|
||||
E1370BE518A0686C00826894 /* r.caf in Resources */,
|
||||
E1370BE618A0686C00826894 /* sonarping.mp3 in Resources */,
|
||||
E148751218A06AFD002CC4F3 /* HelveticaNeueLTStd-Bd.otf in Resources */,
|
||||
|
@ -3399,6 +3713,7 @@
|
|||
76EB068418170B34006006FC /* ContactDetailTableViewCell.m in Sources */,
|
||||
76EB066218170B34006006FC /* SettingsViewController.m in Sources */,
|
||||
76EB05AC18170B33006006FC /* SrtpSocket.m in Sources */,
|
||||
FCB11D931A12A4AA002F93FB /* FullImageViewController.m in Sources */,
|
||||
B60C16651988999D00E97A6C /* VersionMigrations.m in Sources */,
|
||||
76EB062A18170B33006006FC /* BadState.m in Sources */,
|
||||
B97940271832BD2400BD66CB /* UIUtil.m in Sources */,
|
||||
|
@ -3420,6 +3735,7 @@
|
|||
70B8010F190C55660042E3F0 /* CodedOutputStream.m in Sources */,
|
||||
70B8010C190C55660042E3F0 /* AbstractMessage.m in Sources */,
|
||||
E197B61618BBEC1A00F073E5 /* StretchFactorController.m in Sources */,
|
||||
FCFD257F1A154B2C00F4C644 /* RegistrationViewController.m in Sources */,
|
||||
76EB065018170B34006006FC /* DialerViewController.m in Sources */,
|
||||
701231B518ECAA4500D456C4 /* EvpMessageDigest.m in Sources */,
|
||||
76EB062218170B33006006FC /* CyclicalBuffer.m in Sources */,
|
||||
|
@ -3446,6 +3762,7 @@
|
|||
D221A09A169C9E5E00537ABF /* main.m in Sources */,
|
||||
76EB061618170B33006006FC /* AnonymousOccurrenceLogger.m in Sources */,
|
||||
76EB063018170B33006006FC /* Conversions.m in Sources */,
|
||||
FCAFC33F1A0F948F00AE5136 /* ActionContactDetailCell.m in Sources */,
|
||||
76EB065618170B34006006FC /* InCallViewController.m in Sources */,
|
||||
76EB05FE18170B33006006FC /* InitiateSignal.pb.m in Sources */,
|
||||
76EB064C18170B34006006FC /* ContactBrowseViewController.m in Sources */,
|
||||
|
@ -3453,6 +3770,7 @@
|
|||
70B80115190C55660042E3F0 /* GeneratedMessage.m in Sources */,
|
||||
E197B61418BBEC1A00F073E5 /* DropoutTracker.m in Sources */,
|
||||
76EB062C18170B33006006FC /* OperationFailed.m in Sources */,
|
||||
FCAC963C19FEF9280046DFC5 /* SignalsViewController.m in Sources */,
|
||||
707E549218FF26E800C8649D /* SmsInvite.m in Sources */,
|
||||
76EB05DA18170B33006006FC /* LowLatencyConnector.m in Sources */,
|
||||
76EB05EE18170B33006006FC /* CallTermination.m in Sources */,
|
||||
|
@ -3465,9 +3783,13 @@
|
|||
70B80114190C55660042E3F0 /* Field.m in Sources */,
|
||||
E197B61E18BBEC6D00F073E5 /* AudioRouter.m in Sources */,
|
||||
E197B60D18BBEC1A00F073E5 /* AudioSocket.m in Sources */,
|
||||
FCF72A081A01A765006BC849 /* ContactsTableViewController.m in Sources */,
|
||||
FC31962D1A06A2190094C78E /* FingerprintViewController.m in Sources */,
|
||||
76EB061418170B33006006FC /* AnonymousConditionLogger.m in Sources */,
|
||||
FCF72A161A02D2BB006BC849 /* ContactDetailCell.m in Sources */,
|
||||
76EB05C018170B33006006FC /* DhPacket.m in Sources */,
|
||||
765052A1182945EF008313E1 /* LocalizableCustomFontLabel.m in Sources */,
|
||||
FC3196301A0814130094C78E /* SettingsTableViewController.m in Sources */,
|
||||
7038632818F70C0700D4A43F /* EvpSymetricUtil.m in Sources */,
|
||||
76EB066418170B34006006FC /* TabBarParentViewController.m in Sources */,
|
||||
76EB068618170B34006006FC /* ContactTableViewCell.m in Sources */,
|
||||
|
@ -3475,10 +3797,13 @@
|
|||
76EB05A018170B33006006FC /* IpAddress.m in Sources */,
|
||||
70B8011B190C55660042E3F0 /* UnknownFieldSet_Builder.m in Sources */,
|
||||
B9A578B1183D60EE00C17105 /* FavouriteTableViewCell.m in Sources */,
|
||||
FCAC965119FF0A6E0046DFC5 /* MessagesViewController.m in Sources */,
|
||||
76EB057618170B33006006FC /* Contact.m in Sources */,
|
||||
70B80111190C55660042E3F0 /* ExtendableMessage.m in Sources */,
|
||||
FCAC964719FEFE1A0046DFC5 /* DemoDataModel.m in Sources */,
|
||||
E197B61118BBEC1A00F073E5 /* AudioProcessor.m in Sources */,
|
||||
76EB065818170B34006006FC /* LeftSideMenuViewController.m in Sources */,
|
||||
FCAC964019FEF99A0046DFC5 /* TableViewCell.m in Sources */,
|
||||
76EB05EA18170B33006006FC /* CallProgress.m in Sources */,
|
||||
76EB05C218170B33006006FC /* DhPacketSharedSecretHashes.m in Sources */,
|
||||
B6C93C4E199567AD00EDF894 /* DebugLogger.m in Sources */,
|
||||
|
@ -3491,6 +3816,7 @@
|
|||
E197B61218BBEC1A00F073E5 /* AudioStretcher.m in Sources */,
|
||||
76EB05A218170B33006006FC /* IpEndPoint.m in Sources */,
|
||||
70B8010D190C55660042E3F0 /* AbstractMessage_Builder.m in Sources */,
|
||||
FCFD25721A1524DB00F4C644 /* GroupModel.m in Sources */,
|
||||
E197B61A18BBEC1A00F073E5 /* SpeexCodec.m in Sources */,
|
||||
70B80118190C55660042E3F0 /* MutableField.m in Sources */,
|
||||
762D9DCF18281C7400A5E418 /* SettingsTableHeaderView.m in Sources */,
|
||||
|
@ -3500,6 +3826,7 @@
|
|||
76D713E7182D3E3F00C9C9C8 /* PreferenceListTableViewCell.m in Sources */,
|
||||
76EB061818170B33006006FC /* AnonymousValueLogger.m in Sources */,
|
||||
76EB05E618170B33006006FC /* CallController.m in Sources */,
|
||||
FC31962A1A067D8F0094C78E /* MessageComposeTableViewController.m in Sources */,
|
||||
E16E5BEE18AAC40200B7C403 /* EC25KeyAgreementParticipant.m in Sources */,
|
||||
76EB057418170B33006006FC /* RecentCallManager.m in Sources */,
|
||||
76EB061C18170B33006006FC /* ArrayUtil.m in Sources */,
|
||||
|
@ -3511,6 +3838,7 @@
|
|||
B942EB0E183A9633000887BB /* SearchBarTitleView.m in Sources */,
|
||||
765052AF182AC9B5008313E1 /* DialerButtonView.m in Sources */,
|
||||
70B80110190C55660042E3F0 /* ConcreteExtensionField.m in Sources */,
|
||||
FCAC964419FEFD8B0046DFC5 /* DemoDataFactory.m in Sources */,
|
||||
70B80112190C55660042E3F0 /* ExtendableMessage_Builder.m in Sources */,
|
||||
76EB05D418170B33006006FC /* ZrtpManager.m in Sources */,
|
||||
76EB058E18170B33006006FC /* HostNameEndPoint.m in Sources */,
|
||||
|
@ -3519,6 +3847,8 @@
|
|||
76EB065218170B34006006FC /* FavouritesViewController.m in Sources */,
|
||||
E16E5BF018AAC40200B7C403 /* EvpKeyAgreement.m in Sources */,
|
||||
70B80113190C55660042E3F0 /* ExtensionRegistry.m in Sources */,
|
||||
FCFD25821A154B3800F4C644 /* CodeVerificationViewController.m in Sources */,
|
||||
FCF72A131A02D27F006BC849 /* ContactDetailTableViewController.m in Sources */,
|
||||
B9EB5AC61884D370007CBB57 /* UnseenWhisperUserCell.m in Sources */,
|
||||
B65EDA1219E1BE6400AAA7CB /* RPAPICall.m in Sources */,
|
||||
76EB05DC18170B33006006FC /* StreamPair.m in Sources */,
|
||||
|
@ -3527,6 +3857,7 @@
|
|||
70BAFD5D190584BE00FA5E0B /* NotificationTracker.m in Sources */,
|
||||
76EB05A418170B33006006FC /* PacketHandler.m in Sources */,
|
||||
E197B62118BBF12700F073E5 /* AppAudioManager.m in Sources */,
|
||||
FC4FA0261A1B9DC600DA100A /* SignalsNavigationController.m in Sources */,
|
||||
76EB068C18170B34006006FC /* InboxFeedTableViewCell.m in Sources */,
|
||||
76EB062018170B33006006FC /* BloomFilter.m in Sources */,
|
||||
76EB063818170B33006006FC /* DictionaryUtil.m in Sources */,
|
||||
|
@ -3536,14 +3867,17 @@
|
|||
B63761EE19E1FBE8005735D1 /* HttpRequestUtil.m in Sources */,
|
||||
76EB05B618170B33006006FC /* MasterSecret.m in Sources */,
|
||||
76EB05F418170B33006006FC /* CallConnectResult.m in Sources */,
|
||||
FCFD256F1A151BCB00F4C644 /* NewGroupViewController.m in Sources */,
|
||||
76EB059E18170B33006006FC /* HttpSocket.m in Sources */,
|
||||
E197B60E18BBEC1A00F073E5 /* CallAudioManager.m in Sources */,
|
||||
76EB065418170B34006006FC /* InboxFeedViewController.m in Sources */,
|
||||
FC4FA0231A1B8A8D00DA100A /* Socket.m in Sources */,
|
||||
76EB054018170B33006006FC /* AppDelegate.m in Sources */,
|
||||
76EB05D018170B33006006FC /* ZrtpHandshakeSocket.m in Sources */,
|
||||
B63761EF19E1FBE8005735D1 /* HttpResponse.m in Sources */,
|
||||
E197B61518BBEC1A00F073E5 /* JitterQueue.m in Sources */,
|
||||
BFB074C919A5611000F2947C /* ObservableValue.m in Sources */,
|
||||
FCB11D8A1A1284BB002F93FB /* SettingsTableViewCell.m in Sources */,
|
||||
76EB05C818170B33006006FC /* HelloPacket.m in Sources */,
|
||||
BFB074C719A5611000F2947C /* FutureUtil.m in Sources */,
|
||||
76EB057218170B33006006FC /* RecentCall.m in Sources */,
|
||||
|
@ -4200,7 +4534,7 @@
|
|||
"\"$(SRCROOT)/Libraries\"/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Signal/Signal-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)",
|
||||
|
@ -4432,7 +4766,7 @@
|
|||
"\"$(SRCROOT)/Libraries\"/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Signal/Signal-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)",
|
||||
|
@ -4486,7 +4820,7 @@
|
|||
"\"$(SRCROOT)/Libraries\"/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Signal/Signal-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)",
|
||||
|
|
1
Signal.xcworkspace/..Pods
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 585c9e6ca1b55e99fb5c09aa31a6d590c2be5c58
|
11
Signal.xcworkspace/contents.xcworkspacedata
generated
|
@ -1 +1,10 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?><Workspace version='1.0'><FileRef location='group:Signal.xcodeproj'/><FileRef location='group:Pods/Pods.xcodeproj'/></Workspace>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Signal.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<key>CFBundleIcons~ipad</key>
|
||||
<dict/>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.whispersystems.signal</string>
|
||||
<string>org.whispersystems.signal.branch</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
@ -48,6 +48,10 @@
|
|||
<string>remote-notification</string>
|
||||
<string>voip</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>Storyboard</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Storyboard</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
|
|
BIN
Signal/archive@2x.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
Signal/blue-archive@2x.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
Signal/call@2x.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
Signal/call_dark@2x.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
Signal/checkmark.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
Signal/contacts.png
Normal file
After Width: | Height: | Size: 888 B |
BIN
Signal/contacts@2x.png
Normal file
After Width: | Height: | Size: 5 KiB |
BIN
Signal/contacts_tab@2x.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Signal/delete@2x.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
Signal/delete_history@2x.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Signal/endcall@2x.png
Normal file
After Width: | Height: | Size: 8 KiB |
BIN
Signal/favourite.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
Signal/info@2x.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
Signal/keypad@2x.png
Normal file
After Width: | Height: | Size: 674 B |
BIN
Signal/lock@2x.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
Signal/lock_white@2x.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
Signal/logo_intro@2x.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
Signal/missed.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
Signal/mute_off@2x.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
Signal/mute_on@2x.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Signal/photo@2x.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
Signal/quit@2x.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
Signal/received.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
Signal/red-delete@2x.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
Signal/reply.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
Signal/savephoto@2x.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Signal/settings.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Signal/settings_dark@2x.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
Signal/share@2x.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
Signal/shred@2x.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
Signal/signal@2x.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
Signal/signals.png
Normal file
After Width: | Height: | Size: 781 B |
BIN
Signal/speaker_off@2x.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
Signal/speaker_on@2x.png
Normal file
After Width: | Height: | Size: 10 KiB |
|
@ -1,7 +1,11 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "SignalsViewController.h"
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@property (strong, nonatomic) SignalsViewController *signalVC;
|
||||
|
||||
@end
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
[self performUpdateCheck];
|
||||
[self protectPreferenceFiles];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
|
||||
//self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
|
||||
|
||||
[self prepareScreenshotProtection];
|
||||
|
||||
|
@ -142,8 +142,8 @@
|
|||
LeftSideMenuViewController *leftSideMenuViewController = [LeftSideMenuViewController new];
|
||||
|
||||
self.drawerController = [[MMDrawerController alloc] initWithCenterViewController:leftSideMenuViewController.centerTabBarViewController leftDrawerViewController:leftSideMenuViewController];
|
||||
self.window.rootViewController = _drawerController;
|
||||
[self.window makeKeyAndVisible];
|
||||
//self.window.rootViewController = _drawerController;
|
||||
//[self.window makeKeyAndVisible];
|
||||
|
||||
//Accept push notification when app is not open
|
||||
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
|
|
15
Signal/src/ContactsViewController.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// ContactsViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 29/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ContactsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
|
||||
@property(nonatomic,strong) IBOutlet UISearchBar* searchBar;
|
||||
@property(nonatomic,strong) IBOutlet UITableView* tableView;
|
||||
@property(nonatomic,strong) IBOutlet UILabel* phoneNumberLabel;
|
||||
@end
|
165
Signal/src/ContactsViewController.m
Normal file
|
@ -0,0 +1,165 @@
|
|||
//
|
||||
// ContactsViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 29/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Environment.h"
|
||||
#import "Contact.h"
|
||||
#import "ContactsManager.h"
|
||||
#import "PhoneNumberDirectoryFilterManager.h"
|
||||
|
||||
#import "DemoDataFactory.h"
|
||||
|
||||
#import <AddressBook/AddressBook.h>
|
||||
#import "ContactsViewController.h"
|
||||
|
||||
static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableViewCell";
|
||||
|
||||
|
||||
@interface ContactsViewController () {
|
||||
NSMutableDictionary *_latestAlphabeticalContacts;
|
||||
NSArray *_latestSortedAlphabeticalContactKeys;
|
||||
NSArray *_latestContacts;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ContactsViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
|
||||
[self.tableView setContentOffset:CGPointMake(0, self.searchBar.frame.size.height)];
|
||||
|
||||
[self setupContacts];
|
||||
[self.tableView reloadData];
|
||||
|
||||
|
||||
// Uncomment the following line to preserve selection between presentations.
|
||||
// self.clearsSelectionOnViewWillAppear = NO;
|
||||
|
||||
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
|
||||
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
#pragma mark - Contact functions
|
||||
|
||||
- (void)setupContacts {
|
||||
// ObservableValue *observableContacts = Environment.getCurrent.contactsManager.getObservableWhisperUsers;
|
||||
//
|
||||
// [observableContacts watchLatestValue:^(NSArray *latestContacts) {
|
||||
// _latestContacts = latestContacts;
|
||||
// } onThread:NSThread.mainThread untilCancelled:nil];
|
||||
_latestContacts = [DemoDataFactory makeFakeContacts];
|
||||
|
||||
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];
|
||||
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
|
||||
_latestSortedAlphabeticalContactKeys = [_latestContacts sortedArrayUsingDescriptors:sortDescriptors];
|
||||
|
||||
_latestAlphabeticalContacts = [self alphabetDictionaryInit];
|
||||
|
||||
for (Contact*contact in _latestContacts)
|
||||
{
|
||||
NSString * firstLetter = [contact.firstName substringToIndex:1];
|
||||
|
||||
NSMutableArray * mutArray = [[_latestAlphabeticalContacts objectForKey:firstLetter] mutableCopy];
|
||||
if (![mutArray containsObject:contact])
|
||||
[mutArray addObject:contact];
|
||||
[_latestAlphabeticalContacts setObject:mutArray forKey:firstLetter];
|
||||
|
||||
}
|
||||
|
||||
_latestSortedAlphabeticalContactKeys = [[_latestAlphabeticalContacts allKeys]sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
|
||||
}
|
||||
|
||||
- (NSArray *)contactsForSectionIndex:(NSUInteger)index {
|
||||
return [_latestAlphabeticalContacts valueForKey:_latestSortedAlphabeticalContactKeys[index]];
|
||||
}
|
||||
|
||||
-(NSMutableDictionary*)alphabetDictionaryInit
|
||||
{
|
||||
NSDictionary * dic;
|
||||
|
||||
dic = @{
|
||||
@"A": @[],
|
||||
@"B": @[],
|
||||
@"C": @[],
|
||||
@"D": @[],
|
||||
@"E": @[],
|
||||
@"F": @[],
|
||||
@"G": @[],
|
||||
@"H": @[],
|
||||
@"I": @[],
|
||||
@"J": @[],
|
||||
@"K": @[],
|
||||
@"L": @[],
|
||||
@"M": @[],
|
||||
@"N": @[],
|
||||
@"O": @[],
|
||||
@"P": @[],
|
||||
@"Q": @[],
|
||||
@"R": @[],
|
||||
@"S": @[],
|
||||
@"T": @[],
|
||||
@"U": @[],
|
||||
@"V": @[],
|
||||
@"W": @[],
|
||||
@"X": @[],
|
||||
@"Y": @[],
|
||||
@"Z": @[],
|
||||
|
||||
};
|
||||
|
||||
return [dic mutableCopy];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Table view data source
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return (NSInteger)[[self contactsForSectionIndex:(NSUInteger)section] count];
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
|
||||
if ([[self contactsForSectionIndex:(NSUInteger)section] count])
|
||||
return _latestSortedAlphabeticalContactKeys[(NSUInteger)section];
|
||||
else return nil;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return (NSInteger)[[_latestAlphabeticalContacts allKeys] count];
|
||||
}
|
||||
|
||||
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
|
||||
{
|
||||
return _latestSortedAlphabeticalContactKeys;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CONTACT_BROWSE_TABLE_CELL_IDENTIFIER];
|
||||
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:CONTACT_BROWSE_TABLE_CELL_IDENTIFIER];
|
||||
}
|
||||
|
||||
NSArray *contactSection = [self contactsForSectionIndex:(NSUInteger)indexPath.section];
|
||||
Contact *contact = contactSection[(NSUInteger)indexPath.row];
|
||||
|
||||
//TODO: real setup of custom cell
|
||||
cell.textLabel.text = contact.firstName;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
3481
Signal/src/Storyboard/Storyboard.storyboard
Normal file
|
@ -18,6 +18,10 @@
|
|||
@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;
|
||||
|
||||
@property (nonatomic, assign) BOOL isFavourite;
|
||||
|
||||
+ (Contact*)contactWithFirstName:(NSString*)firstName
|
||||
|
|
|
@ -6,7 +6,7 @@ static NSString *const HELVETICA_NEUE_LTSTD_MEDIUM_NAME = @"HelveticaNeueLTStd-M
|
|||
static NSString *const HELVETICA_REGULAR_NAME = @"Helvetica";
|
||||
static NSString *const HELVETICA_LIGHT_NAME = @"Helvetica-Light";
|
||||
|
||||
#define CONTACT_PICTURE_VIEW_BORDER_WIDTH 2.0f
|
||||
#define CONTACT_PICTURE_VIEW_BORDER_WIDTH 0.5f
|
||||
|
||||
@implementation UIUtil
|
||||
|
||||
|
|
16
Signal/src/view controllers/ActionContactDetailCell.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// ActionContactDetailCell.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 09/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ActionContactDetailCell : UITableViewCell
|
||||
@property (strong, nonatomic) IBOutlet UIButton *contactTextButton;
|
||||
@property (strong, nonatomic) IBOutlet UIButton *contactCallButton;
|
||||
@property (strong, nonatomic) IBOutlet UIButton *contactShredButton;
|
||||
@property (strong, nonatomic) IBOutlet UIButton *contactFavoriteButton;
|
||||
@end
|
28
Signal/src/view controllers/ActionContactDetailCell.m
Normal file
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// ActionContactDetailCell.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 09/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DJWActionSheet.h"
|
||||
#import "ActionContactDetailCell.h"
|
||||
|
||||
@implementation ActionContactDetailCell
|
||||
|
||||
- (void)awakeFromNib {
|
||||
// Initialization code
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
15
Signal/src/view controllers/CodeVerificationViewController.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// CodeVerificationViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface CodeVerificationViewController : UIViewController
|
||||
|
||||
@property(nonatomic, strong) IBOutlet UITextField* challengeTextField;
|
||||
|
||||
@end
|
62
Signal/src/view controllers/CodeVerificationViewController.m
Normal file
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// CodeVerificationViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CodeVerificationViewController.h"
|
||||
|
||||
@interface CodeVerificationViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation CodeVerificationViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
[self initializeKeyboardHandlers];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)verifyChallengeAction:(id)sender {
|
||||
|
||||
[_challengeTextField resignFirstResponder];
|
||||
|
||||
//Perform verification
|
||||
|
||||
[self performSegueWithIdentifier:@"verifiedSegue" sender:self];
|
||||
}
|
||||
|
||||
#pragma mark - Keyboard notifications
|
||||
|
||||
- (void)initializeKeyboardHandlers{
|
||||
UITapGestureRecognizer *outsideTabRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)];
|
||||
[self.view addGestureRecognizer:outsideTabRecognizer];
|
||||
|
||||
}
|
||||
|
||||
-(void) dismissKeyboardFromAppropriateSubView {
|
||||
[self.view endEditing:NO];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
24
Signal/src/view controllers/ContactDetailCell.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// ContactDetailCell.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 30/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "Contact.h"
|
||||
#import "UIUtil.h"
|
||||
|
||||
@interface ContactDetailCell : UITableViewCell
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UILabel *contactName;
|
||||
@property (strong, nonatomic) IBOutlet UIImageView *contactImageView;
|
||||
@property (strong, nonatomic) IBOutlet UIImageView *contactFavoriteImageView;
|
||||
@property (strong, nonatomic) IBOutlet UILabel *contactPhoneNumber;
|
||||
@property (strong, nonatomic) IBOutlet UITextView *contactNotesTextView;
|
||||
|
||||
|
||||
|
||||
@end
|
28
Signal/src/view controllers/ContactDetailCell.m
Normal file
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// ContactDetailCell.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 30/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ContactDetailCell.h"
|
||||
#import "DJWActionSheet.h"
|
||||
|
||||
|
||||
@implementation ContactDetailCell
|
||||
|
||||
- (void)awakeFromNib {
|
||||
// Initialization code
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// ContactDetailTableViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 30/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "Contact.h"
|
||||
|
||||
@interface ContactDetailTableViewController : UITableViewController
|
||||
|
||||
@property (nonatomic, strong) Contact *contact;
|
||||
|
||||
@end
|
179
Signal/src/view controllers/ContactDetailTableViewController.m
Normal file
|
@ -0,0 +1,179 @@
|
|||
//
|
||||
// ContactDetailTableViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 30/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ContactDetailTableViewController.h"
|
||||
#import "ContactDetailCell.h"
|
||||
#import "ActionContactDetailCell.h"
|
||||
#import "UIUtil.h"
|
||||
#import "DJWActionSheet.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
kNameMainNumberCellIndexPath = 0,
|
||||
kActionCellIndexPath = 1,
|
||||
kShareCellIndexPath = 2,
|
||||
kEmailCellIndexPath = 3,
|
||||
kAnnexPhoneNumberCellIndexPath = 4,
|
||||
kNotesCellIndexPath = 5,
|
||||
} kCellIndexPath;
|
||||
|
||||
typedef enum {
|
||||
kNameMainNumberCellHeight = 180,
|
||||
kActionCellHeight = 60,
|
||||
kShareCellHeight = 60,
|
||||
kEmailCellHeight = 60,
|
||||
kAnnexPhoneNumberCellHeight = 60,
|
||||
kNotesCellHeight = 165,
|
||||
} kCellHeight;
|
||||
|
||||
static NSString* const kNameMainNumberCell = @"NameMainNumberCell";
|
||||
static NSString* const kActionCell = @"ActionCell";
|
||||
|
||||
//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 ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation ContactDetailTableViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return 6;
|
||||
}
|
||||
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UITableViewCell * cell;
|
||||
|
||||
switch (indexPath.row) {
|
||||
case kNameMainNumberCellIndexPath:
|
||||
cell = (ContactDetailCell*)[tableView dequeueReusableCellWithIdentifier:kNameMainNumberCell forIndexPath:indexPath];
|
||||
[self setUpNameMainUserCell:(ContactDetailCell*)cell];
|
||||
break;
|
||||
case kActionCellIndexPath:
|
||||
cell = (ActionContactDetailCell*)[tableView dequeueReusableCellWithIdentifier:kActionCell forIndexPath:indexPath];
|
||||
break;
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
-(void)setUpNameMainUserCell:(ContactDetailCell*)cell
|
||||
{
|
||||
Contact* c = self.contact;
|
||||
|
||||
cell.contactName.text = [c fullName];
|
||||
|
||||
cell.contactPhoneNumber.text = [c.userTextPhoneNumbers firstObject];
|
||||
|
||||
if (c.image) {
|
||||
cell.contactImageView.image = c.image;
|
||||
}
|
||||
[cell.contactImageView.layer setCornerRadius:50.0f];
|
||||
[cell.contactImageView.layer setMasksToBounds:YES];
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGFloat cellHeight = 44.0f;
|
||||
|
||||
switch (indexPath.row) {
|
||||
case kNameMainNumberCellIndexPath:
|
||||
cellHeight = kNameMainNumberCellHeight;
|
||||
break;
|
||||
case kActionCellIndexPath:
|
||||
cellHeight = kActionCellHeight;
|
||||
break;
|
||||
case kShareCellIndexPath:
|
||||
cellHeight = kShareCellHeight;
|
||||
break;
|
||||
case kEmailCellIndexPath:
|
||||
cellHeight = kEmailCellHeight;
|
||||
break;
|
||||
case kAnnexPhoneNumberCellIndexPath:
|
||||
cellHeight = kAnnexPhoneNumberCellHeight;
|
||||
break;
|
||||
case kNotesCellIndexPath:
|
||||
cellHeight = kNotesCellHeight;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return cellHeight;
|
||||
}
|
||||
|
||||
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
switch (indexPath.row) {
|
||||
case kShareCellIndexPath:
|
||||
[DJWActionSheet showInView:self.tabBarController.view
|
||||
withTitle:nil
|
||||
cancelButtonTitle:@"Cancel"
|
||||
destructiveButtonTitle:nil
|
||||
otherButtonTitles:@[@"Mail", @"Message", @"Airdrop", @"Other"]
|
||||
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
|
||||
NSLog(@"User Cancelled");
|
||||
|
||||
} else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
|
||||
NSLog(@"Destructive button tapped");
|
||||
}else {
|
||||
NSLog(@"The user tapped button at index: %li", (long)tappedButtonIndex);
|
||||
}
|
||||
}];
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
13
Signal/src/view controllers/ContactsTableViewController.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// ContactsTableViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 29/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ContactsTableViewController : UITableViewController
|
||||
|
||||
@end
|
313
Signal/src/view controllers/ContactsTableViewController.m
Normal file
|
@ -0,0 +1,313 @@
|
|||
//
|
||||
// ContactsTableViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 29/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ContactsTableViewController.h"
|
||||
#import "ContactDetailTableViewController.h"
|
||||
#import "DialerViewController.h"
|
||||
|
||||
#import "ContactTableViewCell.h"
|
||||
|
||||
#import "Environment.h"
|
||||
#import "Contact.h"
|
||||
#import "ContactsManager.h"
|
||||
#import "PhoneNumberDirectoryFilterManager.h"
|
||||
|
||||
#import "DemoDataFactory.h"
|
||||
|
||||
#import <AddressBook/AddressBook.h>
|
||||
|
||||
static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableViewCell";
|
||||
|
||||
|
||||
@interface ContactsTableViewController () <UISearchBarDelegate, UISearchResultsUpdating>
|
||||
{
|
||||
NSMutableDictionary *latestAlphabeticalContacts;
|
||||
NSArray *latestSortedAlphabeticalContactKeys;
|
||||
NSArray * latestContacts;
|
||||
|
||||
NSArray * searchResults;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) UISearchController *searchController;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ContactsTableViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
|
||||
//Hide search bar
|
||||
self.tableView.contentOffset = CGPointMake(0, 44);
|
||||
|
||||
[self initializeSearch];
|
||||
|
||||
[self setupContacts];
|
||||
searchResults = latestContacts;
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
-(void)initializeSearch
|
||||
{
|
||||
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
|
||||
|
||||
self.searchController.searchResultsUpdater = self;
|
||||
|
||||
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
|
||||
|
||||
self.tableView.tableHeaderView = self.searchController.searchBar;
|
||||
|
||||
self.searchController.dimsBackgroundDuringPresentation = NO;
|
||||
self.searchController.hidesNavigationBarDuringPresentation = NO;
|
||||
|
||||
self.definesPresentationContext = YES;
|
||||
|
||||
self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - UISearchResultsUpdating
|
||||
|
||||
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
|
||||
|
||||
NSString *searchString = [self.searchController.searchBar text];
|
||||
|
||||
[self filterContentForSearchText:searchString scope:nil];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UISearchBarDelegate
|
||||
|
||||
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope {
|
||||
[self updateSearchResultsForSearchController:self.searchController];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Filter
|
||||
|
||||
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
|
||||
{
|
||||
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"fullName contains[c] %@", searchText];
|
||||
searchResults = [latestContacts filteredArrayUsingPredicate:resultPredicate];
|
||||
if (!searchResults.count && _searchController.searchBar.text.length == 0) searchResults = latestContacts;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Contact functions
|
||||
|
||||
- (void)setupContacts {
|
||||
// ObservableValue *observableContacts = Environment.getCurrent.contactsManager.getObservableWhisperUsers;
|
||||
//
|
||||
// [observableContacts watchLatestValue:^(NSArray *latestContacts) {
|
||||
// _latestContacts = latestContacts;
|
||||
// } onThread:NSThread.mainThread untilCancelled:nil];
|
||||
|
||||
latestContacts = [DemoDataFactory makeFakeContacts];
|
||||
|
||||
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];
|
||||
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
|
||||
latestSortedAlphabeticalContactKeys = [latestContacts sortedArrayUsingDescriptors:sortDescriptors];
|
||||
|
||||
latestAlphabeticalContacts = [self alphabetDictionaryInit];
|
||||
|
||||
for (Contact*contact in latestContacts)
|
||||
{
|
||||
NSString * firstLetter = [contact.firstName substringToIndex:1];
|
||||
|
||||
NSMutableArray * mutArray = [[latestAlphabeticalContacts objectForKey:firstLetter] mutableCopy];
|
||||
if (![mutArray containsObject:contact])
|
||||
[mutArray addObject:contact];
|
||||
[latestAlphabeticalContacts setObject:mutArray forKey:firstLetter];
|
||||
|
||||
}
|
||||
|
||||
latestSortedAlphabeticalContactKeys = [[latestAlphabeticalContacts allKeys]sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
|
||||
}
|
||||
|
||||
- (NSArray *)contactsForSectionIndex:(NSUInteger)index {
|
||||
return [latestAlphabeticalContacts valueForKey:latestSortedAlphabeticalContactKeys[index]];
|
||||
}
|
||||
|
||||
|
||||
-(NSMutableDictionary*)alphabetDictionaryInit
|
||||
{
|
||||
NSDictionary * dic;
|
||||
|
||||
dic = @{
|
||||
@"A": @[],
|
||||
@"B": @[],
|
||||
@"C": @[],
|
||||
@"D": @[],
|
||||
@"E": @[],
|
||||
@"F": @[],
|
||||
@"G": @[],
|
||||
@"H": @[],
|
||||
@"I": @[],
|
||||
@"J": @[],
|
||||
@"K": @[],
|
||||
@"L": @[],
|
||||
@"M": @[],
|
||||
@"N": @[],
|
||||
@"O": @[],
|
||||
@"P": @[],
|
||||
@"Q": @[],
|
||||
@"R": @[],
|
||||
@"S": @[],
|
||||
@"T": @[],
|
||||
@"U": @[],
|
||||
@"V": @[],
|
||||
@"W": @[],
|
||||
@"X": @[],
|
||||
@"Y": @[],
|
||||
@"Z": @[],
|
||||
|
||||
};
|
||||
|
||||
return [dic mutableCopy];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
if (self.searchController.active) {
|
||||
return (NSInteger)[searchResults count];
|
||||
} else {
|
||||
return (NSInteger)[[self contactsForSectionIndex:(NSUInteger)section] count];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
|
||||
|
||||
if ([[self contactsForSectionIndex:(NSUInteger)section] count]) {
|
||||
return latestSortedAlphabeticalContactKeys[(NSUInteger)section];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
|
||||
{
|
||||
UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
|
||||
[header.textLabel setTextColor:[UIColor blackColor]];
|
||||
[header.textLabel setFont:[UIFont fontWithName:@"HelveticaNeue-Thin" size:14.0f]];
|
||||
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
if (self.searchController.active) {
|
||||
return 1;
|
||||
} else {
|
||||
return (NSInteger)[[latestAlphabeticalContacts allKeys] count];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
|
||||
{
|
||||
tableView.sectionIndexBackgroundColor = [UIColor clearColor];
|
||||
return latestSortedAlphabeticalContactKeys;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
ContactTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CONTACT_BROWSE_TABLE_CELL_IDENTIFIER];
|
||||
|
||||
if (!cell) {
|
||||
cell = [[ContactTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:CONTACT_BROWSE_TABLE_CELL_IDENTIFIER];
|
||||
}
|
||||
|
||||
|
||||
[cell configureWithContact:[self contactForIndexPath:indexPath]];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[self performSegueWithIdentifier:@"DetailSegue" sender:self];
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
-(Contact*)contactForIndexPath:(NSIndexPath*)indexPath
|
||||
{
|
||||
Contact *contact = nil;
|
||||
|
||||
if (self.searchController.active) {
|
||||
contact = [searchResults objectAtIndex:(NSUInteger)indexPath.row];
|
||||
} else {
|
||||
NSArray *contactSection = [self contactsForSectionIndex:(NSUInteger)indexPath.section];
|
||||
contact = contactSection[(NSUInteger)indexPath.row];
|
||||
}
|
||||
|
||||
return contact;
|
||||
}
|
||||
|
||||
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return 44.0f;
|
||||
}
|
||||
|
||||
#pragma mark - Segue
|
||||
|
||||
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
|
||||
{
|
||||
if ([segue.identifier isEqualToString:@"DetailSegue"])
|
||||
{
|
||||
Contact *contact = nil;
|
||||
ContactDetailTableViewController * detailvc = [segue destinationViewController];
|
||||
NSIndexPath * indexPath = [self.tableView indexPathForSelectedRow];
|
||||
|
||||
if (self.searchController.active) {
|
||||
contact = [searchResults objectAtIndex:(NSUInteger)indexPath.row];
|
||||
} else {
|
||||
NSArray *contactSection = [self contactsForSectionIndex:(NSUInteger)indexPath.section];
|
||||
contact = contactSection[(NSUInteger)indexPath.row];
|
||||
}
|
||||
detailvc.contact = contact;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - IBAction
|
||||
|
||||
-(IBAction)presentDialer:(id)sender
|
||||
{
|
||||
|
||||
DialerViewController * dialer = [DialerViewController new];
|
||||
|
||||
UINavigationController *navigationController = [[UINavigationController alloc]
|
||||
initWithRootViewController:dialer];
|
||||
navigationController.tabBarController.hidesBottomBarWhenPushed = NO;
|
||||
|
||||
dialer.phoneNumber = nil;
|
||||
|
||||
self.tabBarController.providesPresentationContextTransitionStyle = YES;
|
||||
self.tabBarController.definesPresentationContext = YES;
|
||||
[navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
|
||||
navigationController.hidesBottomBarWhenPushed = YES;
|
||||
navigationController.navigationBarHidden=YES;
|
||||
|
||||
[self.tabBarController presentViewController:navigationController animated:YES completion:^(){
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -21,7 +21,7 @@ static NSString *const CONTRY_CODE_TABLE_CELL_IDENTIFIER = @"CountryCodeTableVie
|
|||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
return UIStatusBarStyleLightContent;
|
||||
return UIStatusBarStyleDefault;
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
@ -64,6 +64,11 @@ static NSString *const CONTRY_CODE_TABLE_CELL_IDENTIFIER = @"CountryCodeTableVie
|
|||
forCountry:countryName];
|
||||
}
|
||||
|
||||
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return 44.0f;
|
||||
}
|
||||
|
||||
#pragma mark - UISearchBarDelegate
|
||||
|
||||
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
|
||||
|
@ -71,4 +76,7 @@ static NSString *const CONTRY_CODE_TABLE_CELL_IDENTIFIER = @"CountryCodeTableVie
|
|||
[_countryCodeTableView reloadData];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13A2093" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6243"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CountryCodeViewController">
|
||||
|
@ -16,51 +17,68 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="Aec-ej-ccl">
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="Aec-ej-ccl">
|
||||
<rect key="frame" x="0.0" y="106" width="320" height="462"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-1" id="nKq-1s-Z6A"/>
|
||||
<outlet property="delegate" destination="-1" id="GHU-1n-beB"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QFE-w4-1GR">
|
||||
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QFE-w4-1GR">
|
||||
<rect key="frame" x="0.0" y="22" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<items>
|
||||
<barButtonItem width="242" style="plain" systemItem="fixedSpace" id="GRQ-uO-YiE"/>
|
||||
<barButtonItem title="Cancel" id="OQ8-LL-GHF">
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<action selector="cancelTapped:" destination="-1" id="XXB-Il-GTJ"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</items>
|
||||
<color key="barTintColor" red="0.13725490200000001" green="0.1215686275" blue="0.12549019610000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="barTintColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</toolbar>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Choose Country Code" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pWD-Rl-eq5" customClass="HelveticaNeueLTStdBoldLabel">
|
||||
<rect key="frame" x="20" y="26" width="226" height="36"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="17"/>
|
||||
<searchBar contentMode="redraw" placeholder="search" translatesAutoresizingMaskIntoConstraints="NO" id="LbU-Dq-i0S">
|
||||
<rect key="frame" x="0.0" y="62" width="320" height="44"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-1" id="KJu-gV-Y08"/>
|
||||
</connections>
|
||||
</searchBar>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Choose Country Code" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pWD-Rl-eq5" customClass="HelveticaNeueLTStdBoldLabel">
|
||||
<rect key="frame" x="86" y="26" width="226" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="RCx-aJ-Vgd"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.73333333329999995" blue="0.87058823529999996" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizationKey" value="CHOOSE_COUNTRY_CODE"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<searchBar contentMode="redraw" fixedFrame="YES" placeholder="search" translatesAutoresizingMaskIntoConstraints="NO" id="LbU-Dq-i0S">
|
||||
<rect key="frame" x="0.0" y="62" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-1" id="KJu-gV-Y08"/>
|
||||
</connections>
|
||||
</searchBar>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.13725490200000001" green="0.1215686275" blue="0.12549019610000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
|
||||
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="Aec-ej-ccl" secondAttribute="trailing" id="7ri-1u-onT"/>
|
||||
<constraint firstItem="LbU-Dq-i0S" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="9HY-c5-seR"/>
|
||||
<constraint firstItem="Aec-ej-ccl" firstAttribute="top" secondItem="1" secondAttribute="top" constant="106" id="Gt2-oz-QpM"/>
|
||||
<constraint firstItem="pWD-Rl-eq5" firstAttribute="top" secondItem="QFE-w4-1GR" secondAttribute="bottom" constant="-40" id="H2r-v2-Oe4"/>
|
||||
<constraint firstAttribute="trailing" secondItem="pWD-Rl-eq5" secondAttribute="trailing" constant="8" id="Kj4-7v-juF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="QFE-w4-1GR" secondAttribute="trailing" id="MC4-oi-i61"/>
|
||||
<constraint firstItem="QFE-w4-1GR" firstAttribute="top" secondItem="1" secondAttribute="top" constant="22" id="ODH-5B-qCb"/>
|
||||
<constraint firstItem="pWD-Rl-eq5" firstAttribute="leading" secondItem="QFE-w4-1GR" secondAttribute="trailing" constant="-234" id="Xvy-83-8bb"/>
|
||||
<constraint firstItem="pWD-Rl-eq5" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="86" id="fg1-iH-OkJ"/>
|
||||
<constraint firstItem="Aec-ej-ccl" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="gaS-xN-W5n"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Aec-ej-ccl" secondAttribute="bottom" id="iqk-df-bOx"/>
|
||||
<constraint firstAttribute="trailing" secondItem="LbU-Dq-i0S" secondAttribute="trailing" id="kJK-l1-VVq"/>
|
||||
<constraint firstItem="QFE-w4-1GR" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="weB-fs-fpo"/>
|
||||
<constraint firstItem="LbU-Dq-i0S" firstAttribute="top" secondItem="QFE-w4-1GR" secondAttribute="bottom" constant="-4" id="y5a-nh-JH0"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
19
Signal/src/view controllers/DemoDataFactory.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// DemoDataFactory.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DemoDataModel.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface DemoDataFactory : NSObject
|
||||
|
||||
+(NSArray*)data;
|
||||
+(NSArray*)makeFakeContacts;
|
||||
+(NSArray*)makeFakeCalls;
|
||||
|
||||
|
||||
@end
|
41
Signal/src/view controllers/DemoDataFactory.m
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// DemoDataFactory.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DemoDataFactory.h"
|
||||
|
||||
@implementation DemoDataFactory
|
||||
|
||||
+(NSArray*)data {
|
||||
NSMutableArray* _mutableArray = [[NSMutableArray alloc]init];
|
||||
|
||||
for (NSUInteger i=0;i<5;i++)
|
||||
[_mutableArray addObject:[DemoDataModel initModel:i]];
|
||||
|
||||
return (NSArray*)_mutableArray;
|
||||
}
|
||||
|
||||
+(NSArray*)makeFakeContacts
|
||||
{
|
||||
NSMutableArray* _mutableArray = [[NSMutableArray alloc]init];
|
||||
|
||||
for (NSUInteger i=0;i<5;i++)
|
||||
[_mutableArray addObject:[DemoDataModel initFakeContacts:i]];
|
||||
|
||||
return (NSArray*)_mutableArray;
|
||||
}
|
||||
|
||||
+(NSArray*)makeFakeCalls
|
||||
{
|
||||
NSMutableArray* _mutableArray = [[NSMutableArray alloc]init];
|
||||
|
||||
for (NSUInteger i=0;i<5;i++)
|
||||
[_mutableArray addObject:[DemoDataModel initRecentCall:i]];
|
||||
|
||||
return (NSArray*)_mutableArray;
|
||||
}
|
||||
@end
|
48
Signal/src/view controllers/DemoDataModel.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// DemoDataModel.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
|
||||
#import "JSQMessages.h"
|
||||
#import "Contact.h"
|
||||
#import "RecentCall.h"
|
||||
|
||||
static NSString * const kJSQDemoAvatarDisplayNameDylan = @"Dylan Bourgeois";
|
||||
static NSString * const kJSQDemoAvatarDisplayNameFred = @"Frederic Jacobs";
|
||||
static NSString * const kJSQDemoAvatarDisplayNameMoxie = @"Moxie Marlinspike";
|
||||
|
||||
static NSString * const kJSQDemoAvatarIdDylan = @"053496-4509-289";
|
||||
static NSString * const kJSQDemoAvatarIdFred = @"468-768355-23123";
|
||||
static NSString * const kJSQDemoAvatarIdMoxie = @"707-8956784-57";
|
||||
|
||||
@interface DemoDataModel : NSObject
|
||||
|
||||
@property (strong, nonatomic) NSMutableArray *messages;
|
||||
|
||||
@property (strong, nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageData;
|
||||
|
||||
@property (strong, nonatomic) JSQMessagesBubbleImage *incomingBubbleImageData;
|
||||
|
||||
@property (strong, nonatomic) NSDictionary *users;
|
||||
|
||||
|
||||
@property (nonatomic, strong) NSString * _sender ;
|
||||
@property (nonatomic, strong) NSString * _snippet ;
|
||||
@property (nonatomic, strong) NSArray * _conversation;
|
||||
@property (nonatomic, strong) NSString * lastActionString;
|
||||
|
||||
+(DemoDataModel*)initModel:(NSUInteger)modelNumber;
|
||||
+(Contact*)initFakeContacts:(NSUInteger)modelNumber;
|
||||
+(RecentCall*)initRecentCall:(NSUInteger)modelNumber;
|
||||
|
||||
|
||||
|
||||
@end
|
171
Signal/src/view controllers/DemoDataModel.m
Normal file
|
@ -0,0 +1,171 @@
|
|||
//
|
||||
// DemoDataModel.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DemoDataModel.h"
|
||||
#import "Contact.h"
|
||||
#import "RecentCall.h"
|
||||
#import "PhoneNumber.h"
|
||||
|
||||
enum {kDemoDataModelCase0, kDemoDataModelCase1,kDemoDataModelCase2, kDemoDataModelCase3, kDemoDataModelCase4};
|
||||
|
||||
@implementation DemoDataModel
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
[self loadFakeMessages];
|
||||
|
||||
JSQMessagesBubbleImageFactory *bubbleFactory = [[JSQMessagesBubbleImageFactory alloc] init];
|
||||
|
||||
self.outgoingBubbleImageData = [bubbleFactory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleBlueColor]];
|
||||
self.incomingBubbleImageData = [bubbleFactory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadFakeMessages
|
||||
{
|
||||
/**
|
||||
* Load some fake messages for demo.
|
||||
*
|
||||
* You should have a mutable array or orderedSet, or something.
|
||||
*/
|
||||
self.messages = [[NSMutableArray alloc] initWithObjects:
|
||||
[[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan
|
||||
senderDisplayName:kJSQDemoAvatarDisplayNameDylan
|
||||
date:[NSDate distantPast]
|
||||
text:@"Welcome to JSQMessages: A messaging UI framework for iOS."],
|
||||
|
||||
[[JSQTextMessage 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
|
||||
senderDisplayName:kJSQDemoAvatarDisplayNameMoxie
|
||||
date:[NSDate date]
|
||||
text:@"JSQMessagesViewController is nearly an exact replica of the iOS Messages App. And perhaps, better."],
|
||||
|
||||
[[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdFred
|
||||
senderDisplayName:kJSQDemoAvatarDisplayNameFred
|
||||
date:[NSDate date]
|
||||
text:@"It is unit-tested, free, open-source, and documented."],
|
||||
|
||||
[[JSQTextMessage alloc] initWithSenderId:kJSQDemoAvatarIdDylan
|
||||
senderDisplayName:kJSQDemoAvatarDisplayNameDylan
|
||||
date:[NSDate date]
|
||||
text:@"Now with media messages!"],
|
||||
nil];
|
||||
}
|
||||
|
||||
|
||||
+(DemoDataModel*)initModel:(NSUInteger)modelNumber
|
||||
{
|
||||
DemoDataModel * _demoModel = [[DemoDataModel alloc] init];
|
||||
|
||||
switch (modelNumber) {
|
||||
case kDemoDataModelCase0:
|
||||
_demoModel._sender = @"Dylan Bourgeois";
|
||||
_demoModel._snippet = @"OpenSSL takes forever to build dude.";
|
||||
_demoModel.lastActionString = @"unread";
|
||||
break;
|
||||
case kDemoDataModelCase1:
|
||||
_demoModel._sender = @"Frederic Jacobs";
|
||||
_demoModel._snippet = @"Bro, you're such an artist.";
|
||||
_demoModel.lastActionString = @"replied";
|
||||
break;
|
||||
case kDemoDataModelCase2:
|
||||
_demoModel._sender = @"Romain Ruetschi";
|
||||
_demoModel._snippet = @"Missed Call";
|
||||
_demoModel.lastActionString = @"missedCall";
|
||||
break;
|
||||
case kDemoDataModelCase3:
|
||||
_demoModel._sender = @"Stephen Colbert";
|
||||
_demoModel._snippet = @"Outgoing Call";
|
||||
_demoModel.lastActionString = @"outgoingCall";
|
||||
break;
|
||||
case kDemoDataModelCase4:
|
||||
_demoModel._sender = @"Johnny Ramone";
|
||||
_demoModel._snippet = @"Rock on...";
|
||||
_demoModel.lastActionString = @"read";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return _demoModel;
|
||||
}
|
||||
|
||||
+(Contact*)initFakeContacts:(NSUInteger)modelNumber
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
+(RecentCall*)initRecentCall:(NSUInteger)modelNumber
|
||||
{
|
||||
RecentCall * _demoCall;
|
||||
|
||||
switch (modelNumber) {
|
||||
case kDemoDataModelCase0:
|
||||
_demoCall = [RecentCall recentCallWithContactID:0 andNumber:[PhoneNumber phoneNumberFromUserSpecifiedText:@"954-394-9043"] andCallType:RPRecentCallTypeMissed];
|
||||
break;
|
||||
case kDemoDataModelCase1:
|
||||
_demoCall = [RecentCall recentCallWithContactID:0 andNumber:[PhoneNumber phoneNumberFromUserSpecifiedText:@"954-304-9043"] andCallType:RPRecentCallTypeIncoming];
|
||||
break;
|
||||
case kDemoDataModelCase2:
|
||||
_demoCall = [RecentCall recentCallWithContactID:0 andNumber:[PhoneNumber phoneNumberFromUserSpecifiedText:@"954-124-9043"] andCallType:RPRecentCallTypeOutgoing];
|
||||
break;
|
||||
case kDemoDataModelCase3:
|
||||
_demoCall = [RecentCall recentCallWithContactID:0 andNumber:[PhoneNumber phoneNumberFromUserSpecifiedText:@"954-454-9043"] andCallType:RPRecentCallTypeIncoming];
|
||||
break;
|
||||
case kDemoDataModelCase4:
|
||||
_demoCall = [RecentCall recentCallWithContactID:0 andNumber:[PhoneNumber phoneNumberFromUserSpecifiedText:@"954-394-9043"] andCallType:RPRecentCallTypeIncoming];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return _demoCall;
|
||||
}
|
||||
@end
|
|
@ -36,13 +36,20 @@
|
|||
[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;
|
||||
[self updateNumberLabel];
|
||||
|
@ -111,6 +118,7 @@
|
|||
}
|
||||
|
||||
- (void)callButtonTapped {
|
||||
|
||||
PhoneNumber *phoneNumber = self.phoneNumberForCurrentInput;
|
||||
|
||||
BOOL shouldTryCall = [Environment.getCurrent.phoneDirectoryManager.getCurrentFilter containsPhoneNumber:phoneNumber] || [Environment.getCurrent.recentCallManager isPhoneNumberPresentInRecentCalls:phoneNumber];
|
||||
|
@ -122,6 +130,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
-(IBAction)cancelButtonTapped:(id)sender
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
-(void) initiateCallToPhoneNumber:(PhoneNumber*) phoneNumber {
|
||||
if (_contact) {
|
||||
[Environment.phoneManager initiateOutgoingCallToContact:_contact
|
||||
|
@ -142,7 +156,9 @@
|
|||
}
|
||||
|
||||
- (void)updateNumberLabel {
|
||||
//DEBUG!!!
|
||||
NSString* numberText = [_currentNumberMutable copy];
|
||||
|
||||
_numberLabel.text = [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:numberText];
|
||||
PhoneNumber* number = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:numberText];
|
||||
[self tryUpdateContactForNumber:number];
|
||||
|
|
26
Signal/src/view controllers/FingerprintViewController.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// FingerprintViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 02/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface FingerprintViewController : UIViewController
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UILabel * presentationLabel;
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIImageView * contactImageView;
|
||||
@property (nonatomic, strong) IBOutlet UILabel * contactFingerprintTitleLabel;
|
||||
@property (nonatomic, strong) IBOutlet UILabel * contactFingerprintLabel;
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIImageView * userImageView;
|
||||
@property (nonatomic, strong) IBOutlet UILabel * userFingerprintTitleLabel;
|
||||
@property (nonatomic, strong) IBOutlet UILabel * userFingerprintLabel;
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIButton * closeButton;
|
||||
@property (nonatomic, strong) IBOutlet UIButton * shredMessagesAndContactButton;
|
||||
|
||||
@end
|
85
Signal/src/view controllers/FingerprintViewController.m
Normal file
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// FingerprintViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 02/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "FingerprintViewController.h"
|
||||
|
||||
#import "DJWActionSheet.h"
|
||||
|
||||
@interface FingerprintViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation FingerprintViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
[self initializeImageViews];
|
||||
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
#pragma mark - Initializers
|
||||
-(void)initializeImageViews
|
||||
{
|
||||
_contactImageView.image = [UIImage imageNamed:@"DefaultContactImage"];
|
||||
_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.layer.cornerRadius = 75.f/2;
|
||||
_userImageView.layer.masksToBounds = YES;
|
||||
_userImageView.layer.borderWidth = 2.0f;
|
||||
_userImageView.layer.borderColor = [[UIColor whiteColor] CGColor];
|
||||
}
|
||||
|
||||
#pragma mark - Action
|
||||
-(IBAction)closeButtonAction:(id)sender
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
-(IBAction)shredAndDelete:(id)sender
|
||||
{
|
||||
[DJWActionSheet showInView:self.view withTitle:@"Are you sure wou want to shred all communications with this contact ? This action is irreversible."
|
||||
cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@[@"Shred all communications & delete contact"]
|
||||
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
|
||||
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
|
||||
NSLog(@"User Cancelled");
|
||||
} else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
|
||||
NSLog(@"Destructive button tapped");
|
||||
}else {
|
||||
[self shredAndDelete];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Shredding & Deleting
|
||||
|
||||
-(void)shredAndDelete
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
20
Signal/src/view controllers/FullImageViewController.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// FullImageViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 11/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface FullImageViewController : UIViewController
|
||||
|
||||
@property(nonatomic, strong) IBOutlet UIImageView* fullImageView;
|
||||
@property(nonatomic, strong) IBOutlet UIButton* saveButton;
|
||||
@property(nonatomic, strong) IBOutlet UIButton* closeButton;
|
||||
|
||||
@property(nonatomic, strong) UIImage* image;
|
||||
|
||||
|
||||
@end
|
67
Signal/src/view controllers/FullImageViewController.m
Normal file
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// FullImageViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 11/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "FullImageViewController.h"
|
||||
#import "DJWActionSheet.h"
|
||||
|
||||
@interface FullImageViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation FullImageViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
_fullImageView.image = _image;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - IBAction
|
||||
|
||||
-(IBAction)close:(id)sender
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
-(IBAction)more:(id)sender
|
||||
{
|
||||
[DJWActionSheet showInView:self.view
|
||||
withTitle:@"Options"
|
||||
cancelButtonTitle:@"Cancel"
|
||||
destructiveButtonTitle:nil
|
||||
otherButtonTitles:@[@"Save to Camera Roll", @"Delete"]
|
||||
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
|
||||
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
|
||||
NSLog(@"User Cancelled");
|
||||
|
||||
} else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
|
||||
NSLog(@"Destructive button tapped");
|
||||
}else {
|
||||
NSLog(@"The user tapped button at index: %li", (long)tappedButtonIndex);
|
||||
}
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
20
Signal/src/view controllers/GroupModel.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// GroupModel.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface GroupModel : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray * groupMembers;
|
||||
@property (nonatomic, strong) UIImage * groupImage;
|
||||
@property (nonatomic, strong) NSString * groupName;
|
||||
|
||||
|
||||
-(instancetype)initWithTitle:(NSString*)title members:(NSMutableArray*)members image:(UIImage*)image;
|
||||
|
||||
@end
|
22
Signal/src/view controllers/GroupModel.m
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// GroupModel.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "GroupModel.h"
|
||||
|
||||
@implementation GroupModel
|
||||
|
||||
-(instancetype)initWithTitle:(NSString*)title members:(NSMutableArray*)members image:(UIImage*)image
|
||||
{
|
||||
_groupName=title;
|
||||
_groupMembers = [members copy];
|
||||
_groupImage = image;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -248,10 +248,15 @@ 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]];
|
||||
}
|
||||
|
||||
- (void)speakerButtonTapped {
|
||||
_speakerButton.selected = [AppAudioManager.sharedInstance toggleSpeakerPhone];
|
||||
NSString* newImageName = _speakerButton.selected ? @"speaker_on" : @"speaker_off";
|
||||
[_speakerButton.imageView setImage:[UIImage imageNamed:newImageName]];
|
||||
}
|
||||
|
||||
- (void)answerButtonTapped {
|
||||
|
@ -295,6 +300,9 @@ 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;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5056" systemVersion="13C1021" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6249" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6243"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="InviteContactsViewController">
|
||||
|
@ -19,7 +20,6 @@
|
|||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="Y27-8Q-Ao4">
|
||||
<rect key="frame" x="0.0" y="43" width="320" height="461"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="separatorColor" red="0.13725490200000001" green="0.1215686275" blue="0.12549019610000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<connections>
|
||||
|
@ -29,11 +29,9 @@
|
|||
</tableView>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="x7J-R5-Aoc" userLabel="Title Bar View" customClass="SearchBarTitleView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Invite Contacts" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aWP-1y-0OY" customClass="HelveticaNeueLTStdBoldLabel">
|
||||
<rect key="frame" x="61" y="26" width="229" height="35"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="22"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -43,7 +41,6 @@
|
|||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cz3-CG-rX8" userLabel="Menu Button">
|
||||
<rect key="frame" x="16" y="29" width="27" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<state key="normal" image="menu_icon.png">
|
||||
<color key="titleColor" red="1" green="0.54845513059999995" blue="7.621079918e-05" alpha="1" colorSpace="calibratedRGB"/>
|
||||
|
@ -52,16 +49,13 @@
|
|||
</button>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rba-1W-PFE" userLabel="Search View">
|
||||
<rect key="frame" x="267" y="0.0" width="320" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ugp-Ce-cP5" userLabel="Search Bar Underline View">
|
||||
<rect key="frame" x="61" y="56" width="210" height="1"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.5450980392" blue="0.93725490199999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</view>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uyI-aT-0uk" userLabel="Search Button">
|
||||
<rect key="frame" x="3" y="19" width="54" height="47"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<state key="normal" image="search_icon.png">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
@ -69,7 +63,6 @@
|
|||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fQW-ac-wlf" userLabel="Search Cancel Button">
|
||||
<rect key="frame" x="275" y="24" width="45" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<state key="normal" image="search_cancel.png">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
@ -77,7 +70,6 @@
|
|||
</button>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="search" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Rlq-MC-79h">
|
||||
<rect key="frame" x="61" y="31" width="210" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="22"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="words" autocorrectionType="no" returnKeyType="search"/>
|
||||
|
@ -99,9 +91,7 @@
|
|||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
<simulatedTabBarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" id="8iO-99-83g" userLabel="New Whisper Users View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="52"/>
|
||||
|
@ -109,7 +99,6 @@
|
|||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="209" translatesAutoresizingMaskIntoConstraints="NO" id="UtW-8T-yLz" customClass="HelveticaNeueLTStdMedLabel">
|
||||
<rect key="frame" x="57" y="5" width="209" height="41"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<string key="text" base64-UTF8="YES">
|
||||
U29tZSBvZiB5b3VyIGNvbnRhY3RzIGhhdmUgcmVjZW50bHkgA3JlZ2lzdGVyZWQgbnVtYmVycyB3aXRo
|
||||
IFNpZ25hbCE
|
||||
|
@ -123,7 +112,6 @@ IFNpZ25hbCE
|
|||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9dy-uC-NBb">
|
||||
<rect key="frame" x="3" y="1" width="50" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<state key="normal" image="dismiss_notification_icon.png">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
|
@ -133,6 +121,8 @@ IFNpZ25hbCE
|
|||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.22352941176470587" green="0.70980392156862748" blue="0.29019607843137252" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" id="DH4-s9-oCT" userLabel="Regular Contacts Header View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="29"/>
|
||||
|
@ -140,13 +130,14 @@ IFNpZ25hbCE
|
|||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="You can invite the following users to use Signal" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="320" translatesAutoresizingMaskIntoConstraints="NO" id="dJX-lY-XWv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Medium" family="Helvetica Neue" pointSize="12"/>
|
||||
<color key="textColor" red="0.0" green="0.73333333329999995" blue="0.87058823529999996" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.8735351562" green="0.8735351562" blue="0.8735351562" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
@ -155,4 +146,9 @@ IFNpZ25hbCE
|
|||
<image name="search_cancel.png" width="18" height="18"/>
|
||||
<image name="search_icon.png" width="25" height="25"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// MessageComposeTableViewController.h
|
||||
//
|
||||
//
|
||||
// Created by Dylan Bourgeois on 02/11/14.
|
||||
//
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "DemoDataFactory.h"
|
||||
#import "Contact.h"
|
||||
|
||||
#import "JSQMessagesToolbarContentView.h"
|
||||
#import "JSQMessagesInputToolbar.h"
|
||||
#import "JSQMessagesComposerTextView.h"
|
||||
|
||||
#import "JSQMessagesKeyboardController.h"
|
||||
|
||||
|
||||
@interface MessageComposeTableViewController : UITableViewController
|
||||
|
||||
|
||||
@end
|
183
Signal/src/view controllers/MessageComposeTableViewController.m
Normal file
|
@ -0,0 +1,183 @@
|
|||
//
|
||||
// MessageComposeTableViewController.m
|
||||
//
|
||||
//
|
||||
// Created by Dylan Bourgeois on 02/11/14.
|
||||
//
|
||||
//
|
||||
|
||||
#import "MessageComposeTableViewController.h"
|
||||
#import "MessagesViewController.h"
|
||||
#import "SignalsViewController.h"
|
||||
|
||||
#import "ContactTableViewCell.h"
|
||||
|
||||
@interface MessageComposeTableViewController () <UISearchBarDelegate, UISearchResultsUpdating>
|
||||
{
|
||||
NSArray* contacts;
|
||||
NSArray* searchResults;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) UISearchController *searchController;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MessageComposeTableViewController
|
||||
|
||||
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
[self initializeSearch];
|
||||
|
||||
contacts = [DemoDataFactory makeFakeContacts];
|
||||
searchResults = contacts;
|
||||
|
||||
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
-(void)initializeSearch
|
||||
{
|
||||
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
|
||||
|
||||
self.searchController.searchResultsUpdater = self;
|
||||
|
||||
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
|
||||
|
||||
self.tableView.tableHeaderView = self.searchController.searchBar;
|
||||
|
||||
self.searchController.dimsBackgroundDuringPresentation = NO;
|
||||
self.searchController.hidesNavigationBarDuringPresentation = NO;
|
||||
|
||||
self.definesPresentationContext = YES;
|
||||
|
||||
self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - UISearchResultsUpdating
|
||||
|
||||
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
|
||||
|
||||
NSString *searchString = [self.searchController.searchBar text];
|
||||
|
||||
[self filterContentForSearchText:searchString scope:nil];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UISearchBarDelegate
|
||||
|
||||
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope {
|
||||
[self updateSearchResultsForSearchController:self.searchController];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Filter
|
||||
|
||||
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
|
||||
{
|
||||
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"fullName contains[c] %@", searchText];
|
||||
searchResults = [contacts filteredArrayUsingPredicate:resultPredicate];
|
||||
if (!searchResults.count && _searchController.searchBar.text.length == 0) searchResults = contacts;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
|
||||
if (self.searchController.active) {
|
||||
return (NSInteger)[searchResults count];
|
||||
} else {
|
||||
return (NSInteger)[contacts count];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (ContactTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
ContactTableViewCell *cell = (ContactTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"ContactTableViewCell"];
|
||||
|
||||
if (cell == nil) {
|
||||
cell = [[ContactTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ContactTableViewCell"];
|
||||
}
|
||||
|
||||
[cell configureWithContact:[self contactForIndexPath:indexPath]];
|
||||
|
||||
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return 44.0f;
|
||||
}
|
||||
|
||||
#pragma mark - Table View delegate
|
||||
|
||||
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
//HACK: This is horrible due to the view hierarchy, but gets the job done. Gets a reference to the SignalsVC so we can present the conversation from it.
|
||||
|
||||
UITabBarController * tb = (UITabBarController*)self.parentViewController.presentingViewController;
|
||||
UINavigationController* nav = (UINavigationController*)[tb.childViewControllers objectAtIndex:1];
|
||||
SignalsViewController* s = (SignalsViewController*)nav.topViewController;
|
||||
|
||||
s.contactFromCompose = [self contactForIndexPath:indexPath];
|
||||
|
||||
[self.searchController dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
[self dismissViewControllerAnimated:YES completion:^(){
|
||||
[s performSegueWithIdentifier:@"showSegue" sender:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ContactTableViewCell * cell = (ContactTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
|
||||
-(Contact*)contactForIndexPath:(NSIndexPath*)indexPath
|
||||
{
|
||||
Contact *contact = nil;
|
||||
|
||||
if (self.searchController.active) {
|
||||
contact = [searchResults objectAtIndex:(NSUInteger)indexPath.row];
|
||||
} else {
|
||||
contact = [contacts objectAtIndex:(NSUInteger)indexPath.row];
|
||||
}
|
||||
|
||||
return contact;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
|
||||
}
|
||||
|
||||
-(IBAction)closeAction:(id)sender
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
||||
@end
|
23
Signal/src/view controllers/MessagesViewController.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// MessagesViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 28/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JSQMessagesViewController.h"
|
||||
#import "JSQMessages.h"
|
||||
|
||||
#import "DemoDataModel.h"
|
||||
|
||||
|
||||
@interface MessagesViewController : JSQMessagesViewController <UIImagePickerControllerDelegate,UINavigationControllerDelegate>
|
||||
@property (strong, nonatomic) DemoDataModel *demoData;
|
||||
|
||||
@property (strong, nonatomic) NSString* _senderTitleString;
|
||||
|
||||
-(void)initWithGroup:(NSArray*)group;
|
||||
|
||||
|
||||
@end
|
474
Signal/src/view controllers/MessagesViewController.m
Normal file
|
@ -0,0 +1,474 @@
|
|||
//
|
||||
// MessagesViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 28/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "MessagesViewController.h"
|
||||
#import "FullImageViewController.h"
|
||||
|
||||
#import "DJWActionSheet.h"
|
||||
#import <MobileCoreServices/UTCoreTypes.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <CoreMedia/CoreMedia.h>
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
kMediaTypePicture,
|
||||
kMediaTypeVideo,
|
||||
} kMediaTypes;
|
||||
|
||||
@interface MessagesViewController () {
|
||||
UIImage* tappedImage;
|
||||
BOOL isGroupConversation;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MessagesViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
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]];
|
||||
|
||||
//DEBUG:
|
||||
isGroupConversation = NO;
|
||||
|
||||
self.title = self._senderTitleString;
|
||||
|
||||
self.senderId = kJSQDemoAvatarIdDylan;
|
||||
self.senderDisplayName = kJSQDemoAvatarDisplayNameDylan;
|
||||
|
||||
self.demoData = [[DemoDataModel alloc] init];
|
||||
|
||||
self.automaticallyScrollsToMostRecentMessage = YES;
|
||||
|
||||
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
|
||||
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
|
||||
|
||||
if (!isGroupConversation)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(keyboardWillShow:)
|
||||
name:UIKeyboardWillShowNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(keyboardWillHide:)
|
||||
name:UIKeyboardWillHideNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)didPressBack{
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[self.navigationController.parentViewController.presentingViewController.navigationController pushViewController:self animated:NO];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
|
||||
}
|
||||
|
||||
-(void)initWithGroup:(NSArray *)group
|
||||
{
|
||||
//Search for an existing group to set self.title & fetch messages for this identifier
|
||||
//If none found, instantiate new group
|
||||
}
|
||||
|
||||
#pragma mark - Keyboard Handlers
|
||||
|
||||
-(void)keyboardWillShow:(id)sender
|
||||
{
|
||||
[self.inputToolbar.contentView setRightBarButtonItem:[JSQMessagesToolbarButtonFactory defaultSendButtonItem]];
|
||||
}
|
||||
|
||||
-(void)keyboardWillHide:(id)sender
|
||||
{
|
||||
[self.inputToolbar.contentView setRightBarButtonItem:[JSQMessagesToolbarButtonFactory signalCallButtonItem]];
|
||||
}
|
||||
|
||||
#pragma mark - Fingerprints
|
||||
|
||||
-(void)showFingerprint
|
||||
{
|
||||
[self performSegueWithIdentifier:@"fingerprintSegue" sender:self];
|
||||
}
|
||||
|
||||
#pragma mark - JSQMessage custom methods
|
||||
|
||||
-(void)updateMessageStatus:(JSQMessage*)message {
|
||||
if ([message.senderId isEqualToString:self.senderId])
|
||||
message.status = kMessageReceived;
|
||||
}
|
||||
|
||||
#pragma mark - JSQMessagesViewController method overrides
|
||||
|
||||
- (void)didPressSendButton:(UIButton *)button
|
||||
withMessageText:(NSString *)text
|
||||
senderId:(NSString *)senderId
|
||||
senderDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date
|
||||
{
|
||||
if ([button.titleLabel.text isEqualToString:@"Call"])
|
||||
{
|
||||
NSLog(@"Let's call !");
|
||||
|
||||
} else if (text.length > 0) {
|
||||
[JSQSystemSoundPlayer jsq_playMessageSentSound];
|
||||
|
||||
JSQTextMessage *message = [[JSQTextMessage alloc] initWithSenderId:senderId
|
||||
senderDisplayName:senderDisplayName
|
||||
date:date
|
||||
text:text];
|
||||
|
||||
[self.demoData.messages addObject:message];
|
||||
[self finishSendingMessage];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - JSQMessages CollectionView DataSource
|
||||
|
||||
- (id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item];
|
||||
}
|
||||
|
||||
- (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
|
||||
JSQMessage *message = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item];
|
||||
|
||||
if ([message.senderId isEqualToString:self.senderId]) {
|
||||
return self.demoData.outgoingBubbleImageData;
|
||||
}
|
||||
|
||||
return self.demoData.incomingBubbleImageData;
|
||||
}
|
||||
|
||||
- (id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
/**
|
||||
* This logic should be consistent with what you return from `heightForCellTopLabelAtIndexPath:`
|
||||
* The other label text delegate methods should follow a similar pattern.
|
||||
*
|
||||
* Show a timestamp for every 3rd message
|
||||
*/
|
||||
if (indexPath.item % 3 == 0) {
|
||||
JSQMessage *message = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item];
|
||||
return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForMessageBubbleTopLabelAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
JSQMessage *message = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item];
|
||||
|
||||
|
||||
/**
|
||||
* iOS7-style sender name labels
|
||||
*/
|
||||
if ([message.senderId isEqualToString:self.senderId]) {
|
||||
[self updateMessageStatus:message];
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (indexPath.item - 1 > 0) {
|
||||
JSQMessage *previousMessage = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item - 1];
|
||||
if ([[previousMessage senderId] isEqualToString:message.senderId]) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't specify attributes to use the defaults.
|
||||
*/
|
||||
return [[NSAttributedString alloc] initWithString:message.senderDisplayName];
|
||||
}
|
||||
|
||||
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
JSQMessage * message = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item];
|
||||
|
||||
if (message.status == kMessageRead){
|
||||
return [[NSAttributedString alloc]initWithString:@"Read" attributes:nil];
|
||||
} else if (message.status == kMessageSent) {
|
||||
return [[NSAttributedString alloc]initWithString:@"Sent" attributes:nil];
|
||||
} else if (message.status == kMessageReceived) {
|
||||
return [[NSAttributedString alloc]initWithString:@"Received" attributes:nil];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionView DataSource
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return (NSInteger)[self.demoData.messages count];
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
/**
|
||||
* 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];
|
||||
}
|
||||
|
||||
cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor,
|
||||
NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) };
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - Adjusting cell label heights
|
||||
|
||||
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
|
||||
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
/**
|
||||
* Each label in a cell has a `height` delegate method that corresponds to its text dataSource method
|
||||
*/
|
||||
|
||||
/**
|
||||
* This logic should be consistent with what you return from `attributedTextForCellTopLabelAtIndexPath:`
|
||||
* The other label height delegate methods should follow similarly
|
||||
*
|
||||
* Show a timestamp for every 3rd message
|
||||
*/
|
||||
if (indexPath.item % 3 == 0) {
|
||||
return kJSQMessagesCollectionViewCellLabelHeightDefault;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
|
||||
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForMessageBubbleTopLabelAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
/**
|
||||
* iOS7-style sender name labels
|
||||
*/
|
||||
JSQMessage *currentMessage = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item];
|
||||
if ([[currentMessage senderId] isEqualToString:self.senderId]) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (indexPath.item - 1 > 0) {
|
||||
JSQMessage *previousMessage = [self.demoData.messages objectAtIndex:(NSUInteger)indexPath.item - 1];
|
||||
if ([[previousMessage senderId] isEqualToString:[currentMessage senderId]]) {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return kJSQMessagesCollectionViewCellLabelHeightDefault;
|
||||
}
|
||||
|
||||
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
|
||||
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return 16.0f;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
-(void)didPressAccessoryButton:(UIButton *)sender
|
||||
{
|
||||
[self.inputToolbar.contentView.textView resignFirstResponder];
|
||||
|
||||
UIView *presenter = self.parentViewController.view;
|
||||
|
||||
[DJWActionSheet showInView:presenter
|
||||
withTitle:nil
|
||||
cancelButtonTitle:@"Cancel"
|
||||
destructiveButtonTitle:nil
|
||||
otherButtonTitles:@[@"Take Photo or Video", @"Choose existing Photo", @"Choose existing Video", @"Send file"]
|
||||
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
|
||||
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
|
||||
NSLog(@"User Cancelled");
|
||||
} else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
|
||||
NSLog(@"Destructive button tapped");
|
||||
}else {
|
||||
switch (tappedButtonIndex) {
|
||||
case 0:
|
||||
[self takePictureOrVideo];
|
||||
break;
|
||||
case 1:
|
||||
[self chooseFromLibrary:kMediaTypePicture];
|
||||
break;
|
||||
case 2:
|
||||
[self chooseFromLibrary:kMediaTypeVideo];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)collectionView:(JSQMessagesCollectionView *)collectionView didTapMessageBubbleAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
id<JSQMessageData> messageItem = [collectionView.dataSource collectionView:collectionView messageDataForItemAtIndexPath:indexPath];
|
||||
|
||||
BOOL isMediaMessage = [messageItem isMediaMessage];
|
||||
|
||||
if (isMediaMessage) {
|
||||
id<JSQMessageMediaData> messageMedia = [messageItem media];
|
||||
|
||||
|
||||
if ([messageMedia isKindOfClass:JSQPhotoMediaItem.class]) {
|
||||
//is a photo
|
||||
tappedImage = ((JSQPhotoMediaItem*)messageMedia).image ;
|
||||
[self performSegueWithIdentifier:@"fullImage" sender:self];
|
||||
|
||||
} else if ([messageMedia isKindOfClass:JSQVideoMediaItem.class]) {
|
||||
//is a video
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Navigation
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
if ([segue.identifier isEqualToString:@"fullImage"])
|
||||
{
|
||||
FullImageViewController* dest = [segue destinationViewController];
|
||||
dest.image = tappedImage;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UIImagePickerController
|
||||
|
||||
/*
|
||||
* Presenting UIImagePickerController
|
||||
*/
|
||||
|
||||
- (void)takePictureOrVideo
|
||||
{
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.delegate = self;
|
||||
picker.allowsEditing = NO;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:
|
||||
UIImagePickerControllerSourceTypeCamera])
|
||||
{
|
||||
picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *)kUTTypeMovie, kUTTypeImage, kUTTypeVideo, nil];
|
||||
[self presentViewController:picker animated:YES completion:NULL];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)chooseFromLibrary:(kMediaTypes)mediaType
|
||||
{
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.delegate = self;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
|
||||
{
|
||||
NSArray* pictureTypeArray = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeImage, nil];
|
||||
|
||||
NSArray* videoTypeArray = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, (NSString*)kUTTypeVideo, nil];
|
||||
|
||||
picker.mediaTypes = (mediaType == kMediaTypePicture) ? pictureTypeArray : videoTypeArray;
|
||||
|
||||
[self presentViewController:picker animated:YES completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dismissing UIImagePickerController
|
||||
*/
|
||||
|
||||
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch data from UIImagePickerController
|
||||
*/
|
||||
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
|
||||
{
|
||||
UIImage *picture_camera = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||
|
||||
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
|
||||
|
||||
if (CFStringCompare ((__bridge_retained CFStringRef)mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
|
||||
//Is a video
|
||||
|
||||
NSURL* videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
|
||||
AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
|
||||
//Create a snapshot image
|
||||
//NOTE: Might not be necessary as JSQMessages might do this automtically
|
||||
AVAssetImageGenerator *generate1 = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
|
||||
generate1.appliesPreferredTrackTransform = YES;
|
||||
NSError *err = NULL;
|
||||
CMTime time = CMTimeMake(2, 1);
|
||||
CGImageRef snapshotRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err];
|
||||
UIImage *snapshot = [[UIImage alloc] initWithCGImage:snapshotRef];
|
||||
|
||||
JSQVideoMediaItem * videoItem = [[JSQVideoMediaItem alloc] initWithFileURL:videoURL isReadyToPlay:YES];
|
||||
JSQMediaMessage * videoMessage = [JSQMediaMessage messageWithSenderId:kJSQDemoAvatarIdDylan
|
||||
displayName:kJSQDemoAvatarDisplayNameDylan
|
||||
media:videoItem];
|
||||
[self.demoData.messages addObject:videoMessage];
|
||||
[self finishSendingMessage];
|
||||
|
||||
} else if (picture_camera) {
|
||||
//Is a photo
|
||||
|
||||
JSQPhotoMediaItem *photoItem = [[JSQPhotoMediaItem alloc] initWithImage:picture_camera];
|
||||
JSQMediaMessage *photoMessage = [JSQMediaMessage messageWithSenderId:kJSQDemoAvatarIdDylan
|
||||
displayName:kJSQDemoAvatarDisplayNameDylan
|
||||
media:photoItem];
|
||||
[self.demoData.messages addObject:photoMessage];
|
||||
[self finishSendingMessage];
|
||||
|
||||
}
|
||||
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
|
||||
}
|
||||
@end
|
19
Signal/src/view controllers/NewGroupViewController.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// NewGroupViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface NewGroupViewController : UIViewController <UITableViewDelegate, UITabBarDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextFieldDelegate>
|
||||
|
||||
@property(nonatomic, strong) IBOutlet UITableView* tableView;
|
||||
|
||||
@property(nonatomic, strong) IBOutlet UITextField* nameGroupTextField;
|
||||
@property(nonatomic, strong) IBOutlet UIButton* groupImageButton;
|
||||
@property(nonatomic, strong) IBOutlet UIView* tapToDismissView;
|
||||
|
||||
@end
|
250
Signal/src/view controllers/NewGroupViewController.m
Normal file
|
@ -0,0 +1,250 @@
|
|||
//
|
||||
// NewGroupViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NewGroupViewController.h"
|
||||
#import "SignalsViewController.h"
|
||||
|
||||
#import "Contact.h"
|
||||
#import "DemoDataFactory.h"
|
||||
#import "GroupModel.h"
|
||||
|
||||
#import "DJWActionSheet.h"
|
||||
#import <MobileCoreServices/UTCoreTypes.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <CoreMedia/CoreMedia.h>
|
||||
|
||||
@interface NewGroupViewController () {
|
||||
NSArray* contacts;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NewGroupViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Create" style:UIBarButtonItemStylePlain target:self action:@selector(createGroup)];
|
||||
self.navigationItem.title = @"New Group";
|
||||
|
||||
contacts = [DemoDataFactory makeFakeContacts];
|
||||
|
||||
[self initializeDelegates];
|
||||
[self initializeTableView];
|
||||
[self initializeKeyboardHandlers];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
-(void)initializeDelegates
|
||||
{
|
||||
self.nameGroupTextField.delegate = self;
|
||||
}
|
||||
|
||||
-(void)initializeTableView
|
||||
{
|
||||
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
|
||||
}
|
||||
|
||||
#pragma mark - Keyboard notifications
|
||||
|
||||
- (void)initializeKeyboardHandlers{
|
||||
UITapGestureRecognizer *outsideTabRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)];
|
||||
[self.tapToDismissView addGestureRecognizer:outsideTabRecognizer];
|
||||
}
|
||||
|
||||
-(void) dismissKeyboardFromAppropriateSubView {
|
||||
[self.nameGroupTextField resignFirstResponder];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - Actions
|
||||
-(void)createGroup {
|
||||
SignalsViewController* s = (SignalsViewController*)((UINavigationController*)[((UITabBarController*)self.parentViewController.presentingViewController).childViewControllers objectAtIndex:1]).topViewController;
|
||||
|
||||
s.groupFromCompose = [self makeGroup];
|
||||
|
||||
[self dismissViewControllerAnimated:YES completion:^(){
|
||||
[s performSegueWithIdentifier:@"showSegue" sender:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
-(GroupModel*)makeGroup {
|
||||
|
||||
//TODO: Add it to Envirronment
|
||||
|
||||
NSString* title = _nameGroupTextField.text;
|
||||
UIImage* img = _groupImageButton.imageView.image;
|
||||
NSMutableArray* mut = [[NSMutableArray alloc]init];
|
||||
|
||||
for (NSIndexPath* idx in _tableView.indexPathsForSelectedRows) {
|
||||
[mut addObject:[contacts objectAtIndex:(NSUInteger)idx.row-1]];
|
||||
}
|
||||
|
||||
return [[GroupModel alloc] initWithTitle:title members:mut image:img];
|
||||
}
|
||||
|
||||
-(IBAction)addGroupPhoto:(id)sender
|
||||
{
|
||||
[DJWActionSheet showInView:self.parentViewController.view withTitle:nil cancelButtonTitle:@"Cancel"
|
||||
destructiveButtonTitle:nil otherButtonTitles:@[@"Take a Picture",@"Choose from Library"]
|
||||
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
|
||||
|
||||
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
|
||||
NSLog(@"User Cancelled");
|
||||
} else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
|
||||
NSLog(@"Destructive button tapped");
|
||||
}else {
|
||||
switch (tappedButtonIndex) {
|
||||
case 0:
|
||||
[self takePicture];
|
||||
break;
|
||||
case 1:
|
||||
[self chooseFromLibrary];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Group Image
|
||||
|
||||
-(void)takePicture
|
||||
{
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.delegate = self;
|
||||
picker.allowsEditing = NO;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:
|
||||
UIImagePickerControllerSourceTypeCamera])
|
||||
{
|
||||
picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *)kUTTypeImage, nil];
|
||||
[self presentViewController:picker animated:YES completion:NULL];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)chooseFromLibrary
|
||||
{
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.delegate = self;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
|
||||
{
|
||||
picker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeImage, nil];
|
||||
[self presentViewController:picker animated:YES completion:nil];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Dismissing UIImagePickerController
|
||||
*/
|
||||
|
||||
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch data from UIImagePickerController
|
||||
*/
|
||||
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
|
||||
{
|
||||
UIImage *picture_camera = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||
|
||||
if (picture_camera) {
|
||||
//There is a photo
|
||||
_groupImageButton.imageView.image = picture_camera;
|
||||
_groupImageButton.imageView.layer.cornerRadius = 40.0f;
|
||||
_groupImageButton.imageView.clipsToBounds = YES;
|
||||
|
||||
}
|
||||
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return (NSInteger)[contacts count]+1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SearchCell"];
|
||||
|
||||
if (cell == nil) {
|
||||
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: indexPath.row == 0 ? @"HeaderCell" : @"GroupSearchCell"];
|
||||
}
|
||||
|
||||
if (indexPath.row > 0) {
|
||||
NSUInteger row = (NSUInteger)indexPath.row;
|
||||
Contact* contact = contacts[row-1];
|
||||
|
||||
cell.textLabel.text = contact.fullName;
|
||||
|
||||
} else {
|
||||
cell.textLabel.text = @"Add People:";
|
||||
cell.textLabel.textColor = [UIColor lightGrayColor];
|
||||
}
|
||||
|
||||
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - Table View delegate
|
||||
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
|
||||
#pragma mark - Text Field Delegate
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
|
||||
[self.nameGroupTextField resignFirstResponder];
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6249" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3746"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6243"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PreferenceListViewController">
|
||||
|
@ -17,7 +18,6 @@
|
|||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="iaf-8A-Gui">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-1" id="tHd-A5-v0y"/>
|
||||
|
@ -26,8 +26,11 @@
|
|||
</tableView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
25
Signal/src/view controllers/RegistrationViewController.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// RegistrationViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "CountryCodeViewController.h"
|
||||
|
||||
|
||||
@interface RegistrationViewController : UIViewController<CountryCodeViewControllerDelegate, UITextFieldDelegate>
|
||||
|
||||
// Country code
|
||||
@property(nonatomic, strong) IBOutlet UIButton* countryCodeButton;
|
||||
@property(nonatomic, strong) IBOutlet UILabel* countryNameLabel;
|
||||
@property(nonatomic, strong) IBOutlet UILabel* countryCodeLabel;
|
||||
|
||||
//Phone number
|
||||
@property(nonatomic, strong) IBOutlet UITextField* phoneNumberTextField;
|
||||
|
||||
|
||||
|
||||
@end
|
222
Signal/src/view controllers/RegistrationViewController.m
Normal file
|
@ -0,0 +1,222 @@
|
|||
//
|
||||
// RegistrationViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 13/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RegistrationViewController.h"
|
||||
|
||||
|
||||
#import "Environment.h"
|
||||
#import "LocalizableText.h"
|
||||
#import "NBAsYouTypeFormatter.h"
|
||||
#import "PhoneNumber.h"
|
||||
#import "PhoneNumberDirectoryFilterManager.h"
|
||||
#import "PhoneNumberUtil.h"
|
||||
#import "PreferencesUtil.h"
|
||||
#import "PushManager.h"
|
||||
#import "RPServerRequestsManager.h"
|
||||
#import "SignalUtil.h"
|
||||
#import "SGNKeychainUtil.h"
|
||||
#import "ThreadManager.h"
|
||||
#import "Util.h"
|
||||
|
||||
#import <Pastelog.h>
|
||||
|
||||
#define kKeyboardPadding 10.0f
|
||||
|
||||
|
||||
@interface RegistrationViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation RegistrationViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
[self populateDefaultCountryNameAndCode];
|
||||
[self initializeKeyboardHandlers];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Locale
|
||||
|
||||
- (void)populateDefaultCountryNameAndCode {
|
||||
NSLocale *locale = NSLocale.currentLocale;
|
||||
NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];
|
||||
NSNumber *cc = [NBPhoneNumberUtil.sharedInstance getCountryCodeForRegion:countryCode];
|
||||
|
||||
_countryCodeLabel.text = [NSString stringWithFormat:@"%@%@",COUNTRY_CODE_PREFIX, cc];
|
||||
//_countryNameLabel.text = [PhoneNumberUtil countryNameFromCountryCode:countryCode];
|
||||
_countryNameLabel.text = @"United States";
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)sendCodeAction:(id)sender {
|
||||
NSString *phoneNumber = [NSString stringWithFormat:@"%@%@", _countryCodeLabel.text, _phoneNumberTextField.text];
|
||||
PhoneNumber* localNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber];
|
||||
if(localNumber==nil){ return; }
|
||||
|
||||
[_phoneNumberTextField resignFirstResponder];
|
||||
|
||||
// perform RPServerRequest here
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (IBAction)changeCountryCodeTapped {
|
||||
CountryCodeViewController *countryCodeController = [CountryCodeViewController new];
|
||||
countryCodeController.delegate = self;
|
||||
[self presentViewController:countryCodeController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)presentInvalidCountryCodeError {
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:REGISTER_CC_ERR_ALERT_VIEW_TITLE
|
||||
message:REGISTER_CC_ERR_ALERT_VIEW_MESSAGE
|
||||
delegate:nil
|
||||
cancelButtonTitle:REGISTER_CC_ERR_ALERT_VIEW_DISMISS
|
||||
otherButtonTitles:nil];
|
||||
[alertView show];
|
||||
}
|
||||
|
||||
#pragma mark - Keyboard notifications
|
||||
|
||||
- (void)initializeKeyboardHandlers{
|
||||
UITapGestureRecognizer *outsideTabRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)];
|
||||
[self.view addGestureRecognizer:outsideTabRecognizer];
|
||||
|
||||
[self observeKeyboardNotifications];
|
||||
|
||||
}
|
||||
|
||||
-(void) dismissKeyboardFromAppropriateSubView {
|
||||
[self.view endEditing:NO];
|
||||
}
|
||||
|
||||
- (void)observeKeyboardNotifications {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(keyboardWillShow:)
|
||||
name:UIKeyboardWillShowNotification
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(keyboardWillHide:)
|
||||
name:UIKeyboardWillHideNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)keyboardWillShow:(NSNotification *)notification {
|
||||
double duration = [[notification userInfo][UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
||||
[UIView animateWithDuration:duration animations:^{
|
||||
CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
|
||||
self.view.frame = CGRectMake(CGRectGetMinX(self.view.frame),
|
||||
CGRectGetMinY(self.view.frame)-keyboardSize.height+kKeyboardPadding,
|
||||
CGRectGetWidth(self.view.frame),
|
||||
CGRectGetHeight(self.view.frame));
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)keyboardWillHide:(NSNotification *)notification {
|
||||
double duration = [[notification userInfo][UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
||||
[UIView animateWithDuration:duration animations:^{
|
||||
CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
|
||||
self.view.frame = CGRectMake(CGRectGetMinX(self.view.frame),
|
||||
CGRectGetMinY(self.view.frame)+keyboardSize.height-kKeyboardPadding,
|
||||
CGRectGetWidth(self.view.frame),
|
||||
CGRectGetHeight(self.view.frame));
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - CountryCodeViewControllerDelegate
|
||||
|
||||
- (void)countryCodeViewController:(CountryCodeViewController *)vc
|
||||
didSelectCountryCode:(NSString *)code
|
||||
forCountry:(NSString *)country {
|
||||
|
||||
//NOTE: It seems [PhoneNumberUtil countryNameFromCountryCode:] doesn't return the country at all. Will investigate.
|
||||
_countryCodeLabel.text = code;
|
||||
_countryNameLabel.text = country;
|
||||
|
||||
// Reformat phone number
|
||||
NSString* digits = _phoneNumberTextField.text.digitsOnly;
|
||||
NSString* reformattedNumber = [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:digits
|
||||
withSpecifiedCountryCodeString:_countryCodeLabel.text];
|
||||
_phoneNumberTextField.text = reformattedNumber;
|
||||
UITextPosition *pos = _phoneNumberTextField.endOfDocument;
|
||||
[_phoneNumberTextField setSelectedTextRange:[_phoneNumberTextField textRangeFromPosition:pos toPosition:pos]];
|
||||
|
||||
// Done choosing country
|
||||
[vc dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)countryCodeViewControllerDidCancel:(CountryCodeViewController *)vc {
|
||||
[vc dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
|
||||
NSString* textBeforeChange = textField.text;
|
||||
|
||||
// backspacing should skip over formatting characters
|
||||
UITextPosition *posIfBackspace = [textField positionFromPosition:textField.beginningOfDocument
|
||||
offset:(NSInteger)(range.location + range.length)];
|
||||
UITextRange *rangeIfBackspace = [textField textRangeFromPosition:posIfBackspace toPosition:posIfBackspace];
|
||||
bool isBackspace = string.length == 0 && range.length == 1 && [rangeIfBackspace isEqual:textField.selectedTextRange];
|
||||
if (isBackspace) {
|
||||
NSString* digits = textBeforeChange.digitsOnly;
|
||||
NSUInteger correspondingDeletePosition = [PhoneNumberUtil translateCursorPosition:range.location + range.length
|
||||
from:textBeforeChange
|
||||
to:digits
|
||||
stickingRightward:true];
|
||||
if (correspondingDeletePosition > 0) {
|
||||
textBeforeChange = digits;
|
||||
range = NSMakeRange(correspondingDeletePosition - 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// make the proposed change
|
||||
NSString* textAfterChange = [textBeforeChange withCharactersInRange:range replacedBy:string];
|
||||
NSUInteger cursorPositionAfterChange = range.location + string.length;
|
||||
|
||||
// reformat the phone number, trying to keep the cursor beside the inserted or deleted digit
|
||||
bool isJustDeletion = string.length == 0;
|
||||
NSString* textAfterReformat = [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:textAfterChange.digitsOnly
|
||||
withSpecifiedCountryCodeString:_countryCodeLabel.text];
|
||||
NSUInteger cursorPositionAfterReformat = [PhoneNumberUtil translateCursorPosition:cursorPositionAfterChange
|
||||
from:textAfterChange
|
||||
to:textAfterReformat
|
||||
stickingRightward:isJustDeletion];
|
||||
textField.text = textAfterReformat;
|
||||
UITextPosition *pos = [textField positionFromPosition:textField.beginningOfDocument
|
||||
offset:(NSInteger)cursorPositionAfterReformat];
|
||||
[textField setSelectedTextRange:[textField textRangeFromPosition:pos toPosition:pos]];
|
||||
|
||||
return NO; // inform our caller that we took care of performing the change
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
21
Signal/src/view controllers/SettingsTableViewCell.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// SettingsTableViewCell.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 11/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface SettingsTableViewCell : UITableViewCell
|
||||
|
||||
//Regular cell
|
||||
@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
|
47
Signal/src/view controllers/SettingsTableViewCell.m
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// SettingsTableViewCell.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 11/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SettingsTableViewCell.h"
|
||||
|
||||
@implementation SettingsTableViewCell
|
||||
|
||||
- (void)awakeFromNib {
|
||||
// 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 {
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
#pragma mark - UISwitch
|
||||
|
||||
-(void)toggleSetting:(id)sender
|
||||
{
|
||||
if ([self.reuseIdentifier isEqualToString:@"hideContactImages"])
|
||||
{
|
||||
self.state.text = self.toggle.isOn ? @"Yes" : @"No";
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Editing Profile
|
||||
-(void)changeImageView:(id)sender
|
||||
{
|
||||
NSLog(@"hi");
|
||||
|
||||
}
|
||||
|
||||
@end
|
13
Signal/src/view controllers/SettingsTableViewController.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// SettingsTableViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 03/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface SettingsTableViewController : UITableViewController
|
||||
|
||||
@end
|
131
Signal/src/view controllers/SettingsTableViewController.m
Normal file
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// SettingsTableViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 03/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SettingsTableViewController.h"
|
||||
#import "DJWActionSheet.h"
|
||||
#import "SettingsTableViewCell.h"
|
||||
|
||||
#define kProfileCellHeight 180.0f
|
||||
#define kStandardCellHeight 60.0f
|
||||
|
||||
#define kNumberOfSections 2
|
||||
|
||||
#define kClearHistoryLogCellRow 4
|
||||
#define kSendDebugLogCellRow 6
|
||||
|
||||
|
||||
typedef enum {
|
||||
kProfileRows = 1,
|
||||
kSecurityRows = 7,
|
||||
} kRowsForSection;
|
||||
|
||||
typedef enum {
|
||||
kProfileSection,
|
||||
kSecuritySection,
|
||||
} kSection;
|
||||
|
||||
@interface SettingsTableViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation SettingsTableViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return kNumberOfSections;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
|
||||
switch (section) {
|
||||
case kProfileSection:
|
||||
return kProfileRows;
|
||||
break;
|
||||
case kSecuritySection:
|
||||
return kSecurityRows;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
switch (indexPath.section) {
|
||||
case kProfileSection:
|
||||
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 ? This action cannot be reverted."
|
||||
cancelButtonTitle:@"Cancel"
|
||||
destructiveButtonTitle:nil
|
||||
otherButtonTitles:@[@"I'm sure."]
|
||||
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
|
||||
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
|
||||
NSLog(@"User Cancelled");
|
||||
|
||||
} else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
|
||||
NSLog(@"Destructive button tapped");
|
||||
}else {
|
||||
NSLog(@"The user tapped button at index: %li", (long)tappedButtonIndex);
|
||||
}
|
||||
}];
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case kSendDebugLogCellRow:
|
||||
//Send debug Log
|
||||
break;
|
||||
default:
|
||||
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");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
19
Signal/src/view controllers/SignalsNavigationController.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// SignalsNavigationController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 18/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Socket.h"
|
||||
|
||||
@interface SignalsNavigationController : UINavigationController
|
||||
|
||||
@property (nonatomic, strong) Socket * socket;
|
||||
|
||||
@property (nonatomic, strong) UIProgressView* socketStatusView;
|
||||
|
||||
|
||||
@end
|
74
Signal/src/view controllers/SignalsNavigationController.m
Normal file
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// SignalsNavigationController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 18/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SignalsNavigationController.h"
|
||||
|
||||
@interface SignalsNavigationController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation SignalsNavigationController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
[self initializeSocketStatusBar];
|
||||
|
||||
_socket = [[Socket alloc]init];
|
||||
|
||||
[self initializeObserver];
|
||||
|
||||
_socket.status = kSocketStatusOpen;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
-(void)initializeSocketStatusBar
|
||||
{
|
||||
_socketStatusView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault];
|
||||
|
||||
CGRect bar = self.navigationBar.frame;
|
||||
_socketStatusView.frame = CGRectMake(0, bar.size.height-1.0f, self.view.frame.size.width, 1.0f);
|
||||
_socketStatusView.progressTintColor = [UIColor greenColor];
|
||||
_socketStatusView.progress = 1.0f;
|
||||
[self.navigationBar addSubview:_socketStatusView];
|
||||
}
|
||||
|
||||
#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
|
||||
{
|
||||
_socketStatusView.progressTintColor = [UIColor greenColor];
|
||||
}
|
||||
|
||||
-(void)socketDidClose
|
||||
{
|
||||
_socketStatusView.progressTintColor = [UIColor redColor];
|
||||
|
||||
}
|
||||
|
||||
-(void)socketIsConnecting
|
||||
{
|
||||
_socketStatusView.progressTintColor = [UIColor yellowColor];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
29
Signal/src/view controllers/Socket.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// Socket.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 18/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
kSocketStatusOpen,
|
||||
kSocketStatusClosed,
|
||||
kSocketStatusConnecting,
|
||||
} SocketStatus;
|
||||
|
||||
static void *kSocketStatusObservationContext = &kSocketStatusObservationContext;
|
||||
|
||||
extern NSString * const SocketOpenedNotification;
|
||||
extern NSString * const SocketClosedNotification;
|
||||
extern NSString * const SocketConnectingNotification;
|
||||
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Socket : NSObject
|
||||
|
||||
@property (nonatomic) SocketStatus status;
|
||||
|
||||
@end
|
52
Signal/src/view controllers/Socket.m
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// Socket.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 18/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Socket.h"
|
||||
|
||||
NSString * const SocketOpenedNotification = @"SocketOpenedNotification";
|
||||
NSString * const SocketClosedNotification = @"SocketClosedNotification";
|
||||
NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||
|
||||
@implementation Socket
|
||||
|
||||
-(instancetype)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_status = kSocketStatusConnecting;
|
||||
[self addObserver:self forKeyPath:@"status" options:0 context:kSocketStatusObservationContext];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||
|
||||
if (context == kSocketStatusObservationContext)
|
||||
{
|
||||
switch (self.status) {
|
||||
case kSocketStatusOpen:
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SocketOpenedNotification object:self];
|
||||
break;
|
||||
case kSocketStatusClosed:
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SocketClosedNotification object:self];
|
||||
break;
|
||||
case kSocketStatusConnecting:
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SocketConnectingNotification object:self];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4510" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6249" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6243"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="TabBarParentViewController">
|
||||
|
@ -24,7 +25,6 @@
|
|||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TxK-UA-SMw">
|
||||
<rect key="frame" x="0.0" y="504" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.13725490196078433" green="0.12156862745098039" blue="0.12549019607843137" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="64" id="Esv-J1-3fb"/>
|
||||
|
@ -40,7 +40,6 @@
|
|||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TEC-kG-R8z">
|
||||
<rect key="frame" x="64" y="504" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.13725490196078433" green="0.12156862745098039" blue="0.12549019607843137" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="64" id="bOG-hx-3TL"/>
|
||||
|
@ -57,7 +56,6 @@
|
|||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UaS-5R-mL2">
|
||||
<rect key="frame" x="128" y="504" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.13725490196078433" green="0.12156862745098039" blue="0.12549019607843137" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="64" id="Jhu-0r-7dg"/>
|
||||
|
@ -74,7 +72,6 @@
|
|||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Yv9-Bj-1YZ">
|
||||
<rect key="frame" x="192" y="504" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.13725490196078433" green="0.12156862745098039" blue="0.12549019607843137" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="64" id="BP0-IJ-0NY"/>
|
||||
|
@ -92,7 +89,6 @@
|
|||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fjJ-JY-NGI">
|
||||
<rect key="frame" x="256" y="504" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.13725490196078433" green="0.12156862745098039" blue="0.12549019607843137" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="64" id="78C-ec-QrH"/>
|
||||
|
@ -109,7 +105,6 @@
|
|||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EuB-DL-7PE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="504"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.13725490200000001" green="0.1215686275" blue="0.12549019610000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="tintColor" red="0.13725490200000001" green="0.1215686275" blue="0.12549019610000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
|
@ -118,7 +113,6 @@
|
|||
</view>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B7o-32-9AW">
|
||||
<rect key="frame" x="128" y="557" width="64" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.5450980392" blue="0.93725490199999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="64" id="5N0-Nd-wG3"/>
|
||||
|
@ -129,7 +123,6 @@
|
|||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="notification_mini_icon.png" translatesAutoresizingMaskIntoConstraints="NO" id="TNS-1q-kpu">
|
||||
<rect key="frame" x="232" y="512" width="24" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
@ -152,8 +145,6 @@
|
|||
<constraint firstItem="fjJ-JY-NGI" firstAttribute="top" secondItem="EuB-DL-7PE" secondAttribute="bottom" id="wyn-Ek-AKc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Yv9-Bj-1YZ" secondAttribute="bottom" id="yXh-ay-seH"/>
|
||||
</constraints>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
@ -164,4 +155,9 @@
|
|||
<image name="tab_icon_keypad.png" width="24" height="24"/>
|
||||
<image name="tab_icon_menu.png" width="36" height="27"/>
|
||||
</resources>
|
||||
</document>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
47
Signal/src/view controllers/TableViewCell.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// TableViewCell.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "DemoDataModel.h"
|
||||
#import "NextResponderScrollView.h"
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
kArchiveState,
|
||||
kInboxState,
|
||||
} CellState;
|
||||
|
||||
@class TableViewCell;
|
||||
@protocol TableViewCellDelegate <NSObject>
|
||||
|
||||
- (void)tableViewCellTappedDelete:(TableViewCell *)cell;
|
||||
- (void)tableViewCellTappedArchive:(TableViewCell *)cell;
|
||||
|
||||
@end
|
||||
|
||||
@interface TableViewCell : UITableViewCell <UIScrollViewDelegate>
|
||||
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIImageView* lastActionImageView;
|
||||
@property (nonatomic, strong) IBOutlet UILabel *nameLabel;
|
||||
@property (nonatomic, strong) IBOutlet UILabel * snippetLabel;
|
||||
@property (nonatomic, strong) IBOutlet UIImageView *contactPictureView;
|
||||
@property (nonatomic, strong) IBOutlet UILabel *timeLabel;
|
||||
@property (nonatomic, strong) IBOutlet NextResponderScrollView *scrollView;
|
||||
@property (nonatomic, strong) IBOutlet UIView *contentContainerView;
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIView *deleteView;
|
||||
@property (nonatomic, strong) IBOutlet UIView *archiveView;
|
||||
@property (nonatomic, strong) IBOutlet UIImageView *deleteImageView;
|
||||
@property (nonatomic, strong) IBOutlet UIImageView *archiveImageView;
|
||||
@property (nonatomic, assign) id<TableViewCellDelegate> delegate;
|
||||
|
||||
-(void)configureWithTestMessage:(DemoDataModel*)testMessage;
|
||||
-(void)configureForState:(CellState)state;
|
||||
-(void)animateDisappear;
|
||||
|
||||
@end
|
181
Signal/src/view controllers/TableViewCell.m
Normal file
|
@ -0,0 +1,181 @@
|
|||
//
|
||||
// TableViewCell.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TableViewCell.h"
|
||||
#import "Util.h"
|
||||
|
||||
#define ARCHIVE_IMAGE_VIEW_WIDTH 22.0f
|
||||
#define DELETE_IMAGE_VIEW_WIDTH 19.0f
|
||||
#define TIME_LABEL_SIZE 10
|
||||
#define DATE_LABEL_SIZE 13
|
||||
|
||||
|
||||
@implementation TableViewCell
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
||||
self = [NSBundle.mainBundle loadNibNamed:NSStringFromClass(self.class)
|
||||
owner:self
|
||||
options:nil][0];
|
||||
|
||||
|
||||
if (self) {
|
||||
_scrollView.contentSize = CGSizeMake(CGRectGetWidth(_contentContainerView.bounds),
|
||||
CGRectGetHeight(_scrollView.frame));
|
||||
|
||||
[UIUtil applyRoundedBorderToImageView:&_contactPictureView];
|
||||
|
||||
_scrollView.contentOffset = CGPointMake(CGRectGetWidth(_archiveView.frame), 0);
|
||||
_deleteImageView.image = [_deleteImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
|
||||
_archiveImageView.image = [_archiveImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
|
||||
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)reuseIdentifier {
|
||||
return NSStringFromClass(self.class);
|
||||
}
|
||||
|
||||
-(void)configureWithTestMessage:(DemoDataModel*)testMessage {
|
||||
_nameLabel.text = testMessage._sender;
|
||||
_snippetLabel.text = testMessage._snippet;
|
||||
_contactPictureView.image = nil;
|
||||
_timeLabel.attributedText = [self dateArrributedString:[NSDate date]];
|
||||
self.separatorInset = UIEdgeInsetsMake(0,_contactPictureView.frame.size.width*1.5f, 0, 0);
|
||||
|
||||
[self setUpLastAction:testMessage.lastActionString];
|
||||
|
||||
}
|
||||
|
||||
-(void)configureForState:(CellState)state
|
||||
{
|
||||
switch (state) {
|
||||
case kArchiveState:
|
||||
_scrollView.userInteractionEnabled=NO;
|
||||
break;
|
||||
case kInboxState:
|
||||
_scrollView.userInteractionEnabled=YES;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setUpLastAction:(NSString*)lastAction {
|
||||
|
||||
//TODO: Set up KVO
|
||||
if ([lastAction isEqualToString:@"read"]) {
|
||||
_lastActionImageView.image = [UIImage imageNamed:@"checkmark"];
|
||||
} else if ([lastAction isEqualToString:@"replied"]) {
|
||||
_lastActionImageView.image = [UIImage imageNamed:@"reply"];
|
||||
} else if ([lastAction isEqualToString:@"missedCall"]) {
|
||||
_lastActionImageView.image = [UIImage imageNamed:@"missed"];
|
||||
} else if ([lastAction isEqualToString:@"outgoingCall"]) {
|
||||
_lastActionImageView.image = [UIImage imageNamed:@"received"];
|
||||
} else if ([lastAction isEqualToString:@"unread"]) {
|
||||
_lastActionImageView.image = nil;
|
||||
_snippetLabel.textColor = [UIColor blackColor];
|
||||
_nameLabel.font = [UIFont boldSystemFontOfSize:15];
|
||||
_timeLabel.textColor = [UIColor colorWithRed:0 green:91/255.f blue:1.0f alpha:1.0f];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Date formatting
|
||||
|
||||
- (NSAttributedString *)dateArrributedString:(NSDate *)date {
|
||||
|
||||
NSString *timeString = [[DateUtil timeFormatter] stringFromDate:date];
|
||||
|
||||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:timeString];
|
||||
|
||||
[attributedString addAttribute:NSForegroundColorAttributeName
|
||||
value:[UIColor darkGrayColor]
|
||||
range:NSMakeRange(0, timeString.length)];
|
||||
|
||||
|
||||
|
||||
[attributedString addAttribute:NSFontAttributeName
|
||||
value:[UIUtil helveticaLightWithSize:TIME_LABEL_SIZE]
|
||||
range:NSMakeRange(0, timeString.length)];
|
||||
|
||||
|
||||
return attributedString;
|
||||
}
|
||||
|
||||
#pragma mark - UIScrollViewDelegate
|
||||
|
||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
|
||||
|
||||
if (_scrollView.contentOffset.x < 0) {
|
||||
_archiveImageView.image = [UIImage imageNamed:@"blue-archive"];
|
||||
_archiveImageView.bounds = CGRectMake(_archiveImageView.bounds.origin.x,
|
||||
_archiveImageView.bounds.origin.y,
|
||||
ARCHIVE_IMAGE_VIEW_WIDTH,
|
||||
_archiveImageView.bounds.size.height);
|
||||
} else {
|
||||
|
||||
double ratio = (_archiveView.frame.size.width/2.0f - _scrollView.contentOffset.x) / (_archiveView.frame.size.width/2.0f);
|
||||
double newWidth = ARCHIVE_IMAGE_VIEW_WIDTH/2.0f + (ARCHIVE_IMAGE_VIEW_WIDTH * ratio)/2.0f;
|
||||
_archiveImageView.bounds = CGRectMake(_archiveImageView.bounds.origin.x,
|
||||
_archiveImageView.bounds.origin.y,
|
||||
(CGFloat)newWidth,
|
||||
_archiveImageView.bounds.size.height);
|
||||
_archiveImageView.tintColor = UIColor.whiteColor;
|
||||
|
||||
}
|
||||
|
||||
if (scrollView.contentOffset.x > CGRectGetWidth(_archiveView.frame)*2) {
|
||||
_deleteImageView.image = [UIImage imageNamed:@"red-delete"];
|
||||
_deleteImageView.bounds = CGRectMake(_deleteImageView.bounds.origin.x,
|
||||
_deleteImageView.bounds.origin.y,
|
||||
DELETE_IMAGE_VIEW_WIDTH,
|
||||
_deleteImageView.bounds.size.height);
|
||||
} else {
|
||||
|
||||
double ratio = _scrollView.contentOffset.x / (CGRectGetWidth(_deleteView.frame)*2);
|
||||
double newWidth = DELETE_IMAGE_VIEW_WIDTH/2.0f + (DELETE_IMAGE_VIEW_WIDTH * ratio)/2.0f;
|
||||
|
||||
_deleteImageView.bounds = CGRectMake(_deleteImageView.bounds.origin.x,
|
||||
_deleteImageView.bounds.origin.y,
|
||||
(CGFloat)newWidth,
|
||||
_deleteImageView.bounds.size.height);
|
||||
_deleteImageView.tintColor = UIColor.whiteColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
|
||||
withVelocity:(CGPoint)velocity
|
||||
targetContentOffset:(inout CGPoint *)targetContentOffset {
|
||||
|
||||
if (_scrollView.contentOffset.x < 0) {
|
||||
[_delegate tableViewCellTappedArchive:self];
|
||||
} else {
|
||||
*targetContentOffset = CGPointMake(CGRectGetWidth(_archiveView.frame), 0);
|
||||
}
|
||||
|
||||
if (scrollView.contentOffset.x > CGRectGetWidth(_archiveView.frame)*2) {
|
||||
[_delegate tableViewCellTappedDelete:self];
|
||||
} else {
|
||||
*targetContentOffset = CGPointMake(CGRectGetWidth(_archiveView.frame), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Animation
|
||||
|
||||
-(void)animateDisappear
|
||||
{
|
||||
[UIView animateWithDuration:1.0f animations:^(){
|
||||
self.alpha = 0;
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@end
|
155
Signal/src/view controllers/TableViewCell.xib
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="TableViewCell" rowHeight="72" id="axX-Rb-kiK" customClass="TableViewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="72"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<tableViewCellContentView key="contentView" multipleTouchEnabled="YES" contentMode="center" tableViewCell="axX-Rb-kiK" id="BRG-hJ-lRa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="318" height="71"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3rD-4i-EKG" userLabel="Delete View">
|
||||
<rect key="frame" x="299" y="0.0" width="102" height="71"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="delete.png" translatesAutoresizingMaskIntoConstraints="NO" id="TBw-ud-Ysk">
|
||||
<rect key="frame" x="50" y="23" width="19" height="25"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="102" id="sEr-Wb-h8b"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yBY-TS-2tI" userLabel="Archive View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="102" height="71"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="archive.png" translatesAutoresizingMaskIntoConstraints="NO" id="WyX-Hb-Mpn">
|
||||
<rect key="frame" x="40" y="25" width="22" height="22"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</view>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceHorizontal="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bG5-iK-ql3" customClass="NextResponderScrollView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="72"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kq8-RD-txC" userLabel="Container View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="604" height="72"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wco-u2-Bz6">
|
||||
<rect key="frame" x="92" y="0.0" width="410" height="72"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="contact_default_feed.png" translatesAutoresizingMaskIntoConstraints="NO" id="p9o-x6-nT5">
|
||||
<rect key="frame" x="115" y="10" width="52" height="53"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qgj-EY-BWC">
|
||||
<rect key="frame" x="180" y="31" width="200" height="35"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="Name Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gWV-cB-qZe">
|
||||
<rect key="frame" x="180" y="8" width="180" height="30"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="17"/>
|
||||
<color key="textColor" red="0.13725490200000001" green="0.1215686275" blue="0.12549019610000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Thursday" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bp6-EC-9eP">
|
||||
<rect key="frame" x="426" y="15" width="56" height="17"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="14"/>
|
||||
<color key="textColor" red="0.13725490200000001" green="0.1215686275" blue="0.12549019610000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="reply.png" translatesAutoresizingMaskIntoConstraints="NO" id="BV6-Tp-SmZ">
|
||||
<rect key="frame" x="459" y="35" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="FZI-2j-0TT"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dGa-iy-WtH" userLabel="Archive View">
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HWq-U9-n0t" userLabel="Delete View">
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerX" secondItem="Wco-u2-Bz6" secondAttribute="centerX" constant="-10" id="3FF-mP-SEU"/>
|
||||
<constraint firstItem="Wco-u2-Bz6" firstAttribute="leading" secondItem="kq8-RD-txC" secondAttribute="leading" constant="92" id="7CN-Mr-Ecm"/>
|
||||
<constraint firstItem="BV6-Tp-SmZ" firstAttribute="top" secondItem="Wco-u2-Bz6" secondAttribute="bottom" constant="-37" id="AoW-bB-S5N"/>
|
||||
<constraint firstItem="Wco-u2-Bz6" firstAttribute="centerY" secondItem="bp6-EC-9eP" secondAttribute="centerY" constant="12.5" id="EGs-nA-2nC"/>
|
||||
<constraint firstAttribute="centerY" secondItem="Wco-u2-Bz6" secondAttribute="centerY" id="GZX-5M-GH9"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Wco-u2-Bz6" secondAttribute="bottom" id="IZD-iJ-o1H"/>
|
||||
<constraint firstItem="Wco-u2-Bz6" firstAttribute="centerY" secondItem="BV6-Tp-SmZ" secondAttribute="centerY" constant="-9" id="aMK-6Q-s3n"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Wco-u2-Bz6" secondAttribute="trailing" constant="102" id="bSf-ft-rxR"/>
|
||||
<constraint firstItem="Wco-u2-Bz6" firstAttribute="top" secondItem="kq8-RD-txC" secondAttribute="top" id="dXQ-dR-4SK"/>
|
||||
<constraint firstItem="Wco-u2-Bz6" firstAttribute="trailing" secondItem="bp6-EC-9eP" secondAttribute="trailing" constant="20" id="jDm-3D-SbD"/>
|
||||
<constraint firstItem="BV6-Tp-SmZ" firstAttribute="centerX" secondItem="bp6-EC-9eP" secondAttribute="centerX" constant="15" id="nLR-lQ-dJH"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="3FF-mP-SEU"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="kq8-RD-txC" secondAttribute="trailing" id="3iz-A6-N93"/>
|
||||
<constraint firstItem="kq8-RD-txC" firstAttribute="top" secondItem="bG5-iK-ql3" secondAttribute="top" id="An4-9G-IYU"/>
|
||||
<constraint firstItem="kq8-RD-txC" firstAttribute="leading" secondItem="bG5-iK-ql3" secondAttribute="leading" id="HqR-mX-M8E"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kq8-RD-txC" secondAttribute="centerX" constant="-102" id="LkM-VZ-WRa"/>
|
||||
<constraint firstAttribute="bottom" secondItem="kq8-RD-txC" secondAttribute="bottom" id="nsI-NR-f3Y"/>
|
||||
<constraint firstAttribute="centerY" secondItem="kq8-RD-txC" secondAttribute="centerY" id="q6R-fT-3Qv"/>
|
||||
<constraint firstAttribute="height" constant="72" id="s7n-Dd-n3b"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="axX-Rb-kiK" id="TMe-oF-FQE"/>
|
||||
</connections>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerX" secondItem="bG5-iK-ql3" secondAttribute="centerX" id="1eG-bp-0aH"/>
|
||||
<constraint firstItem="bG5-iK-ql3" firstAttribute="leading" secondItem="BRG-hJ-lRa" secondAttribute="leadingMargin" constant="-8" id="Dmq-W5-Xkr"/>
|
||||
<constraint firstAttribute="centerY" secondItem="bG5-iK-ql3" secondAttribute="centerY" constant="-0.25" id="IQe-4d-baG"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="3rD-4i-EKG" secondAttribute="trailing" constant="23" id="LCr-QP-vla"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="3rD-4i-EKG" secondAttribute="bottom" constant="-7.5" id="SPU-lp-rQv"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="3rD-4i-EKG" secondAttribute="trailing" constant="-9" id="SbS-PB-jL2"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="bG5-iK-ql3" secondAttribute="trailing" constant="-8" id="ikW-Es-Ngp"/>
|
||||
<constraint firstItem="3rD-4i-EKG" firstAttribute="top" secondItem="BRG-hJ-lRa" secondAttribute="topMargin" constant="-8" id="yxg-lB-7gK"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="LCr-QP-vla"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="archiveImageView" destination="WyX-Hb-Mpn" id="99i-j3-F49"/>
|
||||
<outlet property="archiveView" destination="yBY-TS-2tI" id="Olb-KX-yw5"/>
|
||||
<outlet property="contactPictureView" destination="p9o-x6-nT5" id="oUA-O3-JIc"/>
|
||||
<outlet property="contentContainerView" destination="kq8-RD-txC" id="yaJ-z3-8sC"/>
|
||||
<outlet property="deleteImageView" destination="TBw-ud-Ysk" id="a1T-GR-0cx"/>
|
||||
<outlet property="deleteView" destination="3rD-4i-EKG" id="oak-Hh-6CC"/>
|
||||
<outlet property="lastActionImageView" destination="BV6-Tp-SmZ" id="UvX-Wb-tWS"/>
|
||||
<outlet property="nameLabel" destination="gWV-cB-qZe" id="drr-G2-EB6"/>
|
||||
<outlet property="scrollView" destination="bG5-iK-ql3" id="wEp-AH-Pdu"/>
|
||||
<outlet property="snippetLabel" destination="Qgj-EY-BWC" id="EIb-je-Cw5"/>
|
||||
<outlet property="timeLabel" destination="bp6-EC-9eP" id="O4O-ST-o3v"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="archive.png" width="100" height="100"/>
|
||||
<image name="contact_default_feed.png" width="242" height="242"/>
|
||||
<image name="delete.png" width="100" height="100"/>
|
||||
<image name="reply.png" width="100" height="100"/>
|
||||
</resources>
|
||||
</document>
|
25
Signal/src/view controllers/UITests/SignalsViewController.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// SignalsViewController.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#include "TableViewCell.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "GroupModel.h"
|
||||
|
||||
|
||||
@interface SignalsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, TableViewCellDelegate>
|
||||
|
||||
@property (nonatomic) Contact* contactFromCompose;
|
||||
@property (nonatomic) GroupModel* groupFromCompose;
|
||||
|
||||
@property (nonatomic,strong) IBOutlet UITableView* _tableView;
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl * segmentedControl;
|
||||
|
||||
|
||||
@end
|
157
Signal/src/view controllers/UITests/SignalsViewController.m
Normal file
|
@ -0,0 +1,157 @@
|
|||
//
|
||||
// SignalsViewController.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Dylan Bourgeois on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "DemoDataFactory.h"
|
||||
#import "TableViewCell.h"
|
||||
|
||||
#import "MessagesViewController.h"
|
||||
#import "SignalsViewController.h"
|
||||
|
||||
|
||||
#define CELL_HEIGHT 71.0f
|
||||
#define HEADER_HEIGHT 44.0f
|
||||
|
||||
|
||||
static NSString *const kCellNibName = @"TableViewCell";
|
||||
static NSString *const kSegueIndentifier = @"showSegue";
|
||||
|
||||
|
||||
@interface SignalsViewController () {
|
||||
NSArray * _dataArray;
|
||||
NSUInteger numberOfCells;
|
||||
|
||||
}
|
||||
@property (strong, nonatomic) DemoDataModel *demoData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SignalsViewController
|
||||
|
||||
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
|
||||
if (self) {
|
||||
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
|
||||
delegate.signalVC = self;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
_dataArray = [DemoDataFactory data];
|
||||
numberOfCells = _dataArray.count;
|
||||
[self tableViewSetUp];
|
||||
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
|
||||
-(void)tableViewSetUp
|
||||
{
|
||||
self._tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return (NSInteger)numberOfCells;
|
||||
}
|
||||
|
||||
- (TableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
return [self inboxFeedCellForIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
return CELL_HEIGHT;
|
||||
}
|
||||
|
||||
-(TableViewCell*)inboxFeedCellForIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
TableViewCell *cell = [self._tableView dequeueReusableCellWithIdentifier:kCellNibName];
|
||||
|
||||
|
||||
if (!cell) {
|
||||
cell = [[TableViewCell 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:(TableViewCell *)cell {
|
||||
NSLog(@"Delete");
|
||||
}
|
||||
|
||||
- (void)tableViewCellTappedArchive:(TableViewCell *)cell {
|
||||
NSLog(@"Archive");
|
||||
}
|
||||
|
||||
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[self performSegueWithIdentifier:kSegueIndentifier sender:self];
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - Navigation
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
|
||||
if ([segue.identifier isEqualToString:kSegueIndentifier])
|
||||
{
|
||||
MessagesViewController * vc = [segue destinationViewController];
|
||||
NSIndexPath *selectedIndexPath = [self._tableView indexPathForSelectedRow];
|
||||
if (selectedIndexPath) {
|
||||
vc._senderTitleString = ((DemoDataModel*)_dataArray[(NSUInteger)selectedIndexPath.row])._sender;
|
||||
} else if (_contactFromCompose) {
|
||||
vc._senderTitleString = _contactFromCompose.fullName;
|
||||
} else if (_groupFromCompose) {
|
||||
vc._senderTitleString = _groupFromCompose.groupName;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - IBAction
|
||||
|
||||
-(IBAction)segmentDidChange:(id)sender
|
||||
{
|
||||
switch (_segmentedControl.selectedSegmentIndex) {
|
||||
case 0:
|
||||
numberOfCells=5;
|
||||
[self._tableView reloadData];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
numberOfCells=3;
|
||||
[self._tableView reloadData];
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
@end
|
|
@ -1,14 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1552</int>
|
||||
<string key="IBDocument.SystemVersion">12F37</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.39</string>
|
||||
<string key="IBDocument.HIToolboxVersion">626.00</string>
|
||||
<int key="IBDocument.SystemTarget">1792</int>
|
||||
<string key="IBDocument.SystemVersion">14A388a</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">6250</string>
|
||||
<string key="IBDocument.AppKitVersion">1343.14</string>
|
||||
<string key="IBDocument.HIToolboxVersion">755.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">2083</string>
|
||||
<string key="NS.object.0">6244</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
|
@ -34,7 +34,7 @@
|
|||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBUIView" id="191373211">
|
||||
<reference key="NSNextResponder"/>
|
||||
<nil key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="IBUIButton" id="627495493">
|
||||
|
@ -49,21 +49,21 @@
|
|||
<int key="IBUIContentHorizontalAlignment">0</int>
|
||||
<int key="IBUIContentVerticalAlignment">0</int>
|
||||
<int key="IBUIButtonType">1</int>
|
||||
<string key="IBUINormalTitle">Answer</string>
|
||||
<object class="NSColor" key="IBUIHighlightedTitleColor" id="1030841825">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<object class="NSColor" key="IBUINormalTitleColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MCAwLjQ0ODMwNTg3NjQgMC4wMTQ0MjU2MDIyMQA</bytes>
|
||||
</object>
|
||||
<object class="NSColor" key="IBUIHighlightedTitleColor" id="1030841825">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<string key="IBUINormalTitle">Answer</string>
|
||||
<object class="IBUIFontDescription" key="IBUIFontDescription" id="973887861">
|
||||
<int key="type">2</int>
|
||||
<double key="pointSize">15</double>
|
||||
</object>
|
||||
<object class="NSFont" key="IBUIFont" id="533433202">
|
||||
<string key="NSName">Helvetica-Bold</string>
|
||||
<object class="NSFont" key="IBUIFont" id="791711818">
|
||||
<string key="NSName">HelveticaNeue-Bold</string>
|
||||
<double key="NSSize">15</double>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
|
@ -80,14 +80,14 @@
|
|||
<int key="IBUIContentHorizontalAlignment">0</int>
|
||||
<int key="IBUIContentVerticalAlignment">0</int>
|
||||
<int key="IBUIButtonType">1</int>
|
||||
<string key="IBUINormalTitle">Reject</string>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<object class="NSColor" key="IBUINormalTitleColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MC40NDgzMDU4NzY0IDAuMDEwNTY4MjM3MjkgMAA</bytes>
|
||||
</object>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<string key="IBUINormalTitle">Reject</string>
|
||||
<reference key="IBUIFontDescription" ref="973887861"/>
|
||||
<reference key="IBUIFont" ref="533433202"/>
|
||||
<reference key="IBUIFont" ref="791711818"/>
|
||||
</object>
|
||||
<object class="IBUIButton" id="997104522">
|
||||
<reference key="NSNextResponder" ref="191373211"/>
|
||||
|
@ -101,14 +101,14 @@
|
|||
<int key="IBUIContentHorizontalAlignment">0</int>
|
||||
<int key="IBUIContentVerticalAlignment">0</int>
|
||||
<int key="IBUIButtonType">1</int>
|
||||
<string key="IBUINormalTitle">Force Register</string>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<object class="NSColor" key="IBUINormalTitleColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MC40NDgzMDU4NzY0IDAuMDEwNTY4MjM3MjkgMAA</bytes>
|
||||
</object>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<string key="IBUINormalTitle">Force Register</string>
|
||||
<reference key="IBUIFontDescription" ref="973887861"/>
|
||||
<reference key="IBUIFont" ref="533433202"/>
|
||||
<reference key="IBUIFont" ref="791711818"/>
|
||||
</object>
|
||||
<object class="IBUIButton" id="318920417">
|
||||
<reference key="NSNextResponder" ref="191373211"/>
|
||||
|
@ -122,14 +122,14 @@
|
|||
<int key="IBUIContentHorizontalAlignment">0</int>
|
||||
<int key="IBUIContentVerticalAlignment">0</int>
|
||||
<int key="IBUIButtonType">1</int>
|
||||
<string key="IBUINormalTitle">Call ...</string>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<object class="NSColor" key="IBUINormalTitleColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MCAwLjQ0ODMwNTg3NjQgMC4wMTQ0MjU2MDIyMQA</bytes>
|
||||
</object>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<string key="IBUINormalTitle">Call ...</string>
|
||||
<reference key="IBUIFontDescription" ref="973887861"/>
|
||||
<reference key="IBUIFont" ref="533433202"/>
|
||||
<reference key="IBUIFont" ref="791711818"/>
|
||||
</object>
|
||||
<object class="IBUIButton" id="727423514">
|
||||
<reference key="NSNextResponder" ref="191373211"/>
|
||||
|
@ -143,14 +143,14 @@
|
|||
<int key="IBUIContentHorizontalAlignment">0</int>
|
||||
<int key="IBUIContentVerticalAlignment">0</int>
|
||||
<int key="IBUIButtonType">1</int>
|
||||
<string key="IBUINormalTitle">Hangup</string>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<object class="NSColor" key="IBUINormalTitleColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MC41IDAgMAA</bytes>
|
||||
</object>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="1030841825"/>
|
||||
<string key="IBUINormalTitle">Hangup</string>
|
||||
<reference key="IBUIFontDescription" ref="973887861"/>
|
||||
<reference key="IBUIFont" ref="533433202"/>
|
||||
<reference key="IBUIFont" ref="791711818"/>
|
||||
</object>
|
||||
<object class="IBUITableView" id="66560115">
|
||||
<reference key="NSNextResponder" ref="191373211"/>
|
||||
|
@ -195,8 +195,8 @@
|
|||
<int key="type">1</int>
|
||||
<double key="pointSize">17</double>
|
||||
</object>
|
||||
<object class="NSFont" key="IBUIFont" id="25549041">
|
||||
<string key="NSName">Helvetica</string>
|
||||
<object class="NSFont" key="IBUIFont" id="234669106">
|
||||
<string key="NSName">HelveticaNeue</string>
|
||||
<double key="NSSize">17</double>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
|
@ -222,7 +222,7 @@
|
|||
<int key="IBUINumberOfLines">10</int>
|
||||
<int key="IBUILineBreakMode">0</int>
|
||||
<reference key="IBUIFontDescription" ref="638011444"/>
|
||||
<reference key="IBUIFont" ref="25549041"/>
|
||||
<reference key="IBUIFont" ref="234669106"/>
|
||||
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
|
||||
<double key="preferredMaxLayoutWidth">301</double>
|
||||
</object>
|
||||
|
@ -245,13 +245,12 @@
|
|||
<int key="IBUINumberOfLines">10</int>
|
||||
<int key="IBUILineBreakMode">0</int>
|
||||
<reference key="IBUIFontDescription" ref="638011444"/>
|
||||
<reference key="IBUIFont" ref="25549041"/>
|
||||
<reference key="IBUIFont" ref="234669106"/>
|
||||
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
|
||||
<double key="preferredMaxLayoutWidth">301</double>
|
||||
</object>
|
||||
</array>
|
||||
<string key="NSFrame">{{0, 20}, {320, 548}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSNextKeyView" ref="318920417"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
|
@ -263,6 +262,8 @@
|
|||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
|
||||
<object class="IBUIScreenMetrics" key="IBUISimulatedDestinationMetrics">
|
||||
<string key="IBUISimulatedSizeMetricsClass">IBUIScreenMetrics</string>
|
||||
<string key="IBUITargetRuntime">IBCocoaTouchFramework</string>
|
||||
<string key="IBUIDisplayName">iPhone 4-inch</string>
|
||||
<object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<array key="dict.sortedKeys">
|
||||
|
@ -274,15 +275,13 @@
|
|||
<string>{568, 320}</string>
|
||||
</array>
|
||||
</object>
|
||||
<string key="IBUITargetRuntime">IBCocoaTouchFramework</string>
|
||||
<string key="IBUIDisplayName">Retina 4 Full Screen</string>
|
||||
<int key="IBUIType">2</int>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<array key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
|
@ -532,8 +531,12 @@
|
|||
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBDocument.previouslyAttemptedUpgradeToXcode5">NO</bool>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
|
||||
<integer value="4600" key="NS.object.0"/>
|
||||
</object>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">2083</string>
|
||||
</data>
|
||||
</archive>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4510" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RecentCallsViewController">
|
||||
|
@ -94,8 +95,6 @@
|
|||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
@ -103,4 +102,9 @@
|
|||
<image name="search_cancel.png" width="18" height="18"/>
|
||||
<image name="search_icon.png" width="25" height="25"/>
|
||||
</resources>
|
||||
</document>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4510" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ContactBrowseViewController">
|
||||
|
@ -134,9 +135,7 @@ IFdoaXNwZXIhA
|
|||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
<simulatedTabBarMetrics key="simulatedBottomBarMetrics" translucent="NO"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
@ -146,4 +145,9 @@ IFdoaXNwZXIhA
|
|||
<image name="search_icon.png" width="25" height="25"/>
|
||||
<image name="whisper_notification_icon.png" width="28" height="17"/>
|
||||
</resources>
|
||||
</document>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13A2093" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
|
@ -14,7 +15,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="+1 (234)-567-8905" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="rFC-L1-ZvO">
|
||||
<rect key="frame" x="26" y="23" width="202" height="21"/>
|
||||
<rect key="frame" x="26" y="23" width="202" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="16"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -27,7 +28,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" id="RXT-bl-LZn" userLabel="Seperator view">
|
||||
<rect key="frame" x="9" y="47" width="300" height="1"/>
|
||||
<rect key="frame" x="9" y="48" width="300" height="1"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
|
@ -39,4 +40,9 @@
|
|||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5056" systemVersion="13C1021" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ContactDetailViewController">
|
||||
|
@ -20,7 +21,6 @@
|
|||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="none" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="jNG-R5-r0m">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="519"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-1" id="vyd-cy-GMS"/>
|
||||
|
@ -34,10 +34,8 @@
|
|||
<constraint firstItem="jNG-R5-r0m" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="rGH-rn-ki2"/>
|
||||
<constraint firstAttribute="bottom" secondItem="jNG-R5-r0m" secondAttribute="bottom" id="rJn-Dd-NeH"/>
|
||||
</constraints>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
|
||||
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
|
||||
<simulatedTabBarMetrics key="simulatedBottomBarMetrics" translucent="NO"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" id="rbM-xj-rv4" userLabel="Contact Detail Header View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
|
||||
|
@ -45,24 +43,28 @@
|
|||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Moxie Marlinspike" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="201" translatesAutoresizingMaskIntoConstraints="NO" id="5qW-wL-wnI">
|
||||
<rect key="frame" x="80" y="22" width="201" height="55"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Medium" family="Helvetica Neue" pointSize="18"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="contact_default_feed.png" translatesAutoresizingMaskIntoConstraints="NO" id="zfe-la-xIb">
|
||||
<rect key="frame" x="17" y="22" width="55" height="55"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZNu-c1-4Uj" userLabel="Seperator view">
|
||||
<rect key="frame" x="0.0" y="98" width="320" height="1"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="contact_default_feed.png" width="242" height="242"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|