mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Notifications enhancements.
- Tap to reply to a message. - Badges application with the number of unread messages. - Pick up a phone call from lock screen, or decline it. - Settings for notification sounds while app in foreground and text displayed on local notifications.
This commit is contained in:
parent
80b1f2cbcb
commit
13448bdb2d
40 changed files with 947 additions and 204 deletions
|
@ -340,6 +340,8 @@
|
||||||
B640C4771A477B0F005C7C8A /* TSAttachementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B640C4761A477B0F005C7C8A /* TSAttachementsTest.m */; };
|
B640C4771A477B0F005C7C8A /* TSAttachementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B640C4761A477B0F005C7C8A /* TSAttachementsTest.m */; };
|
||||||
B65031CF1A7862AA002EBBBD /* SignedPreKeyDeletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B65031CE1A7862AA002EBBBD /* SignedPreKeyDeletionTests.m */; };
|
B65031CF1A7862AA002EBBBD /* SignedPreKeyDeletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B65031CE1A7862AA002EBBBD /* SignedPreKeyDeletionTests.m */; };
|
||||||
B65EDA1219E1BE6400AAA7CB /* RPAPICall.m in Sources */ = {isa = PBXBuildFile; fileRef = B65EDA1119E1BE6400AAA7CB /* RPAPICall.m */; };
|
B65EDA1219E1BE6400AAA7CB /* RPAPICall.m in Sources */ = {isa = PBXBuildFile; fileRef = B65EDA1119E1BE6400AAA7CB /* RPAPICall.m */; };
|
||||||
|
B66B9F721AEA6D1100E2E609 /* NotificationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B66B9F711AEA6D1100E2E609 /* NotificationSettingsViewController.m */; };
|
||||||
|
B66B9F7D1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B66B9F7C1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m */; };
|
||||||
B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B66DBF4919D5BBC8006EA940 /* Images.xcassets */; };
|
B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B66DBF4919D5BBC8006EA940 /* Images.xcassets */; };
|
||||||
B671B2461A93B238002BBD9D /* GroupContactsResult.m in Sources */ = {isa = PBXBuildFile; fileRef = B671B2451A93B238002BBD9D /* GroupContactsResult.m */; };
|
B671B2461A93B238002BBD9D /* GroupContactsResult.m in Sources */ = {isa = PBXBuildFile; fileRef = B671B2451A93B238002BBD9D /* GroupContactsResult.m */; };
|
||||||
B67ADDC41989FF8700E1A773 /* RPServerRequestsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B67ADDC31989FF8700E1A773 /* RPServerRequestsManager.m */; };
|
B67ADDC41989FF8700E1A773 /* RPServerRequestsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B67ADDC31989FF8700E1A773 /* RPServerRequestsManager.m */; };
|
||||||
|
@ -405,6 +407,8 @@
|
||||||
B6F509971AA53F760068F56A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; };
|
B6F509971AA53F760068F56A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; };
|
||||||
B6FAAAE81A41BC6C007FEC1D /* TSAttachmentPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FAAAE71A41BC6C007FEC1D /* TSAttachmentPointer.m */; };
|
B6FAAAE81A41BC6C007FEC1D /* TSAttachmentPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FAAAE71A41BC6C007FEC1D /* TSAttachmentPointer.m */; };
|
||||||
B6FAAAEE1A41C918007FEC1D /* TSAttachmentStream.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FAAAED1A41C918007FEC1D /* TSAttachmentStream.m */; };
|
B6FAAAEE1A41C918007FEC1D /* TSAttachmentStream.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FAAAED1A41C918007FEC1D /* TSAttachmentStream.m */; };
|
||||||
|
B6FE7EB71ADD62FA00A6D22F /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */; };
|
||||||
|
B6FE7EBA1ADD63AE00A6D22F /* NSData+ows_StripToken.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FE7EB91ADD63AE00A6D22F /* NSData+ows_StripToken.m */; };
|
||||||
B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
|
B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
|
||||||
B90418E7183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
|
B90418E7183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
|
||||||
B96A3100187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = B96A30FE187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf */; };
|
B96A3100187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = B96A30FE187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf */; };
|
||||||
|
@ -946,6 +950,10 @@
|
||||||
B65EDA1019E1BE6400AAA7CB /* RPAPICall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RPAPICall.h; sourceTree = "<group>"; };
|
B65EDA1019E1BE6400AAA7CB /* RPAPICall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RPAPICall.h; sourceTree = "<group>"; };
|
||||||
B65EDA1119E1BE6400AAA7CB /* RPAPICall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RPAPICall.m; sourceTree = "<group>"; };
|
B65EDA1119E1BE6400AAA7CB /* RPAPICall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RPAPICall.m; sourceTree = "<group>"; };
|
||||||
B661C211198EE2EA00548CA1 /* iOSVersions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iOSVersions.h; path = src/environment/iOSVersions.h; sourceTree = "<group>"; };
|
B661C211198EE2EA00548CA1 /* iOSVersions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iOSVersions.h; path = src/environment/iOSVersions.h; sourceTree = "<group>"; };
|
||||||
|
B66B9F701AEA6D1100E2E609 /* NotificationSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsViewController.h; sourceTree = "<group>"; };
|
||||||
|
B66B9F711AEA6D1100E2E609 /* NotificationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsViewController.m; sourceTree = "<group>"; };
|
||||||
|
B66B9F7B1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsOptionsViewController.h; sourceTree = "<group>"; };
|
||||||
|
B66B9F7C1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsOptionsViewController.m; sourceTree = "<group>"; };
|
||||||
B66DBF4919D5BBC8006EA940 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
B66DBF4919D5BBC8006EA940 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||||
B671B2441A93B238002BBD9D /* GroupContactsResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupContactsResult.h; sourceTree = "<group>"; };
|
B671B2441A93B238002BBD9D /* GroupContactsResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupContactsResult.h; sourceTree = "<group>"; };
|
||||||
B671B2451A93B238002BBD9D /* GroupContactsResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupContactsResult.m; sourceTree = "<group>"; };
|
B671B2451A93B238002BBD9D /* GroupContactsResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupContactsResult.m; sourceTree = "<group>"; };
|
||||||
|
@ -1088,6 +1096,9 @@
|
||||||
B6FAAAE71A41BC6C007FEC1D /* TSAttachmentPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSAttachmentPointer.m; path = Attachements/TSAttachmentPointer.m; sourceTree = "<group>"; };
|
B6FAAAE71A41BC6C007FEC1D /* TSAttachmentPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSAttachmentPointer.m; path = Attachements/TSAttachmentPointer.m; sourceTree = "<group>"; };
|
||||||
B6FAAAEC1A41C918007FEC1D /* TSAttachmentStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSAttachmentStream.h; path = Attachements/TSAttachmentStream.h; sourceTree = "<group>"; };
|
B6FAAAEC1A41C918007FEC1D /* TSAttachmentStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSAttachmentStream.h; path = Attachements/TSAttachmentStream.h; sourceTree = "<group>"; };
|
||||||
B6FAAAED1A41C918007FEC1D /* TSAttachmentStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSAttachmentStream.m; path = Attachements/TSAttachmentStream.m; sourceTree = "<group>"; };
|
B6FAAAED1A41C918007FEC1D /* TSAttachmentStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSAttachmentStream.m; path = Attachements/TSAttachmentStream.m; sourceTree = "<group>"; };
|
||||||
|
B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = System/Library/Frameworks/PushKit.framework; sourceTree = SDKROOT; };
|
||||||
|
B6FE7EB81ADD63AE00A6D22F /* NSData+ows_StripToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+ows_StripToken.h"; sourceTree = "<group>"; };
|
||||||
|
B6FE7EB91ADD63AE00A6D22F /* NSData+ows_StripToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+ows_StripToken.m"; sourceTree = "<group>"; };
|
||||||
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
|
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
|
||||||
B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = "<group>"; };
|
B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = "<group>"; };
|
||||||
B96A30FE187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "HelveticaNeueLTStd-Bd.otf"; sourceTree = "<group>"; };
|
B96A30FE187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "HelveticaNeueLTStd-Bd.otf"; sourceTree = "<group>"; };
|
||||||
|
@ -1227,6 +1238,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B6FE7EB71ADD62FA00A6D22F /* PushKit.framework in Frameworks */,
|
||||||
FC3BD9881A30A790005B96BB /* Social.framework in Frameworks */,
|
FC3BD9881A30A790005B96BB /* Social.framework in Frameworks */,
|
||||||
FCB11D8C1A129A76002F93FB /* CoreMedia.framework in Frameworks */,
|
FCB11D8C1A129A76002F93FB /* CoreMedia.framework in Frameworks */,
|
||||||
70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */,
|
70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */,
|
||||||
|
@ -1750,6 +1762,8 @@
|
||||||
76EB04C818170B33006006FC /* util */ = {
|
76EB04C818170B33006006FC /* util */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B6FE7EB81ADD63AE00A6D22F /* NSData+ows_StripToken.h */,
|
||||||
|
B6FE7EB91ADD63AE00A6D22F /* NSData+ows_StripToken.m */,
|
||||||
A59E6D701A79E5D100D98E2E /* MIMETypeUtil.h */,
|
A59E6D701A79E5D100D98E2E /* MIMETypeUtil.h */,
|
||||||
A59E6D711A79E5D100D98E2E /* MIMETypeUtil.m */,
|
A59E6D711A79E5D100D98E2E /* MIMETypeUtil.m */,
|
||||||
FCFA64B11A24F29E0007FB87 /* UI Categories */,
|
FCFA64B11A24F29E0007FB87 /* UI Categories */,
|
||||||
|
@ -2449,6 +2463,7 @@
|
||||||
D221A08C169C9E5E00537ABF /* Frameworks */ = {
|
D221A08C169C9E5E00537ABF /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */,
|
||||||
FC3BD9871A30A790005B96BB /* Social.framework */,
|
FC3BD9871A30A790005B96BB /* Social.framework */,
|
||||||
B60EDE031A05A01700D73516 /* AudioToolbox.framework */,
|
B60EDE031A05A01700D73516 /* AudioToolbox.framework */,
|
||||||
FCB11D8B1A129A76002F93FB /* CoreMedia.framework */,
|
FCB11D8B1A129A76002F93FB /* CoreMedia.framework */,
|
||||||
|
@ -2594,6 +2609,10 @@
|
||||||
FCD274E11A5AFD8000202277 /* PrivacySettingsTableViewController.m */,
|
FCD274E11A5AFD8000202277 /* PrivacySettingsTableViewController.m */,
|
||||||
FCD274E61A5AFDC900202277 /* AdvancedSettingsTableViewController.h */,
|
FCD274E61A5AFDC900202277 /* AdvancedSettingsTableViewController.h */,
|
||||||
FCD274E71A5AFDC900202277 /* AdvancedSettingsTableViewController.m */,
|
FCD274E71A5AFDC900202277 /* AdvancedSettingsTableViewController.m */,
|
||||||
|
B66B9F701AEA6D1100E2E609 /* NotificationSettingsViewController.h */,
|
||||||
|
B66B9F711AEA6D1100E2E609 /* NotificationSettingsViewController.m */,
|
||||||
|
B66B9F7B1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.h */,
|
||||||
|
B66B9F7C1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m */,
|
||||||
FCD274E91A5AFDDB00202277 /* AboutTableViewController.h */,
|
FCD274E91A5AFDDB00202277 /* AboutTableViewController.h */,
|
||||||
FCD274EA1A5AFDDB00202277 /* AboutTableViewController.m */,
|
FCD274EA1A5AFDDB00202277 /* AboutTableViewController.m */,
|
||||||
);
|
);
|
||||||
|
@ -2981,6 +3000,7 @@
|
||||||
B63AF5C71A1F757900D01AAD /* TSContactsIntersectionRequest.m in Sources */,
|
B63AF5C71A1F757900D01AAD /* TSContactsIntersectionRequest.m in Sources */,
|
||||||
B6B0968B1A1D25ED008BFAA6 /* TSStorageManager+SignedPreKeyStore.m in Sources */,
|
B6B0968B1A1D25ED008BFAA6 /* TSStorageManager+SignedPreKeyStore.m in Sources */,
|
||||||
76EB05AC18170B33006006FC /* SrtpSocket.m in Sources */,
|
76EB05AC18170B33006006FC /* SrtpSocket.m in Sources */,
|
||||||
|
B6FE7EBA1ADD63AE00A6D22F /* NSData+ows_StripToken.m in Sources */,
|
||||||
B6A5D05C1A7827ED0043D837 /* TSAvailablePreKeysCountRequest.m in Sources */,
|
B6A5D05C1A7827ED0043D837 /* TSAvailablePreKeysCountRequest.m in Sources */,
|
||||||
FCB11D931A12A4AA002F93FB /* FullImageViewController.m in Sources */,
|
FCB11D931A12A4AA002F93FB /* FullImageViewController.m in Sources */,
|
||||||
B6B096871A1D25ED008BFAA6 /* TSStorageManager+IdentityKeyStore.m in Sources */,
|
B6B096871A1D25ED008BFAA6 /* TSStorageManager+IdentityKeyStore.m in Sources */,
|
||||||
|
@ -3058,6 +3078,7 @@
|
||||||
FCAC963C19FEF9280046DFC5 /* SignalsViewController.m in Sources */,
|
FCAC963C19FEF9280046DFC5 /* SignalsViewController.m in Sources */,
|
||||||
76EB05DA18170B33006006FC /* LowLatencyConnector.m in Sources */,
|
76EB05DA18170B33006006FC /* LowLatencyConnector.m in Sources */,
|
||||||
76EB05EE18170B33006006FC /* CallTermination.m in Sources */,
|
76EB05EE18170B33006006FC /* CallTermination.m in Sources */,
|
||||||
|
B66B9F7D1AEAF40500E2E609 /* NotificationSettingsOptionsViewController.m in Sources */,
|
||||||
E1CD329618BCFF9900B1A496 /* SoundInstance.m in Sources */,
|
E1CD329618BCFF9900B1A496 /* SoundInstance.m in Sources */,
|
||||||
B6FAAAEE1A41C918007FEC1D /* TSAttachmentStream.m in Sources */,
|
B6FAAAEE1A41C918007FEC1D /* TSAttachmentStream.m in Sources */,
|
||||||
76EB05B418170B33006006FC /* HashChain.m in Sources */,
|
76EB05B418170B33006006FC /* HashChain.m in Sources */,
|
||||||
|
@ -3128,6 +3149,7 @@
|
||||||
B6FAAAE81A41BC6C007FEC1D /* TSAttachmentPointer.m in Sources */,
|
B6FAAAE81A41BC6C007FEC1D /* TSAttachmentPointer.m in Sources */,
|
||||||
B6B096881A1D25ED008BFAA6 /* TSStorageManager+keyFromIntLong.m in Sources */,
|
B6B096881A1D25ED008BFAA6 /* TSStorageManager+keyFromIntLong.m in Sources */,
|
||||||
B6B50AAB1A4192C500F8F607 /* TSMessagesManager+attachments.m in Sources */,
|
B6B50AAB1A4192C500F8F607 /* TSMessagesManager+attachments.m in Sources */,
|
||||||
|
B66B9F721AEA6D1100E2E609 /* NotificationSettingsViewController.m in Sources */,
|
||||||
76EB059018170B33006006FC /* IgnoredPacketFailure.m in Sources */,
|
76EB059018170B33006006FC /* IgnoredPacketFailure.m in Sources */,
|
||||||
B60FB9B01A4711D4006A5A66 /* TSAttachmentEncryptionResult.m in Sources */,
|
B60FB9B01A4711D4006A5A66 /* TSAttachmentEncryptionResult.m in Sources */,
|
||||||
76EB05D418170B33006006FC /* ZrtpManager.m in Sources */,
|
76EB05D418170B33006006FC /* ZrtpManager.m in Sources */,
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.0.3</string>
|
<string>2.1</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2.0.20</string>
|
<string>2.0.21</string>
|
||||||
<key>LOGS_EMAIL</key>
|
<key>LOGS_EMAIL</key>
|
||||||
<string>support@whispersystems.org</string>
|
<string>support@whispersystems.org</string>
|
||||||
<key>LOGS_URL</key>
|
<key>LOGS_URL</key>
|
||||||
|
|
|
@ -5,15 +5,15 @@
|
||||||
#import "DebugLogger.h"
|
#import "DebugLogger.h"
|
||||||
#import "DiscardingLog.h"
|
#import "DiscardingLog.h"
|
||||||
#import "Environment.h"
|
#import "Environment.h"
|
||||||
#import "InCallViewController.h"
|
#import "PhoneNumberDirectoryFilterManager.h"
|
||||||
#import "PreferencesUtil.h"
|
#import "PreferencesUtil.h"
|
||||||
#import "NotificationTracker.h"
|
|
||||||
#import "PushManager.h"
|
#import "PushManager.h"
|
||||||
#import "PriorityQueue.h"
|
#import "PriorityQueue.h"
|
||||||
#import "Release.h"
|
#import "Release.h"
|
||||||
#import "SignalsViewController.h"
|
#import "SignalsViewController.h"
|
||||||
#import "TSAccountManager.h"
|
#import "TSAccountManager.h"
|
||||||
#import "TSPreKeyManager.h"
|
#import "TSPreKeyManager.h"
|
||||||
|
#import "TSMessagesManager.h"
|
||||||
#import "TSSocketManager.h"
|
#import "TSSocketManager.h"
|
||||||
#import "TSStorageManager.h"
|
#import "TSStorageManager.h"
|
||||||
#import "Util.h"
|
#import "Util.h"
|
||||||
|
@ -29,9 +29,6 @@
|
||||||
@interface AppDelegate ()
|
@interface AppDelegate ()
|
||||||
|
|
||||||
@property (nonatomic, retain) UIWindow *blankWindow;
|
@property (nonatomic, retain) UIWindow *blankWindow;
|
||||||
@property (nonatomic, strong) NotificationTracker *notificationTracker;
|
|
||||||
|
|
||||||
@property (nonatomic) TOCFutureSource *callPickUpFuture;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -68,12 +65,12 @@
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
[self setupAppearance];
|
[self setupAppearance];
|
||||||
|
|
||||||
|
[[PushManager sharedManager] registerPushKitNotificationFuture];
|
||||||
|
|
||||||
if (getenv("runningTests_dontStartApp")) {
|
if (getenv("runningTests_dontStartApp")) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.notificationTracker = [NotificationTracker notificationTracker];
|
|
||||||
|
|
||||||
CategorizingLogger* logger = [CategorizingLogger categorizingLogger];
|
CategorizingLogger* logger = [CategorizingLogger categorizingLogger];
|
||||||
[logger addLoggingCallback:^(NSString *category, id details, NSUInteger index) {}];
|
[logger addLoggingCallback:^(NSString *category, id details, NSUInteger index) {}];
|
||||||
[Environment setCurrent:[Release releaseEnvironmentWithLogging:logger]];
|
[Environment setCurrent:[Release releaseEnvironmentWithLogging:logger]];
|
||||||
|
@ -119,7 +116,9 @@
|
||||||
[self prepareScreenshotProtection];
|
[self prepareScreenshotProtection];
|
||||||
|
|
||||||
if ([TSAccountManager isRegistered]) {
|
if ([TSAccountManager isRegistered]) {
|
||||||
[TSSocketManager becomeActive];
|
if ([self applicationIsActive]) {
|
||||||
|
[TSSocketManager becomeActiveFromForeground];
|
||||||
|
}
|
||||||
[[PushManager sharedManager] validateUserNotificationSettings];
|
[[PushManager sharedManager] validateUserNotificationSettings];
|
||||||
[self refreshContacts];
|
[self refreshContacts];
|
||||||
[TSPreKeyManager refreshPreKeys];
|
[TSPreKeyManager refreshPreKeys];
|
||||||
|
@ -172,85 +171,27 @@
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
|
|
||||||
if ([self isRedPhonePush:userInfo]) {
|
|
||||||
ResponderSessionDescriptor* call;
|
|
||||||
if (![self.notificationTracker shouldProcessNotification:userInfo]){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@try {
|
|
||||||
call = [ResponderSessionDescriptor responderSessionDescriptorFromEncryptedRemoteNotification:userInfo];
|
|
||||||
DDLogDebug(@"Received remote notification. Parsed session descriptor: %@.", call);
|
|
||||||
self.callPickUpFuture = [TOCFutureSource new];
|
|
||||||
} @catch (OperationFailed* ex) {
|
|
||||||
DDLogError(@"Error parsing remote notification. Error: %@.", ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!call) {
|
|
||||||
DDLogError(@"Decryption of session descriptor failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Environment.phoneManager incomingCallWithSession:call];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
|
||||||
|
|
||||||
if ([self isRedPhonePush:userInfo]) {
|
|
||||||
[self application:application didReceiveRemoteNotification:userInfo];
|
|
||||||
} else {
|
|
||||||
[TSSocketManager becomeActive];
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC),
|
|
||||||
dispatch_get_main_queue(), ^{
|
|
||||||
completionHandler(UIBackgroundFetchResultNewData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isRedPhonePush:(NSDictionary*)pushDict {
|
|
||||||
NSDictionary *aps = [pushDict objectForKey:@"aps"];
|
|
||||||
NSString *category = [aps objectForKey:@"category"];
|
|
||||||
|
|
||||||
if ([category isEqualToString:Signal_Call_Category]) {
|
|
||||||
return YES;
|
|
||||||
} else{
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)applicationDidBecomeActive:(UIApplication *)application {
|
-(void)applicationDidBecomeActive:(UIApplication *)application {
|
||||||
if ([TSAccountManager isRegistered]) {
|
if ([TSAccountManager isRegistered] && [self applicationIsActive]) {
|
||||||
[TSSocketManager becomeActive];
|
// We're double checking that the app is active, to be sure since we can't verify in production env due to code signing.
|
||||||
|
[TSSocketManager becomeActiveFromForeground];
|
||||||
}
|
}
|
||||||
// Hacky way to clear notification center after processed push
|
|
||||||
[UIApplication.sharedApplication setApplicationIconBadgeNumber:1];
|
|
||||||
[UIApplication.sharedApplication setApplicationIconBadgeNumber:0];
|
|
||||||
|
|
||||||
[self removeScreenProtection];
|
[self removeScreenProtection];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||||
[self protectScreen];
|
[self protectScreen];
|
||||||
|
|
||||||
|
if ([TSAccountManager isRegistered]) {
|
||||||
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
|
||||||
|
[self updateBadge];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler{
|
- (void)updateBadge {
|
||||||
|
if ([TSAccountManager isRegistered]) {
|
||||||
[self application:application didReceiveRemoteNotification:userInfo];
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:(NSInteger)[[TSMessagesManager sharedManager] unreadMessagesCount]];
|
||||||
if ([identifier isEqualToString:Signal_Call_Accept_Identifier]) {
|
|
||||||
[self.callPickUpFuture trySetResult:@YES];
|
|
||||||
completionHandler();
|
|
||||||
} else if ([identifier isEqualToString:Signal_Call_Decline_Identifier]){
|
|
||||||
[self.callPickUpFuture trySetResult:@NO];
|
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC),
|
|
||||||
dispatch_get_main_queue(), ^{
|
|
||||||
completionHandler();
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
completionHandler();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,4 +270,31 @@
|
||||||
[manager forceUpdate];
|
[manager forceUpdate];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark Push Notifications Delegate Methods
|
||||||
|
|
||||||
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
|
||||||
|
[[PushManager sharedManager] application:application didReceiveRemoteNotification:userInfo];
|
||||||
|
}
|
||||||
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
||||||
|
[[PushManager sharedManager] application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
|
||||||
|
[[PushManager sharedManager] application:application didReceiveLocalNotification:notification];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
|
||||||
|
[[PushManager sharedManager] application:application handleActionWithIdentifier:identifier forLocalNotification:notification completionHandler:completionHandler];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)applicationIsActive {
|
||||||
|
UIApplication *app = [UIApplication sharedApplication];
|
||||||
|
|
||||||
|
if (app.applicationState == UIApplicationStateActive) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="tuk-0x-yCb">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="tuk-0x-yCb">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||||
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
|
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
|
||||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||||
|
@ -4160,6 +4160,69 @@ A0 09 9A FF A8 8A 09 99</string>
|
||||||
</variation>
|
</variation>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="jp5-vZ-AhJ">
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jp5-vZ-AhJ" id="sji-CJ-bhq">
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Notifications" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BaC-fn-VoA">
|
||||||
|
<rect key="frame" x="0.0" y="-21" width="42" height="21"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="307" id="HeG-Yg-7m7">
|
||||||
|
<variation key="heightClass=regular-widthClass=compact" constant="200"/>
|
||||||
|
</constraint>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
<variation key="default">
|
||||||
|
<mask key="constraints">
|
||||||
|
<exclude reference="HeG-Yg-7m7"/>
|
||||||
|
</mask>
|
||||||
|
</variation>
|
||||||
|
<variation key="heightClass=regular-widthClass=compact">
|
||||||
|
<mask key="constraints">
|
||||||
|
<include reference="HeG-Yg-7m7"/>
|
||||||
|
</mask>
|
||||||
|
</variation>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="BaC-fn-VoA" firstAttribute="leading" secondItem="sji-CJ-bhq" secondAttribute="leadingMargin" id="Tae-ZO-Fxf">
|
||||||
|
<variation key="heightClass=regular-widthClass=compact" constant="7"/>
|
||||||
|
</constraint>
|
||||||
|
<constraint firstAttribute="trailingMargin" secondItem="BaC-fn-VoA" secondAttribute="trailing" constant="70" id="U1d-NR-s31"/>
|
||||||
|
<constraint firstAttribute="centerY" secondItem="BaC-fn-VoA" secondAttribute="centerY" constant="0.5" id="gMd-UT-AWs">
|
||||||
|
<variation key="heightClass=regular-widthClass=compact" constant="0.0"/>
|
||||||
|
</constraint>
|
||||||
|
<constraint firstItem="BaC-fn-VoA" firstAttribute="top" secondItem="sji-CJ-bhq" secondAttribute="topMargin" constant="3" id="zfO-kb-UBa">
|
||||||
|
<variation key="heightClass=regular-widthClass=compact" constant="11"/>
|
||||||
|
</constraint>
|
||||||
|
</constraints>
|
||||||
|
<variation key="default">
|
||||||
|
<mask key="subviews">
|
||||||
|
<exclude reference="BaC-fn-VoA"/>
|
||||||
|
</mask>
|
||||||
|
<mask key="constraints">
|
||||||
|
<exclude reference="gMd-UT-AWs"/>
|
||||||
|
<exclude reference="U1d-NR-s31"/>
|
||||||
|
<exclude reference="zfO-kb-UBa"/>
|
||||||
|
<exclude reference="Tae-ZO-Fxf"/>
|
||||||
|
</mask>
|
||||||
|
</variation>
|
||||||
|
<variation key="heightClass=regular-widthClass=compact">
|
||||||
|
<mask key="subviews">
|
||||||
|
<include reference="BaC-fn-VoA"/>
|
||||||
|
</mask>
|
||||||
|
<mask key="constraints">
|
||||||
|
<include reference="gMd-UT-AWs"/>
|
||||||
|
<exclude reference="U1d-NR-s31"/>
|
||||||
|
<exclude reference="zfO-kb-UBa"/>
|
||||||
|
<include reference="Tae-ZO-Fxf"/>
|
||||||
|
</mask>
|
||||||
|
</variation>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
</tableViewCell>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="Xx7-pz-aLN">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="Xx7-pz-aLN">
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Xx7-pz-aLN" id="pMA-vR-8Ae">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Xx7-pz-aLN" id="pMA-vR-8Ae">
|
||||||
|
@ -4404,6 +4467,7 @@ A0 09 9A FF A8 8A 09 99</string>
|
||||||
<outlet property="registeredNumber" destination="ipE-BI-sLL" id="uQB-V6-ooY"/>
|
<outlet property="registeredNumber" destination="ipE-BI-sLL" id="uQB-V6-ooY"/>
|
||||||
<outlet property="settingsAboutTitle" destination="6FV-LR-9Hv" id="fOe-Zy-6i7"/>
|
<outlet property="settingsAboutTitle" destination="6FV-LR-9Hv" id="fOe-Zy-6i7"/>
|
||||||
<outlet property="settingsAdvancedTitle" destination="qix-5C-dh1" id="vhZ-Zv-TIj"/>
|
<outlet property="settingsAdvancedTitle" destination="qix-5C-dh1" id="vhZ-Zv-TIj"/>
|
||||||
|
<outlet property="settingsNotifications" destination="BaC-fn-VoA" id="za4-od-AIj"/>
|
||||||
<outlet property="settingsPrivacyTitle" destination="TAs-sK-kbi" id="Ea0-do-XJB"/>
|
<outlet property="settingsPrivacyTitle" destination="TAs-sK-kbi" id="Ea0-do-XJB"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#import "AppAudioManager.h"
|
#import "AppAudioManager.h"
|
||||||
|
|
||||||
|
#import <AudioToolbox/AudioServices.h>
|
||||||
#import "AudioRouter.h"
|
#import "AudioRouter.h"
|
||||||
#import "SoundBoard.h"
|
#import "SoundBoard.h"
|
||||||
#import "SoundPlayer.h"
|
#import "SoundPlayer.h"
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
- (void)addCall:(CallState*)call {
|
- (void)addCall:(CallState*)call {
|
||||||
require(call != nil);
|
require(call != nil);
|
||||||
|
|
||||||
[call.futureCallLocallyAcceptedOrRejected finallyDo:^(TOCFuture* interactionCompletion) {
|
[call.futureTermination finallyDo:^(TOCFuture* interactionCompletion) {
|
||||||
bool isOutgoingCall = call.initiatedLocally;
|
bool isOutgoingCall = call.initiatedLocally;
|
||||||
bool isMissedCall = interactionCompletion.hasFailed;
|
bool isMissedCall = interactionCompletion.hasFailed;
|
||||||
Contact* contact = [self tryGetContactForCall:call];
|
Contact* contact = [self tryGetContactForCall:call];
|
||||||
|
|
|
@ -85,7 +85,7 @@ andCurrentRegionCodeForPhoneNumbers:(NSString*)currentRegionCodeForPhoneNumbers
|
||||||
- (void)setSignalsViewController:(SignalsViewController *)signalsViewController;
|
- (void)setSignalsViewController:(SignalsViewController *)signalsViewController;
|
||||||
- (void)setSignUpFlowNavigationController:(UINavigationController *)signUpFlowNavigationController;
|
- (void)setSignUpFlowNavigationController:(UINavigationController *)signUpFlowNavigationController;
|
||||||
|
|
||||||
+ (void)messageIdentifier:(NSString*)identifier;
|
+ (void)messageThreadId:(NSString*)threadId;
|
||||||
+ (void)messageGroupModel:(TSGroupModel*)model;
|
+ (void)messageIdentifier:(NSString*)identifier withCompose:(BOOL)compose;
|
||||||
|
+ (void)messageGroupModel:(TSGroupModel*)model withCompose:(BOOL)compose;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#import "PhoneNumberDirectoryFilterManager.h"
|
#import "PhoneNumberDirectoryFilterManager.h"
|
||||||
#import "SignalKeyingStorage.h"
|
#import "SignalKeyingStorage.h"
|
||||||
#import "SignalsViewController.h"
|
#import "SignalsViewController.h"
|
||||||
|
#import "TSContactThread.h"
|
||||||
|
#import "TSGroupThread.h"
|
||||||
#import "TSStorageManager.h"
|
#import "TSStorageManager.h"
|
||||||
|
|
||||||
static NSString* const kCallSegue = @"2.0_6.0_Call_Segue";
|
static NSString* const kCallSegue = @"2.0_6.0_Call_Segue";
|
||||||
|
@ -184,7 +186,22 @@ phoneDirectoryManager;
|
||||||
_signUpFlowNavigationController = navigationController;
|
_signUpFlowNavigationController = navigationController;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)messageIdentifier:(NSString*)identifier{
|
+ (void)messageThreadId:(NSString*)threadId {
|
||||||
|
TSThread *thread = [TSThread fetchObjectWithUniqueID:threadId];
|
||||||
|
|
||||||
|
if (!thread) {
|
||||||
|
DDLogWarn(@"We get UILocalNotifications with unknown threadId: %@", threadId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([thread isGroupThread]) {
|
||||||
|
[self messageGroup:(TSGroupThread*)thread];
|
||||||
|
} else {
|
||||||
|
[self messageIdentifier:((TSContactThread*)thread).contactIdentifier withCompose:YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)messageIdentifier:(NSString*)identifier withCompose:(BOOL)compose {
|
||||||
Environment *env = [self getCurrent];
|
Environment *env = [self getCurrent];
|
||||||
SignalsViewController *vc = env.signalsViewController;
|
SignalsViewController *vc = env.signalsViewController;
|
||||||
|
|
||||||
|
@ -194,10 +211,23 @@ phoneDirectoryManager;
|
||||||
|
|
||||||
[vc.navigationController popToRootViewControllerAnimated:YES];
|
[vc.navigationController popToRootViewControllerAnimated:YES];
|
||||||
vc.contactIdentifierFromCompose = identifier;
|
vc.contactIdentifierFromCompose = identifier;
|
||||||
|
vc.composeMessage = compose;
|
||||||
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)messageGroupModel:(TSGroupModel*)model {
|
+ (void)messageGroup:(TSGroupThread*)groupThread {
|
||||||
|
Environment *env = [self getCurrent];
|
||||||
|
SignalsViewController *vc = env.signalsViewController;
|
||||||
|
|
||||||
|
if (vc.presentedViewController) {
|
||||||
|
[vc.presentedViewController dismissViewControllerAnimated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
[vc.navigationController popToRootViewControllerAnimated:YES];
|
||||||
|
[vc performSegueWithIdentifier:@"showSegue" sender:groupThread];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)messageGroupModel:(TSGroupModel*)model withCompose:(BOOL)compose {
|
||||||
Environment *env = [self getCurrent];
|
Environment *env = [self getCurrent];
|
||||||
SignalsViewController *vc = env.signalsViewController;
|
SignalsViewController *vc = env.signalsViewController;
|
||||||
|
|
||||||
|
@ -207,6 +237,7 @@ phoneDirectoryManager;
|
||||||
|
|
||||||
[vc.navigationController popToRootViewControllerAnimated:YES];
|
[vc.navigationController popToRootViewControllerAnimated:YES];
|
||||||
vc.groupFromCompose = model;
|
vc.groupFromCompose = model;
|
||||||
|
vc.composeMessage = compose;
|
||||||
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,10 @@ typedef NS_ENUM(NSUInteger, TSImageQuality) {
|
||||||
|
|
||||||
- (NotificationType)notificationPreviewType;
|
- (NotificationType)notificationPreviewType;
|
||||||
- (void)setNotificationPreviewType:(NotificationType)type;
|
- (void)setNotificationPreviewType:(NotificationType)type;
|
||||||
|
- (NSString*)nameForNotificationPreviewType:(NotificationType)notificationType;
|
||||||
|
|
||||||
|
- (BOOL)soundInForeground;
|
||||||
|
- (void)setSoundInForeground:(BOOL)enabled;
|
||||||
|
|
||||||
- (TSImageQuality)imageUploadQuality;
|
- (TSImageQuality)imageUploadQuality;
|
||||||
- (void)setImageUploadQuality:(TSImageQuality)quality;
|
- (void)setImageUploadQuality:(TSImageQuality)quality;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define HAS_SENT_A_MESSAGE_KEY @"User has sent a message"
|
#define HAS_SENT_A_MESSAGE_KEY @"User has sent a message"
|
||||||
#define HAS_ARCHIVED_A_MESSAGE_KEY @"User archived a message"
|
#define HAS_ARCHIVED_A_MESSAGE_KEY @"User archived a message"
|
||||||
#define kSignalVersionKey @"SignalUpdateVersionKey"
|
#define kSignalVersionKey @"SignalUpdateVersionKey"
|
||||||
|
#define PLAY_SOUND_IN_FOREGROUND_KEY @"NotificationSoundInForeground"
|
||||||
|
|
||||||
#define BloomFilterCacheName @"bloomfilter"
|
#define BloomFilterCacheName @"bloomfilter"
|
||||||
|
|
||||||
|
@ -141,17 +142,6 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
-(NotificationType)notificationPreviewType {
|
|
||||||
NSNumber *preference = [self tryGetValueForKey:NOTIFICATION_PREVIEW_TYPE_KEY];
|
|
||||||
|
|
||||||
if (preference) {
|
|
||||||
return [preference unsignedIntegerValue];
|
|
||||||
} else {
|
|
||||||
return NotificationNamePreview;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-(TSImageQuality)imageUploadQuality {
|
-(TSImageQuality)imageUploadQuality {
|
||||||
// always return average image quality
|
// always return average image quality
|
||||||
return TSImageQualityMedium;
|
return TSImageQualityMedium;
|
||||||
|
@ -161,11 +151,6 @@
|
||||||
[self setValueForKey:IMAGE_UPLOAD_QUALITY_KEY toValue:@(quality)];
|
[self setValueForKey:IMAGE_UPLOAD_QUALITY_KEY toValue:@(quality)];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)setNotificationPreviewType:(NotificationType)type
|
|
||||||
{
|
|
||||||
[self setValueForKey:NOTIFICATION_PREVIEW_TYPE_KEY toValue:@(type)];
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)setScreenSecurity:(BOOL)flag{
|
-(void)setScreenSecurity:(BOOL)flag{
|
||||||
[self setValueForKey:SCREEN_SECURITY_KEY toValue:@(flag)];
|
[self setValueForKey:SCREEN_SECURITY_KEY toValue:@(flag)];
|
||||||
}
|
}
|
||||||
|
@ -214,6 +199,51 @@
|
||||||
return currentVersion;
|
return currentVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark Notification Preferences
|
||||||
|
|
||||||
|
- (BOOL)soundInForeground {
|
||||||
|
NSNumber *preference = [self tryGetValueForKey:PLAY_SOUND_IN_FOREGROUND_KEY];
|
||||||
|
if (preference) {
|
||||||
|
return [preference boolValue];
|
||||||
|
} else{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setSoundInForeground:(BOOL)enabled {
|
||||||
|
[self setValueForKey:PLAY_SOUND_IN_FOREGROUND_KEY toValue:@(enabled)];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setNotificationPreviewType:(NotificationType)type
|
||||||
|
{
|
||||||
|
[self setValueForKey:NOTIFICATION_PREVIEW_TYPE_KEY toValue:@(type)];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NotificationType)notificationPreviewType {
|
||||||
|
NSNumber *preference = [self tryGetValueForKey:NOTIFICATION_PREVIEW_TYPE_KEY];
|
||||||
|
|
||||||
|
if (preference) {
|
||||||
|
return [preference unsignedIntegerValue];
|
||||||
|
} else {
|
||||||
|
return NotificationNamePreview;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*)nameForNotificationPreviewType:(NotificationType)notificationType {
|
||||||
|
switch (notificationType) {
|
||||||
|
case NotificationNamePreview:
|
||||||
|
return NSLocalizedString(@"NOTIFICATIONS_SENDER_AND_MESSAGE", nil);
|
||||||
|
case NotificationNameNoPreview:
|
||||||
|
return NSLocalizedString(@"NOTIFICATIONS_SENDER_ONLY", nil);
|
||||||
|
case NotificationNoNameNoPreview:
|
||||||
|
return NSLocalizedString(@"NOTIFICATIONS_NONE", nil);
|
||||||
|
default:
|
||||||
|
DDLogWarn(@"Undefined NotificationType in Settings");
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark Bloom filter
|
#pragma mark Bloom filter
|
||||||
|
|
||||||
- (NSData*)tryRetreiveBloomFilter {
|
- (NSData*)tryRetreiveBloomFilter {
|
||||||
|
|
|
@ -59,8 +59,8 @@
|
||||||
|
|
||||||
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:waitingController animated:YES completion:nil];
|
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:waitingController animated:YES completion:nil];
|
||||||
|
|
||||||
[PushManager.sharedManager registrationAndRedPhoneTokenRequestWithSuccess:^(NSData *pushToken, NSString *signupToken) {
|
[PushManager.sharedManager registrationAndRedPhoneTokenRequestWithSuccess:^(NSData *pushToken, NSData *voipToken, NSString *signupToken) {
|
||||||
[TSAccountManager registerWithRedPhoneToken:signupToken pushToken:pushToken success:^{
|
[TSAccountManager registerWithRedPhoneToken:signupToken pushToken:pushToken voipToken:voipToken success:^{
|
||||||
[UIApplication.sharedApplication setNetworkActivityIndicatorVisible:NO];
|
[UIApplication.sharedApplication setNetworkActivityIndicatorVisible:NO];
|
||||||
[self clearMigrationFlag];
|
[self clearMigrationFlag];
|
||||||
Environment *env = [Environment getCurrent];
|
Environment *env = [Environment getCurrent];
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#import <CollapsingFutures.h>
|
#import <CollapsingFutures.h>
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#define Signal_Thread_UserInfo_Key @"Signal_Thread_Id"
|
||||||
|
|
||||||
#define Signal_Call_Accept_Identifier @"Signal_Call_Accept"
|
#define Signal_Call_Accept_Identifier @"Signal_Call_Accept"
|
||||||
#define Signal_Call_Decline_Identifier @"Signal_Call_Decline"
|
#define Signal_Call_Decline_Identifier @"Signal_Call_Decline"
|
||||||
|
|
||||||
|
@ -19,6 +21,8 @@
|
||||||
#define Signal_Message_MarkAsRead_Identifier @"Signal_Message_MarkAsRead"
|
#define Signal_Message_MarkAsRead_Identifier @"Signal_Message_MarkAsRead"
|
||||||
|
|
||||||
typedef void(^failedPushRegistrationBlock)(NSError *error);
|
typedef void(^failedPushRegistrationBlock)(NSError *error);
|
||||||
|
typedef void (^pushTokensSuccessBlock)(NSData *pushToken, NSData *voipToken);
|
||||||
|
typedef void (^registrationTokensSuccessBlock)(NSData *pushToken, NSData *voipToken, NSString *signupToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Push Manager is responsible for registering the device for Signal push notifications.
|
* The Push Manager is responsible for registering the device for Signal push notifications.
|
||||||
|
@ -35,7 +39,7 @@ typedef void(^failedPushRegistrationBlock)(NSError *error);
|
||||||
* @param failure Failure completion block
|
* @param failure Failure completion block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
- (void)registrationAndRedPhoneTokenRequestWithSuccess:(void (^)(NSData* pushToken, NSString* signupToken))success failure:(failedPushRegistrationBlock)failure;
|
- (void)registrationAndRedPhoneTokenRequestWithSuccess:(registrationTokensSuccessBlock)success failure:(failedPushRegistrationBlock)failure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Push Notification Token of this device
|
* Returns the Push Notification Token of this device
|
||||||
|
@ -44,7 +48,7 @@ typedef void(^failedPushRegistrationBlock)(NSError *error);
|
||||||
* @param failure Failure block, executed when failed to get push token
|
* @param failure Failure block, executed when failed to get push token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
- (void)requestPushTokenWithSuccess:(void (^)(NSData* pushToken))success failure:(void(^)(NSError *))failure;
|
- (void)requestPushTokenWithSuccess:(pushTokensSuccessBlock)success failure:(void(^)(NSError *))failure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers for Users Notifications. By doing this on launch, we are sure that the correct categories of user notifications is registered.
|
* Registers for Users Notifications. By doing this on launch, we are sure that the correct categories of user notifications is registered.
|
||||||
|
@ -58,5 +62,15 @@ typedef void(^failedPushRegistrationBlock)(NSError *error);
|
||||||
|
|
||||||
@property TOCFutureSource *pushNotificationFutureSource;
|
@property TOCFutureSource *pushNotificationFutureSource;
|
||||||
@property TOCFutureSource *userNotificationFutureSource;
|
@property TOCFutureSource *userNotificationFutureSource;
|
||||||
|
@property TOCFutureSource *pushKitNotificationFutureSource;
|
||||||
|
|
||||||
|
-(TOCFuture*)registerPushKitNotificationFuture;
|
||||||
|
|
||||||
|
#pragma mark Push Notifications Delegate Methods
|
||||||
|
|
||||||
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
|
||||||
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;
|
||||||
|
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler;
|
||||||
|
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -5,19 +5,29 @@
|
||||||
// Created by Frederic Jacobs on 31/07/14.
|
// Created by Frederic Jacobs on 31/07/14.
|
||||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#import <PushKit/PushKit.h>
|
||||||
|
|
||||||
|
#import "ContactsManager.h"
|
||||||
|
#import "InCallViewController.h"
|
||||||
|
#import "NotificationTracker.h"
|
||||||
|
|
||||||
#import "PreferencesUtil.h"
|
#import "PreferencesUtil.h"
|
||||||
#import "PushManager.h"
|
#import "PushManager.h"
|
||||||
#import "Environment.h"
|
#import "Environment.h"
|
||||||
#import "RPServerRequestsManager.h"
|
#import "RPServerRequestsManager.h"
|
||||||
#import "TSAccountManager.h"
|
#import "TSAccountManager.h"
|
||||||
|
#import "TSSocketManager.h"
|
||||||
|
|
||||||
#define pushManagerDomain @"org.whispersystems.pushmanager"
|
#define pushManagerDomain @"org.whispersystems.pushmanager"
|
||||||
|
|
||||||
@interface PushManager ()
|
@interface PushManager () <PKPushRegistryDelegate>
|
||||||
|
|
||||||
@property TOCFutureSource *registerWithServerFutureSource;
|
@property TOCFutureSource *registerWithServerFutureSource;
|
||||||
@property UIAlertView *missingPermissionsAlertView;
|
@property UIAlertView *missingPermissionsAlertView;
|
||||||
|
@property (nonatomic, strong) NotificationTracker *notificationTracker;
|
||||||
|
|
||||||
|
@property (nonatomic) UIBackgroundTaskIdentifier callBackgroundTask;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation PushManager
|
@implementation PushManager
|
||||||
|
@ -36,6 +46,7 @@
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
|
self.notificationTracker = [NotificationTracker notificationTracker];
|
||||||
self.missingPermissionsAlertView =
|
self.missingPermissionsAlertView =
|
||||||
[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ACTION_REQUIRED_TITLE", @"")
|
[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ACTION_REQUIRED_TITLE", @"")
|
||||||
message:NSLocalizedString(@"PUSH_SETTINGS_MESSAGE", @"")
|
message:NSLocalizedString(@"PUSH_SETTINGS_MESSAGE", @"")
|
||||||
|
@ -46,6 +57,135 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark Manage Incoming Push
|
||||||
|
|
||||||
|
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
|
||||||
|
|
||||||
|
if ([self isRedPhonePush:userInfo]) {
|
||||||
|
ResponderSessionDescriptor* call;
|
||||||
|
if (![self.notificationTracker shouldProcessNotification:userInfo]){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@try {
|
||||||
|
call = [ResponderSessionDescriptor responderSessionDescriptorFromEncryptedRemoteNotification:userInfo];
|
||||||
|
DDLogDebug(@"Received remote notification. Parsed session descriptor: %@.", call);
|
||||||
|
} @catch (OperationFailed* ex) {
|
||||||
|
DDLogError(@"Error parsing remote notification. Error: %@.", ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!call) {
|
||||||
|
DDLogError(@"Decryption of session descriptor failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Environment.phoneManager incomingCallWithSession:call];
|
||||||
|
|
||||||
|
|
||||||
|
if (![self applicationIsActive]) {
|
||||||
|
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
||||||
|
|
||||||
|
NSString *callerId = call.initiatorNumber.toE164;
|
||||||
|
NSString *nameString = [[Environment getCurrent].contactsManager nameStringForPhoneIdentifier:callerId];
|
||||||
|
|
||||||
|
NSString *displayName = nameString?nameString:callerId;
|
||||||
|
|
||||||
|
notification.alertBody = [NSString stringWithFormat:@"Incoming call from %@", displayName];
|
||||||
|
notification.category = Signal_Call_Category;
|
||||||
|
notification.soundName = @"r.caf";
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
||||||
|
|
||||||
|
if (_callBackgroundTask == 0) {
|
||||||
|
_callBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||||
|
_callBackgroundTask = 0;
|
||||||
|
[Environment.phoneManager hangupOrDenyCall];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (![self applicationIsActive]) {
|
||||||
|
[TSSocketManager becomeActiveFromBackground];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code should in principle never be called. The only cases where it would be called are with the old-style "content-available:1" pushes if there is no "voip" token registered
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
||||||
|
if ([self isRedPhonePush:userInfo]) {
|
||||||
|
[self application:application didReceiveRemoteNotification:userInfo];
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC),
|
||||||
|
dispatch_get_main_queue(), ^{
|
||||||
|
completionHandler(UIBackgroundFetchResultNewData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
|
||||||
|
if ([notification.category isEqualToString:Signal_Message_Category]) {
|
||||||
|
NSString *threadId = [notification.userInfo objectForKey:Signal_Thread_UserInfo_Key];
|
||||||
|
[Environment messageThreadId:threadId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
|
||||||
|
|
||||||
|
if ([identifier isEqualToString:Signal_Call_Accept_Identifier]) {
|
||||||
|
[Environment.phoneManager answerCall];
|
||||||
|
|
||||||
|
completionHandler();
|
||||||
|
} else if ([identifier isEqualToString:Signal_Call_Decline_Identifier]){
|
||||||
|
[Environment.phoneManager hangupOrDenyCall];
|
||||||
|
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC),
|
||||||
|
dispatch_get_main_queue(), ^{
|
||||||
|
completionHandler();
|
||||||
|
});
|
||||||
|
} else{
|
||||||
|
NSString *threadId = [notification.userInfo objectForKey:Signal_Thread_UserInfo_Key];
|
||||||
|
[Environment messageThreadId:threadId];
|
||||||
|
|
||||||
|
completionHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isRedPhonePush:(NSDictionary*)pushDict {
|
||||||
|
NSDictionary *aps = [pushDict objectForKey:@"aps"];
|
||||||
|
NSString *category = [aps objectForKey:@"category"];
|
||||||
|
|
||||||
|
if ([category isEqualToString:Signal_Call_Category]) {
|
||||||
|
return YES;
|
||||||
|
} else{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark PushKit
|
||||||
|
|
||||||
|
-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
|
||||||
|
{
|
||||||
|
[[PushManager sharedManager].pushKitNotificationFutureSource trySetResult:credentials.token];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
|
||||||
|
{
|
||||||
|
[self application:[UIApplication sharedApplication] didReceiveRemoteNotification:payload.dictionaryPayload];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(TOCFuture*)registerPushKitNotificationFuture{
|
||||||
|
self.pushKitNotificationFutureSource = [TOCFutureSource new];
|
||||||
|
PKPushRegistry* voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
|
||||||
|
voipRegistry.delegate = self;
|
||||||
|
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
|
||||||
|
return self.pushKitNotificationFutureSource.future;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark Register device for Push Notification locally
|
#pragma mark Register device for Push Notification locally
|
||||||
|
|
||||||
- (TOCFuture *)registerPushNotificationFuture
|
- (TOCFuture *)registerPushNotificationFuture
|
||||||
|
@ -56,7 +196,7 @@
|
||||||
return self.pushNotificationFutureSource.future;
|
return self.pushNotificationFutureSource.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)requestPushTokenWithSuccess:(void (^)(NSData *pushToken))success failure:(failedPushRegistrationBlock)failure
|
- (void)requestPushTokenWithSuccess:(pushTokensSuccessBlock)success failure:(failedPushRegistrationBlock)failure
|
||||||
{
|
{
|
||||||
TOCFuture *requestPushTokenFuture = [self registerPushNotificationFuture];
|
TOCFuture *requestPushTokenFuture = [self registerPushNotificationFuture];
|
||||||
|
|
||||||
|
@ -67,7 +207,12 @@
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[requestPushTokenFuture thenDo:^(NSData *pushToken) {
|
[requestPushTokenFuture thenDo:^(NSData *pushToken) {
|
||||||
TOCFuture *registerPushTokenFuture = [self registerForPushFutureWithToken:pushToken];
|
TOCFuture *voipPushTokenFuture = [self registerPushKitNotificationFuture];
|
||||||
|
|
||||||
|
[voipPushTokenFuture finallyDo:^(TOCFuture *completed) {
|
||||||
|
NSData *voipPushToken = completed.hasResult?completed.forceGetResult:nil;
|
||||||
|
|
||||||
|
TOCFuture *registerPushTokenFuture = [self registerForPushFutureWithToken:pushToken voipToken:voipPushToken];
|
||||||
|
|
||||||
[registerPushTokenFuture catchDo:^(id failureObj) {
|
[registerPushTokenFuture catchDo:^(id failureObj) {
|
||||||
failure(failureObj);
|
failure(failureObj);
|
||||||
|
@ -77,24 +222,28 @@
|
||||||
TOCFuture *userRegistration = [self registerForUserNotificationsFuture];
|
TOCFuture *userRegistration = [self registerForUserNotificationsFuture];
|
||||||
|
|
||||||
[userRegistration thenDo:^(UIUserNotificationSettings *userNotificationSettings) {
|
[userRegistration thenDo:^(UIUserNotificationSettings *userNotificationSettings) {
|
||||||
success(pushToken);
|
success(pushToken, voipPushToken);
|
||||||
|
}];
|
||||||
}];
|
}];
|
||||||
}];
|
}];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)registrationAndRedPhoneTokenRequestWithSuccess:(void (^)(NSData *pushToken, NSString *signupToken))success
|
- (void)registrationAndRedPhoneTokenRequestWithSuccess:(registrationTokensSuccessBlock)success
|
||||||
failure:(failedPushRegistrationBlock)failure
|
failure:(failedPushRegistrationBlock)failure
|
||||||
{
|
{
|
||||||
if (!self.wantRemoteNotifications) {
|
if (!self.wantRemoteNotifications) {
|
||||||
[self registerTokenWithRedPhoneServer:[@"Fake PushToken" dataUsingEncoding:NSUTF8StringEncoding]
|
NSData *fakeToken = [@"Fake PushToken" dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
[self registerTokenWithRedPhoneServer:fakeToken
|
||||||
|
voipToken:fakeToken
|
||||||
withSuccess:success
|
withSuccess:success
|
||||||
failure:failure];
|
failure:failure];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self requestPushTokenWithSuccess:^(NSData *pushToken) {
|
[self requestPushTokenWithSuccess:^(NSData *pushToken, NSData *voipToken) {
|
||||||
[self registerTokenWithRedPhoneServer:pushToken withSuccess:success failure:failure];
|
[self registerTokenWithRedPhoneServer:pushToken voipToken:voipToken withSuccess:success failure:failure];
|
||||||
} failure:^(NSError *error) {
|
} failure:^(NSError *error) {
|
||||||
[self.missingPermissionsAlertView show];
|
[self.missingPermissionsAlertView show];
|
||||||
failure([NSError errorWithDomain:pushManagerDomain code:400 userInfo:@{}]);
|
failure([NSError errorWithDomain:pushManagerDomain code:400 userInfo:@{}]);
|
||||||
|
@ -102,7 +251,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)registerTokenWithRedPhoneServer:(NSData*)pushToken
|
- (void)registerTokenWithRedPhoneServer:(NSData*)pushToken
|
||||||
withSuccess:(void (^)(NSData *pushToken, NSString *signupToken))success
|
voipToken:(NSData*)voipToken
|
||||||
|
withSuccess:(registrationTokensSuccessBlock)success
|
||||||
failure:(failedPushRegistrationBlock)failure
|
failure:(failedPushRegistrationBlock)failure
|
||||||
{
|
{
|
||||||
[RPServerRequestsManager.sharedInstance performRequest:[RPAPICall requestTextSecureVerificationCode]
|
[RPServerRequestsManager.sharedInstance performRequest:[RPAPICall requestTextSecureVerificationCode]
|
||||||
|
@ -117,7 +267,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
success(pushToken, tsToken);
|
success(pushToken, voipToken, tsToken);
|
||||||
}
|
}
|
||||||
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||||
failure(error);
|
failure(error);
|
||||||
|
@ -127,13 +277,61 @@
|
||||||
- (TOCFuture *)registerForUserNotificationsFuture
|
- (TOCFuture *)registerForUserNotificationsFuture
|
||||||
{
|
{
|
||||||
self.userNotificationFutureSource = [TOCFutureSource new];
|
self.userNotificationFutureSource = [TOCFutureSource new];
|
||||||
|
|
||||||
UIUserNotificationSettings *settings =
|
UIUserNotificationSettings *settings =
|
||||||
[UIUserNotificationSettings settingsForTypes:(UIUserNotificationType)[self allNotificationTypes]
|
[UIUserNotificationSettings settingsForTypes:(UIUserNotificationType)[self allNotificationTypes]
|
||||||
categories:nil];
|
categories:[NSSet setWithObjects:[self userNotificationsCallCategory], [self userNotificationsMessageCategory], nil]];
|
||||||
|
|
||||||
[UIApplication.sharedApplication registerUserNotificationSettings:settings];
|
[UIApplication.sharedApplication registerUserNotificationSettings:settings];
|
||||||
return self.userNotificationFutureSource.future;
|
return self.userNotificationFutureSource.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIUserNotificationCategory*)userNotificationsMessageCategory{
|
||||||
|
UIMutableUserNotificationAction *action_accept = [UIMutableUserNotificationAction new];
|
||||||
|
action_accept.identifier = Signal_Message_View_Identifier;
|
||||||
|
action_accept.title = NSLocalizedString(@"View", @"");
|
||||||
|
action_accept.activationMode = UIUserNotificationActivationModeForeground;
|
||||||
|
action_accept.destructive = NO;
|
||||||
|
action_accept.authenticationRequired = YES;
|
||||||
|
|
||||||
|
UIMutableUserNotificationAction *action_decline = [UIMutableUserNotificationAction new];
|
||||||
|
action_decline.identifier = Signal_Message_MarkAsRead_Identifier;
|
||||||
|
action_decline.title = NSLocalizedString(@"Mark as read", @"");
|
||||||
|
action_decline.activationMode = UIUserNotificationActivationModeBackground;
|
||||||
|
action_decline.destructive = NO;
|
||||||
|
action_decline.authenticationRequired = NO;
|
||||||
|
|
||||||
|
UIMutableUserNotificationCategory *messageCategory = [UIMutableUserNotificationCategory new];
|
||||||
|
messageCategory.identifier = Signal_Message_Category;
|
||||||
|
[messageCategory setActions:@[action_accept, action_decline] forContext:UIUserNotificationActionContextMinimal];
|
||||||
|
[messageCategory setActions:@[action_accept, action_decline] forContext:UIUserNotificationActionContextDefault];
|
||||||
|
|
||||||
|
return messageCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIUserNotificationCategory*)userNotificationsCallCategory{
|
||||||
|
UIMutableUserNotificationAction *action_accept = [UIMutableUserNotificationAction new];
|
||||||
|
action_accept.identifier = Signal_Call_Accept_Identifier;
|
||||||
|
action_accept.title = NSLocalizedString(@"ANSWER_CALL_BUTTON_TITLE", @"");
|
||||||
|
action_accept.activationMode = UIUserNotificationActivationModeForeground;
|
||||||
|
action_accept.destructive = NO;
|
||||||
|
action_accept.authenticationRequired = NO;
|
||||||
|
|
||||||
|
UIMutableUserNotificationAction *action_decline = [UIMutableUserNotificationAction new];
|
||||||
|
action_decline.identifier = Signal_Call_Decline_Identifier;
|
||||||
|
action_decline.title = NSLocalizedString(@"REJECT_CALL_BUTTON_TITLE", @"");
|
||||||
|
action_decline.activationMode = UIUserNotificationActivationModeBackground;
|
||||||
|
action_decline.destructive = NO;
|
||||||
|
action_decline.authenticationRequired = NO;
|
||||||
|
|
||||||
|
UIMutableUserNotificationCategory *callCategory = [UIMutableUserNotificationCategory new];
|
||||||
|
callCategory.identifier = Signal_Call_Category;
|
||||||
|
[callCategory setActions:@[action_accept, action_decline] forContext:UIUserNotificationActionContextMinimal];
|
||||||
|
[callCategory setActions:@[action_accept, action_decline] forContext:UIUserNotificationActionContextDefault];
|
||||||
|
|
||||||
|
return callCategory;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)needToRegisterForRemoteNotifications
|
- (BOOL)needToRegisterForRemoteNotifications
|
||||||
{
|
{
|
||||||
return self.wantRemoteNotifications && (!UIApplication.sharedApplication.isRegisteredForRemoteNotifications);
|
return self.wantRemoteNotifications && (!UIApplication.sharedApplication.isRegisteredForRemoteNotifications);
|
||||||
|
@ -165,11 +363,11 @@
|
||||||
|
|
||||||
#pragma mark Register Push Notification Token with RedPhone server
|
#pragma mark Register Push Notification Token with RedPhone server
|
||||||
|
|
||||||
- (TOCFuture *)registerForPushFutureWithToken:(NSData *)token
|
- (TOCFuture *)registerForPushFutureWithToken:(NSData *)pushToken voipToken:(NSData*)voipToken
|
||||||
{
|
{
|
||||||
self.registerWithServerFutureSource = [TOCFutureSource new];
|
self.registerWithServerFutureSource = [TOCFutureSource new];
|
||||||
|
|
||||||
[RPServerRequestsManager.sharedInstance performRequest:[RPAPICall registerPushNotificationWithPushToken:token]
|
[RPServerRequestsManager.sharedInstance performRequest:[RPAPICall registerPushNotificationWithPushToken:pushToken voipToken:voipToken]
|
||||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||||
if ([task.response isKindOfClass:NSHTTPURLResponse.class]) {
|
if ([task.response isKindOfClass:NSHTTPURLResponse.class]) {
|
||||||
NSInteger statusCode = [(NSHTTPURLResponse *)task.response statusCode];
|
NSInteger statusCode = [(NSHTTPURLResponse *)task.response statusCode];
|
||||||
|
@ -192,4 +390,14 @@
|
||||||
return self.registerWithServerFutureSource.future;
|
return self.registerWithServerFutureSource.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)applicationIsActive {
|
||||||
|
UIApplication *app = [UIApplication sharedApplication];
|
||||||
|
|
||||||
|
if (app.applicationState == UIApplicationStateActive) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -34,7 +34,7 @@ typedef NS_ENUM(NSInteger, HTTPMethod) {
|
||||||
+ (RPAPICall*)requestVerificationCode;
|
+ (RPAPICall*)requestVerificationCode;
|
||||||
+ (RPAPICall*)requestVerificationCodeWithVoice;
|
+ (RPAPICall*)requestVerificationCodeWithVoice;
|
||||||
+ (RPAPICall*)verifyVerificationCode:(NSString*)verificationCode;
|
+ (RPAPICall*)verifyVerificationCode:(NSString*)verificationCode;
|
||||||
+ (RPAPICall*)registerPushNotificationWithPushToken:(NSData*)pushToken;
|
+ (RPAPICall*)registerPushNotificationWithPushToken:(NSData*)pushToken voipToken:(NSData*)voipToken;
|
||||||
+ (RPAPICall*)requestTextSecureVerificationCode;
|
+ (RPAPICall*)requestTextSecureVerificationCode;
|
||||||
+ (RPAPICall*)unregisterWithPushToken:(NSData*)pushToken;
|
+ (RPAPICall*)unregisterWithPushToken:(NSData*)pushToken;
|
||||||
+ (RPAPICall*)fetchBloomFilter;
|
+ (RPAPICall*)fetchBloomFilter;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#import "SignalUtil.h"
|
#import "SignalUtil.h"
|
||||||
#import "SignalKeyingStorage.h"
|
#import "SignalKeyingStorage.h"
|
||||||
#import "Util.h"
|
#import "Util.h"
|
||||||
|
#import "NSData+ows_StripToken.h"
|
||||||
|
|
||||||
#define CLAIMED_INTEROP_VERSION_IN_INITIATE_SIGNAL 1
|
#define CLAIMED_INTEROP_VERSION_IN_INITIATE_SIGNAL 1
|
||||||
|
|
||||||
|
@ -64,10 +65,15 @@
|
||||||
return apiCall;
|
return apiCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (RPAPICall*)registerPushNotificationWithPushToken:(NSData*)pushToken {
|
+ (RPAPICall*)registerPushNotificationWithPushToken:(NSData*)pushToken voipToken:(NSData*)voipToken {
|
||||||
RPAPICall *apiCall = [self defaultAPICall];
|
RPAPICall *apiCall = [self defaultAPICall];
|
||||||
|
if (voipToken) {
|
||||||
|
apiCall.parameters = @{@"voip":[voipToken ows_tripToken]};
|
||||||
|
} else {
|
||||||
|
DDLogWarn(@"No VoIP push token registered, might experience some issues while in background.");
|
||||||
|
}
|
||||||
apiCall.method = HTTP_PUT;
|
apiCall.method = HTTP_PUT;
|
||||||
apiCall.endPoint = [NSString stringWithFormat:@"/apn/%@", pushToken.encodedAsHexString];
|
apiCall.endPoint = [NSString stringWithFormat:@"/apn/%@", [pushToken ows_tripToken]];
|
||||||
return apiCall;
|
return apiCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ typedef void(^failedVerificationBlock)(NSError *error);
|
||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
+ (void)registerWithRedPhoneToken:(NSString*)tsToken pushToken:(NSData*)pushToken success:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock;
|
+ (void)registerWithRedPhoneToken:(NSString*)tsToken pushToken:(NSData*)pushToken voipToken:(NSData*)voipToken success:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register's the device's push notification token with the server
|
* Register's the device's push notification token with the server
|
||||||
|
@ -68,7 +68,7 @@ typedef void(^failedVerificationBlock)(NSError *error);
|
||||||
* @param pushToken Apple's Push Token
|
* @param pushToken Apple's Push Token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
+ (void)registerForPushNotifications:(NSData*)pushToken success:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock;
|
+ (void)registerForPushNotifications:(NSData*)pushToken voipToken:(NSData*)voipToken success:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#import "Constraints.h"
|
#import "Constraints.h"
|
||||||
#import "NSData+Base64.h"
|
#import "NSData+Base64.h"
|
||||||
#import "NSData+hexString.h"
|
#import "NSData+hexString.h"
|
||||||
|
#import "NSData+ows_StripToken.h"
|
||||||
#import "NSURLSessionDataTask+StatusCode.h"
|
#import "NSURLSessionDataTask+StatusCode.h"
|
||||||
|
|
||||||
#import "SecurityUtils.h"
|
#import "SecurityUtils.h"
|
||||||
|
@ -71,11 +72,12 @@
|
||||||
return registrationID;
|
return registrationID;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)registerForPushNotifications:(NSData *)pushToken success:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock{
|
+ (void)registerForPushNotifications:(NSData *)pushToken voipToken:(NSData*)voipToken success:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock{
|
||||||
|
|
||||||
NSString *stringToken = [[pushToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<> "]];
|
NSString *pushTokenString = [pushToken ows_tripToken];
|
||||||
|
NSString *voipTokenString = [voipToken ows_tripToken];
|
||||||
|
|
||||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRegisterForPushRequest alloc] initWithPushIdentifier:stringToken] success:^(NSURLSessionDataTask *task, id responseObject) {
|
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRegisterForPushRequest alloc] initWithPushIdentifier:pushTokenString voipIdentifier:voipTokenString] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||||
success();
|
success();
|
||||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||||
NSLog(@"NSError: %@", error.debugDescription);
|
NSLog(@"NSError: %@", error.debugDescription);
|
||||||
|
@ -96,7 +98,12 @@
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)registerWithRedPhoneToken:(NSString*)tsToken pushToken:(NSData*)pushToken success:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock{
|
+ (void)registerWithRedPhoneToken:(NSString*)tsToken
|
||||||
|
pushToken:(NSData*)pushToken
|
||||||
|
voipToken:(NSData*)voipToken
|
||||||
|
success:(successCompletionBlock)successBlock
|
||||||
|
failure:(failedVerificationBlock)failureBlock
|
||||||
|
{
|
||||||
|
|
||||||
NSString *authToken = [self generateNewAccountAuthenticationToken];
|
NSString *authToken = [self generateNewAccountAuthenticationToken];
|
||||||
NSString *signalingKey = [self generateNewSignalingKeyToken];
|
NSString *signalingKey = [self generateNewSignalingKeyToken];
|
||||||
|
@ -118,10 +125,10 @@
|
||||||
|
|
||||||
[TSStorageManager storeServerToken:authToken signalingKey:signalingKey phoneNumber:phoneNumber];
|
[TSStorageManager storeServerToken:authToken signalingKey:signalingKey phoneNumber:phoneNumber];
|
||||||
|
|
||||||
[self registerForPushNotifications:pushToken success:^{
|
[self registerForPushNotifications:pushToken voipToken:voipToken success:^{
|
||||||
[self registerPreKeys:^{
|
[self registerPreKeys:^{
|
||||||
successBlock();
|
successBlock();
|
||||||
[TSSocketManager becomeActive];
|
[TSSocketManager becomeActiveFromForeground];
|
||||||
} failure:failureBlock];
|
} failure:failureBlock];
|
||||||
} failure:^(NSError *error) {
|
} failure:^(NSError *error) {
|
||||||
failureBlock([self errorForRegistrationFailure:kTSRegistrationFailureNetwork HTTPStatusCode:0]);
|
failureBlock([self errorForRegistrationFailure:kTSRegistrationFailureNetwork HTTPStatusCode:0]);
|
||||||
|
@ -140,10 +147,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)registerPreKeysAfterPush:(NSData*)pushToken
|
+ (void)registerPreKeysAfterPush:(NSData*)pushToken
|
||||||
|
voipToken:(NSData*)voipToken
|
||||||
success:(successCompletionBlock)successBlock
|
success:(successCompletionBlock)successBlock
|
||||||
failure:(failedVerificationBlock)failureBlock
|
failure:(failedVerificationBlock)failureBlock
|
||||||
{
|
{
|
||||||
[self registerForPushNotifications:pushToken success:^{
|
[self registerForPushNotifications:pushToken voipToken:voipToken success:^{
|
||||||
[self registerPreKeys:successBlock
|
[self registerPreKeys:successBlock
|
||||||
failure:failureBlock];
|
failure:failureBlock];
|
||||||
} failure:failureBlock];
|
} failure:failureBlock];
|
||||||
|
|
|
@ -27,4 +27,6 @@
|
||||||
|
|
||||||
- (void)handleSendToMyself:(TSOutgoingMessage*)outgoingMessage;
|
- (void)handleSendToMyself:(TSOutgoingMessage*)outgoingMessage;
|
||||||
|
|
||||||
|
- (NSUInteger)unreadMessagesCount;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#import "TSInvalidIdentityKeyReceivingErrorMessage.h"
|
#import "TSInvalidIdentityKeyReceivingErrorMessage.h"
|
||||||
#import "TSInfoMessage.h"
|
#import "TSInfoMessage.h"
|
||||||
|
|
||||||
|
#import "TSDatabaseView.h"
|
||||||
#import "TSStorageManager+keyingMaterial.h"
|
#import "TSStorageManager+keyingMaterial.h"
|
||||||
#import "TSStorageManager+IdentityKeyStore.h"
|
#import "TSStorageManager+IdentityKeyStore.h"
|
||||||
#import "TSStorageManager+SessionStore.h"
|
#import "TSStorageManager+SessionStore.h"
|
||||||
|
@ -349,7 +350,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *name = [thread name];
|
NSString *name = [thread name];
|
||||||
[self notifyUserForIncomingMessage:incomingMessage from:name];
|
[self notifyUserForIncomingMessage:incomingMessage from:name inThread:thread];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,8 +400,57 @@
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)notifyUserForIncomingMessage:(TSIncomingMessage*)message from:(NSString*)name {
|
- (NSUInteger)unreadMessagesCount {
|
||||||
|
__block NSUInteger numberOfItems;
|
||||||
|
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||||
|
numberOfItems = [[transaction ext:TSUnreadDatabaseViewExtensionName] numberOfItemsInAllGroups];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return numberOfItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)notifyUserForIncomingMessage:(TSIncomingMessage*)message from:(NSString*)name inThread:(TSThread*)thread {
|
||||||
|
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
|
||||||
|
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
||||||
|
notification.category = Signal_Message_Category;
|
||||||
|
notification.userInfo = @{Signal_Thread_UserInfo_Key:thread.uniqueId};
|
||||||
|
|
||||||
|
switch ([[Environment preferences] notificationPreviewType]) {
|
||||||
|
case NotificationNamePreview:
|
||||||
|
if ([thread isGroupThread]) {
|
||||||
|
NSString *sender = [[Environment getCurrent].contactsManager nameStringForPhoneIdentifier:message.authorId];
|
||||||
|
if (!sender) {
|
||||||
|
sender = message.authorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.alertBody = [NSString stringWithFormat:@"New message from %@ in group \"%@\": %@", sender, name, message.description];
|
||||||
|
} else {
|
||||||
|
notification.alertBody = [NSString stringWithFormat:@"%@: %@", name, message.description];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NotificationNameNoPreview:{
|
||||||
|
if ([thread isGroupThread]) {
|
||||||
|
notification.alertBody = [NSString stringWithFormat:@"%@ \"%@\"", NSLocalizedString(@"APN_MESSAGE_IN_GROUP",nil), name];
|
||||||
|
} else {
|
||||||
|
notification.alertBody = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"APN_MESSAGE_FROM", nil), name];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NotificationNoNameNoPreview:
|
||||||
|
notification.alertBody = NSLocalizedString(@"APN_Message", nil);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
notification.alertBody = NSLocalizedString(@"APN_Message", nil);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
||||||
AudioServicesPlayAlertSound(_newMessageSound);
|
AudioServicesPlayAlertSound(_newMessageSound);
|
||||||
|
} else {
|
||||||
|
if ([Environment.preferences soundInForeground]) {
|
||||||
|
AudioServicesPlayAlertSound(_newMessageSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
|
|
|
@ -9,5 +9,7 @@
|
||||||
#import "TSRequest.h"
|
#import "TSRequest.h"
|
||||||
|
|
||||||
@interface TSRegisterForPushRequest : TSRequest
|
@interface TSRegisterForPushRequest : TSRequest
|
||||||
- (id) initWithPushIdentifier:(NSString*)identifier;
|
|
||||||
|
- (id) initWithPushIdentifier:(NSString*)identifier voipIdentifier:(NSString*)voipId;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -12,12 +12,13 @@
|
||||||
|
|
||||||
@implementation TSRegisterForPushRequest
|
@implementation TSRegisterForPushRequest
|
||||||
|
|
||||||
- (id) initWithPushIdentifier:(NSString*)identifier{
|
- (id) initWithPushIdentifier:(NSString*)identifier voipIdentifier:(NSString*)voipId
|
||||||
|
{
|
||||||
self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", textSecureAccountsAPI, @"apn"]]];
|
self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", textSecureAccountsAPI, @"apn"]]];
|
||||||
|
|
||||||
self.HTTPMethod = @"PUT";
|
self.HTTPMethod = @"PUT";
|
||||||
|
|
||||||
self.parameters = [NSMutableDictionary dictionaryWithObjects:@[identifier] forKeys:@[@"apnRegistrationId"]];
|
self.parameters = [NSMutableDictionary dictionaryWithObjects:@[identifier, voipId] forKeys:@[@"apnRegistrationId", @"voipRegistrationId"]];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,9 @@ extern NSString * const SocketConnectingNotification;
|
||||||
|
|
||||||
@interface TSSocketManager : NSObject <SRWebSocketDelegate>
|
@interface TSSocketManager : NSObject <SRWebSocketDelegate>
|
||||||
|
|
||||||
+ (void)becomeActive;
|
+ (void)becomeActiveFromForeground;
|
||||||
|
+ (void)becomeActiveFromBackground;
|
||||||
|
|
||||||
+ (void)resignActivity;
|
+ (void)resignActivity;
|
||||||
+ (void)sendNotification;
|
+ (void)sendNotification;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#define kWebSocketHeartBeat 30
|
#define kWebSocketHeartBeat 30
|
||||||
#define kWebSocketReconnectTry 5
|
#define kWebSocketReconnectTry 5
|
||||||
|
#define kBackgroundConnectTimer 120
|
||||||
|
|
||||||
NSString * const SocketOpenedNotification = @"SocketOpenedNotification";
|
NSString * const SocketOpenedNotification = @"SocketOpenedNotification";
|
||||||
NSString * const SocketClosedNotification = @"SocketClosedNotification";
|
NSString * const SocketClosedNotification = @"SocketClosedNotification";
|
||||||
|
@ -32,11 +33,15 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
|
|
||||||
@property (nonatomic, retain) SRWebSocket *websocket;
|
@property (nonatomic, retain) SRWebSocket *websocket;
|
||||||
@property (nonatomic) SocketStatus status;
|
@property (nonatomic) SocketStatus status;
|
||||||
|
|
||||||
|
@property (nonatomic, retain) NSTimer *backgroundConnectTimer;
|
||||||
|
@property (nonatomic) UIBackgroundTaskIdentifier fetchingTaskIdentifier;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation TSSocketManager
|
@implementation TSSocketManager
|
||||||
|
|
||||||
- (id)init{
|
- (instancetype)init{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
|
@ -47,7 +52,7 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)sharedManager {
|
+ (instancetype)sharedManager {
|
||||||
static TSSocketManager *sharedMyManager = nil;
|
static TSSocketManager *sharedMyManager = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
|
@ -106,7 +111,11 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
#pragma mark - Delegate methods
|
#pragma mark - Delegate methods
|
||||||
|
|
||||||
- (void) webSocketDidOpen:(SRWebSocket *)webSocket {
|
- (void) webSocketDidOpen:(SRWebSocket *)webSocket {
|
||||||
self.pingTimer = [NSTimer scheduledTimerWithTimeInterval:kWebSocketHeartBeat target:self selector:@selector(webSocketHeartBeat) userInfo:nil repeats:YES];
|
self.pingTimer = [NSTimer scheduledTimerWithTimeInterval:kWebSocketHeartBeat
|
||||||
|
target:self
|
||||||
|
selector:@selector(webSocketHeartBeat)
|
||||||
|
userInfo:nil
|
||||||
|
repeats:YES];
|
||||||
self.status = kSocketStatusOpen;
|
self.status = kSocketStatusOpen;
|
||||||
|
|
||||||
[self.reconnectTimer invalidate];
|
[self.reconnectTimer invalidate];
|
||||||
|
@ -198,10 +207,71 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
|
|
||||||
- (void)scheduleRetry {
|
- (void)scheduleRetry {
|
||||||
if (!self.reconnectTimer || ![self.reconnectTimer isValid]) {
|
if (!self.reconnectTimer || ![self.reconnectTimer isValid]) {
|
||||||
self.reconnectTimer = [NSTimer scheduledTimerWithTimeInterval:kWebSocketReconnectTry target:[self class] selector:@selector(becomeActive) userInfo:nil repeats:YES];
|
self.reconnectTimer = [NSTimer scheduledTimerWithTimeInterval:kWebSocketReconnectTry
|
||||||
|
target:[self class]
|
||||||
|
selector:@selector(becomeActive)
|
||||||
|
userInfo:nil
|
||||||
|
repeats:YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Background Connect
|
||||||
|
|
||||||
|
+ (void)becomeActiveFromForeground {
|
||||||
|
TSSocketManager *sharedInstance = [self sharedManager];
|
||||||
|
|
||||||
|
[sharedInstance.backgroundConnectTimer invalidate];
|
||||||
|
sharedInstance.backgroundConnectTimer = nil;
|
||||||
|
sharedInstance.fetchingTaskIdentifier = 0;
|
||||||
|
|
||||||
|
[self becomeActive];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+ (void)becomeActiveFromBackground {
|
||||||
|
TSSocketManager *sharedInstance = [TSSocketManager sharedManager];
|
||||||
|
|
||||||
|
if (sharedInstance.fetchingTaskIdentifier == 0) {
|
||||||
|
sharedInstance.fetchingTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||||
|
sharedInstance.fetchingTaskIdentifier = 0;
|
||||||
|
[TSSocketManager resignActivity];
|
||||||
|
}];
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSTimer * timer = [NSTimer timerWithTimeInterval:kBackgroundConnectTimer
|
||||||
|
target:sharedInstance
|
||||||
|
selector:@selector(closeBackgroundTask)
|
||||||
|
userInfo:nil
|
||||||
|
repeats:NO];
|
||||||
|
|
||||||
|
[[NSRunLoop mainRunLoop] addTimer:timer
|
||||||
|
forMode:NSDefaultRunLoopMode];
|
||||||
|
});
|
||||||
|
|
||||||
|
[self becomeActive];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)closeBackgroundTask {
|
||||||
|
UIBackgroundTaskIdentifier identifier = self.fetchingTaskIdentifier;
|
||||||
|
self.fetchingTaskIdentifier = 0;
|
||||||
|
|
||||||
|
if ([_websocket readyState] != SR_OPEN) {
|
||||||
|
[self backgroundConnectTimedOut];
|
||||||
|
}
|
||||||
|
|
||||||
|
[TSSocketManager resignActivity];
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] endBackgroundTask:identifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)backgroundConnectTimedOut {
|
||||||
|
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
||||||
|
notification.alertBody = NSLocalizedString(@"APN_FETCHED_FAILED", nil);
|
||||||
|
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark UI Delegates
|
#pragma mark UI Delegates
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||||
|
|
15
Signal/src/util/NSData+ows_StripToken.h
Normal file
15
Signal/src/util/NSData+ows_StripToken.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// NSData+ows_StripToken.h
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Frederic Jacobs on 14/04/15.
|
||||||
|
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface NSData (ows_StripToken)
|
||||||
|
|
||||||
|
- (NSString*)ows_tripToken;
|
||||||
|
|
||||||
|
@end
|
19
Signal/src/util/NSData+ows_StripToken.m
Normal file
19
Signal/src/util/NSData+ows_StripToken.m
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// NSData+ows_StripToken.m
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Frederic Jacobs on 14/04/15.
|
||||||
|
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "NSData+ows_StripToken.h"
|
||||||
|
|
||||||
|
@implementation NSData (ows_StripToken)
|
||||||
|
|
||||||
|
- (NSString*)ows_tripToken {
|
||||||
|
return [[[NSString stringWithFormat:@"%@", self]
|
||||||
|
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]
|
||||||
|
stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -78,10 +78,10 @@
|
||||||
[[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall verifyVerificationCode:_challengeTextField.text]
|
[[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall verifyVerificationCode:_challengeTextField.text]
|
||||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||||
|
|
||||||
[PushManager.sharedManager registrationAndRedPhoneTokenRequestWithSuccess:^(NSData *pushToken,
|
[PushManager.sharedManager registrationAndRedPhoneTokenRequestWithSuccess:^(NSData *pushToken, NSData *voipToken, NSString *signupToken) {
|
||||||
NSString *signupToken) {
|
|
||||||
[TSAccountManager registerWithRedPhoneToken:signupToken
|
[TSAccountManager registerWithRedPhoneToken:signupToken
|
||||||
pushToken:pushToken
|
pushToken:pushToken
|
||||||
|
voipToken:voipToken
|
||||||
success:^{
|
success:^{
|
||||||
success();
|
success();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
#import "PhoneNumber.h"
|
#import "PhoneNumber.h"
|
||||||
#import "PhoneNumberDirectoryFilterManager.h"
|
#import "PhoneNumberDirectoryFilterManager.h"
|
||||||
|
|
||||||
|
#define PICK_UP_NOTIFICATION @"RedPhoneCallPickUpNotification"
|
||||||
|
#define HANG_UP_NOTIFICATION @"RedPhoneCallHangUpNotification"
|
||||||
|
|
||||||
|
|
||||||
@interface InCallViewController : UIViewController
|
@interface InCallViewController : UIViewController
|
||||||
|
|
||||||
@property (nonatomic, strong) IBOutlet UIView *conversationContactView;
|
@property (nonatomic, strong) IBOutlet UIView *conversationContactView;
|
||||||
|
|
|
@ -418,7 +418,7 @@
|
||||||
NSString *identifier = [[[self contactForIndexPath:indexPath] textSecureIdentifiers] firstObject];
|
NSString *identifier = [[[self contactForIndexPath:indexPath] textSecureIdentifiers] firstObject];
|
||||||
|
|
||||||
[self dismissViewControllerAnimated:YES completion:^(){
|
[self dismissViewControllerAnimated:YES completion:^(){
|
||||||
[Environment messageIdentifier:identifier];
|
[Environment messageIdentifier:identifier withCompose:YES];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,4 +28,6 @@
|
||||||
- (void)setupWithTSIdentifier:(NSString*)identifier;
|
- (void)setupWithTSIdentifier:(NSString*)identifier;
|
||||||
- (void)setupWithTSGroup:(TSGroupModel*)model;
|
- (void)setupWithTSGroup:(TSGroupModel*)model;
|
||||||
|
|
||||||
|
- (void)setComposeOnOpen:(BOOL)compose;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -108,6 +108,7 @@ typedef enum : NSUInteger {
|
||||||
@property NSUInteger page;
|
@property NSUInteger page;
|
||||||
|
|
||||||
@property BOOL isVisible;
|
@property BOOL isVisible;
|
||||||
|
@property (nonatomic) BOOL composeOnOpen;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -135,6 +136,10 @@ typedef enum : NSUInteger {
|
||||||
isGroupConversation = YES;
|
isGroupConversation = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setComposeOnOpen:(BOOL)compose {
|
||||||
|
_composeOnOpen = compose;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setupWithThread:(TSThread *)thread {
|
- (void)setupWithThread:(TSThread *)thread {
|
||||||
self.thread = thread;
|
self.thread = thread;
|
||||||
isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]];
|
isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]];
|
||||||
|
@ -232,9 +237,14 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
- (void)viewDidAppear:(BOOL)animated {
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
[super viewDidAppear:animated];
|
[super viewDidAppear:animated];
|
||||||
|
[self markAllMessagesAsRead];
|
||||||
[self startReadTimer];
|
[self startReadTimer];
|
||||||
_isVisible = YES;
|
_isVisible = YES;
|
||||||
[self initializeTitleLabelGestureRecognizer];
|
[self initializeTitleLabelGestureRecognizer];
|
||||||
|
|
||||||
|
if (_composeOnOpen) {
|
||||||
|
[self popKeyBoard];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated {
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
|
@ -1593,6 +1603,10 @@ typedef enum : NSUInteger {
|
||||||
[self.collectionView reloadData];
|
[self.collectionView reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)popKeyBoard {
|
||||||
|
[self.inputToolbar.contentView.textView becomeFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)dismissKeyBoard {
|
- (void)dismissKeyBoard {
|
||||||
[self.inputToolbar.contentView.textView resignFirstResponder];
|
[self.inputToolbar.contentView.textView resignFirstResponder];
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ static NSString* const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
|
||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
-(void)createGroup {
|
-(void)createGroup {
|
||||||
TSGroupModel* model = [self makeGroup];
|
TSGroupModel* model = [self makeGroup];
|
||||||
[Environment messageGroupModel:model];
|
[Environment messageGroupModel:model withCompose:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
//
|
||||||
|
// NotificationSettingsOptionsViewController.h
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Frederic Jacobs on 24/04/15.
|
||||||
|
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface NotificationSettingsOptionsViewController : UITableViewController
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,55 @@
|
||||||
|
//
|
||||||
|
// NotificationSettingsOptionsViewController.m
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Frederic Jacobs on 24/04/15.
|
||||||
|
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "NotificationSettingsOptionsViewController.h"
|
||||||
|
#import "Environment.h"
|
||||||
|
#import "PropertyListPreferences.h"
|
||||||
|
#import "PreferencesUtil.h"
|
||||||
|
|
||||||
|
@interface NotificationSettingsOptionsViewController ()
|
||||||
|
@property NSArray *options;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NotificationSettingsOptionsViewController
|
||||||
|
|
||||||
|
- (void)viewDidLoad
|
||||||
|
{
|
||||||
|
self.options = @[@(NotificationNamePreview),
|
||||||
|
@(NotificationNameNoPreview),
|
||||||
|
@(NotificationNoNameNoPreview)];
|
||||||
|
[super viewDidLoad];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Table view data source
|
||||||
|
|
||||||
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||||
|
{
|
||||||
|
return (NSInteger)[self.options count];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"NotificationSettingsOption"];
|
||||||
|
PropertyListPreferences *prefs = [Environment preferences];
|
||||||
|
[[cell textLabel] setText:[prefs nameForNotificationPreviewType:[[self.options objectAtIndex:(NSUInteger)indexPath.row] unsignedIntegerValue]]];
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
[Environment.preferences setNotificationPreviewType:[[self.options objectAtIndex:(NSUInteger)indexPath.row] unsignedIntegerValue]];
|
||||||
|
[self.navigationController popViewControllerAnimated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
13
Signal/src/view controllers/NotificationSettingsViewController.h
Executable file
13
Signal/src/view controllers/NotificationSettingsViewController.h
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
//
|
||||||
|
// NotificationPreviewViewController.h
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Dylan Bourgeois on 09/12/14.
|
||||||
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface NotificationSettingsViewController : UITableViewController
|
||||||
|
|
||||||
|
@end
|
110
Signal/src/view controllers/NotificationSettingsViewController.m
Executable file
110
Signal/src/view controllers/NotificationSettingsViewController.m
Executable file
|
@ -0,0 +1,110 @@
|
||||||
|
//
|
||||||
|
// NotificationPreviewViewController.m
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Frederic Jacobs on 09/12/14.
|
||||||
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "NotificationSettingsViewController.h"
|
||||||
|
|
||||||
|
#import "Environment.h"
|
||||||
|
#import "PreferencesUtil.h"
|
||||||
|
#import "NotificationSettingsOptionsViewController.h"
|
||||||
|
#import "UIUtil.h"
|
||||||
|
|
||||||
|
@interface NotificationSettingsViewController ()
|
||||||
|
|
||||||
|
@property NSArray *notificationsSections;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NotificationSettingsViewController
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
return [super initWithStyle:UITableViewStyleGrouped];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLoad
|
||||||
|
{
|
||||||
|
[super viewDidLoad];
|
||||||
|
[self setTitle:NSLocalizedString(@"SETTINGS_NOTIFICATIONS", nil)];
|
||||||
|
|
||||||
|
|
||||||
|
self.notificationsSections = @[NSLocalizedString(@"NOTIFICATIONS_SECTION_BACKGROUND", nil),
|
||||||
|
NSLocalizedString(@"NOTIFICATIONS_SECTION_INAPP",nil)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidAppear:(BOOL)animated
|
||||||
|
{
|
||||||
|
[self.tableView reloadData];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Table view data source
|
||||||
|
|
||||||
|
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
|
||||||
|
return [self.notificationsSections objectAtIndex:(NSUInteger)section];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||||
|
{
|
||||||
|
return (NSInteger)self.notificationsSections.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
NSString *cellIdentifier = @"SignalTableViewCellIdentifier";
|
||||||
|
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
|
||||||
|
|
||||||
|
if (cell == nil) {
|
||||||
|
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyListPreferences *prefs = Environment.preferences;
|
||||||
|
if (indexPath.section == 0) {
|
||||||
|
NotificationType notifType = [prefs notificationPreviewType];
|
||||||
|
NSString *detailString = [prefs nameForNotificationPreviewType:notifType];
|
||||||
|
|
||||||
|
[[cell textLabel]setText:NSLocalizedString(@"NOTIFICATIONS_SHOW", nil)];
|
||||||
|
[[cell detailTextLabel] setText:detailString];
|
||||||
|
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
|
||||||
|
} else {
|
||||||
|
BOOL soundEnabled = [prefs soundInForeground];
|
||||||
|
|
||||||
|
[[cell textLabel]setText:NSLocalizedString(@"NOTIFICATIONS_SOUND", nil)];
|
||||||
|
[[cell detailTextLabel] setText:nil];
|
||||||
|
UISwitch *switchv = [[UISwitch alloc] initWithFrame:CGRectZero];
|
||||||
|
switchv.on = soundEnabled;
|
||||||
|
[switchv addTarget:self
|
||||||
|
action:@selector(didToggleSoundNotificationsSwitch:)
|
||||||
|
forControlEvents:UIControlEventValueChanged];
|
||||||
|
|
||||||
|
cell.accessoryView = switchv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)didToggleSoundNotificationsSwitch:(UISwitch*)sender
|
||||||
|
{
|
||||||
|
[Environment.preferences setSoundInForeground:sender.on];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
NotificationSettingsOptionsViewController *vc = [[NotificationSettingsOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
|
||||||
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
|
||||||
|
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
@property IBOutlet UILabel *networkStatusHeader;
|
@property IBOutlet UILabel *networkStatusHeader;
|
||||||
@property IBOutlet UILabel *settingsPrivacyTitle;
|
@property IBOutlet UILabel *settingsPrivacyTitle;
|
||||||
|
@property IBOutlet UILabel *settingsNotifications;
|
||||||
@property IBOutlet UILabel *settingsAdvancedTitle;
|
@property IBOutlet UILabel *settingsAdvancedTitle;
|
||||||
@property IBOutlet UILabel *settingsAboutTitle;
|
@property IBOutlet UILabel *settingsAboutTitle;
|
||||||
@property IBOutlet UIButton *destroyAccountButton;
|
@property IBOutlet UIButton *destroyAccountButton;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#import "AdvancedSettingsTableViewController.h"
|
#import "AdvancedSettingsTableViewController.h"
|
||||||
#import "AboutTableViewController.h"
|
#import "AboutTableViewController.h"
|
||||||
#import "PushManager.h"
|
#import "PushManager.h"
|
||||||
|
#import "NotificationSettingsViewController.h"
|
||||||
|
|
||||||
#define kProfileCellHeight 87.0f
|
#define kProfileCellHeight 87.0f
|
||||||
#define kStandardCellHeight 44.0f
|
#define kStandardCellHeight 44.0f
|
||||||
|
@ -45,22 +46,23 @@
|
||||||
|
|
||||||
#define kRegisteredNumberRow 0
|
#define kRegisteredNumberRow 0
|
||||||
#define kPrivacyRow 0
|
#define kPrivacyRow 0
|
||||||
#define kAdvancedRow 1
|
#define kNotificationRow 1
|
||||||
#define kAboutRow 2
|
#define kAdvancedRow 2
|
||||||
|
#define kAboutRow 3
|
||||||
#define kNetworkRow 0
|
#define kNetworkRow 0
|
||||||
#define kUnregisterRow 0
|
#define kUnregisterRow 0
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kRegisteredRows = 1,
|
kRegisteredRows = 1,
|
||||||
kGeneralRows = 3,
|
kGeneralRows = 4,
|
||||||
kNetworkStatusRows = 1,
|
kNetworkStatusRows = 1,
|
||||||
kUnregisterRows = 1,
|
kUnregisterRows = 1,
|
||||||
} kRowsForSection;
|
} kRowsForSection;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kRegisteredNumberSection=0,
|
kRegisteredNumberSection=0,
|
||||||
kGeneralSection=2,
|
|
||||||
kNetworkStatusSection=1,
|
kNetworkStatusSection=1,
|
||||||
|
kGeneralSection=2,
|
||||||
kUnregisterSection=3,
|
kUnregisterSection=3,
|
||||||
} kSection;
|
} kSection;
|
||||||
|
|
||||||
|
@ -86,6 +88,7 @@ typedef enum {
|
||||||
_settingsPrivacyTitle.text = NSLocalizedString(@"SETTINGS_PRIVACY_TITLE",@"");
|
_settingsPrivacyTitle.text = NSLocalizedString(@"SETTINGS_PRIVACY_TITLE",@"");
|
||||||
_settingsAdvancedTitle.text = NSLocalizedString(@"SETTINGS_ADVANCED_TITLE",@"");
|
_settingsAdvancedTitle.text = NSLocalizedString(@"SETTINGS_ADVANCED_TITLE",@"");
|
||||||
_settingsAboutTitle.text = NSLocalizedString(@"SETTINGS_ABOUT",@"");
|
_settingsAboutTitle.text = NSLocalizedString(@"SETTINGS_ABOUT",@"");
|
||||||
|
_settingsNotifications.text = NSLocalizedString(@"SETTINGS_NOTIFICATIONS", nil);
|
||||||
[_destroyAccountButton setTitle:NSLocalizedString(@"SETTINGS_DELETE_ACCOUNT_BUTTON", @"") forState:UIControlStateNormal];
|
[_destroyAccountButton setTitle:NSLocalizedString(@"SETTINGS_DELETE_ACCOUNT_BUTTON", @"") forState:UIControlStateNormal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +143,12 @@ typedef enum {
|
||||||
[self.navigationController pushViewController:vc animated:YES];
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kNotificationRow:
|
||||||
|
{
|
||||||
|
NotificationSettingsViewController *vc = [[NotificationSettingsViewController alloc] init];
|
||||||
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
|
break;
|
||||||
|
}
|
||||||
case kAdvancedRow:
|
case kAdvancedRow:
|
||||||
{
|
{
|
||||||
AdvancedSettingsTableViewController *vc = [[AdvancedSettingsTableViewController alloc]init];
|
AdvancedSettingsTableViewController *vc = [[AdvancedSettingsTableViewController alloc]init];
|
||||||
|
@ -193,7 +202,7 @@ typedef enum {
|
||||||
|
|
||||||
- (void)proceedToUnregistration{
|
- (void)proceedToUnregistration{
|
||||||
[TSAccountManager unregisterTextSecureWithSuccess:^{
|
[TSAccountManager unregisterTextSecureWithSuccess:^{
|
||||||
[PushManager.sharedManager requestPushTokenWithSuccess:^(NSData* pushToken){
|
[PushManager.sharedManager requestPushTokenWithSuccess:^(NSData* pushToken, NSData *voipToken){
|
||||||
[[RPServerRequestsManager sharedInstance]performRequest:[RPAPICall unregisterWithPushToken:pushToken] success:^(NSURLSessionDataTask *task, id responseObject) {
|
[[RPServerRequestsManager sharedInstance]performRequest:[RPAPICall unregisterWithPushToken:pushToken] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||||
[Environment resetAppData];
|
[Environment resetAppData];
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
@property (nonatomic) NSString *contactIdentifierFromCompose;
|
@property (nonatomic) NSString *contactIdentifierFromCompose;
|
||||||
@property (nonatomic) TSGroupModel *groupFromCompose;
|
@property (nonatomic) TSGroupModel *groupFromCompose;
|
||||||
|
@property (nonatomic) BOOL composeMessage;
|
||||||
|
|
||||||
@property (nonatomic, retain) IBOutlet UITableView *tableView;
|
@property (nonatomic, retain) IBOutlet UITableView *tableView;
|
||||||
@property (nonatomic, retain) IBOutlet UIButton *inboxButton;
|
@property (nonatomic, retain) IBOutlet UIButton *inboxButton;
|
||||||
@property (nonatomic, retain) IBOutlet UIButton *archiveButton;
|
@property (nonatomic, retain) IBOutlet UIButton *archiveButton;
|
||||||
|
|
|
@ -211,12 +211,7 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
|
|
||||||
|
|
||||||
-(void) updateInboxCountLabel {
|
-(void) updateInboxCountLabel {
|
||||||
|
NSUInteger numberOfItems = [[TSMessagesManager sharedManager] unreadMessagesCount];
|
||||||
__block NSUInteger numberOfItems;
|
|
||||||
[_editingDbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
|
||||||
numberOfItems = [[transaction ext:TSUnreadDatabaseViewExtensionName] numberOfItemsInAllGroups];
|
|
||||||
}];
|
|
||||||
|
|
||||||
NSNumber *badgeNumber = [NSNumber numberWithUnsignedInteger:numberOfItems];
|
NSNumber *badgeNumber = [NSNumber numberWithUnsignedInteger:numberOfItems];
|
||||||
NSString *badgeValue = nil;
|
NSString *badgeValue = nil;
|
||||||
|
|
||||||
|
@ -224,6 +219,7 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
badgeValue = [badgeNumber stringValue];
|
badgeValue = [badgeNumber stringValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeNumber.integerValue];
|
||||||
self.inboxCountLabel.text = badgeValue;
|
self.inboxCountLabel.text = badgeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,23 +231,30 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
#pragma mark - Navigation
|
#pragma mark - Navigation
|
||||||
|
|
||||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||||
|
|
||||||
if ([segue.identifier isEqualToString:kSegueIndentifier]){
|
if ([segue.identifier isEqualToString:kSegueIndentifier]){
|
||||||
MessagesViewController * vc = [segue destinationViewController];
|
MessagesViewController * vc = [segue destinationViewController];
|
||||||
NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
|
NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
|
||||||
TSThread *thread = [self threadForIndexPath:selectedIndexPath];
|
TSThread *thread = [self threadForIndexPath:selectedIndexPath];
|
||||||
if (self.contactIdentifierFromCompose){
|
if (self.contactIdentifierFromCompose){
|
||||||
[vc setupWithTSIdentifier:self.contactIdentifierFromCompose];
|
[vc setupWithTSIdentifier:self.contactIdentifierFromCompose];
|
||||||
|
[vc setComposeOnOpen:self.composeMessage];
|
||||||
self.contactIdentifierFromCompose = nil;
|
self.contactIdentifierFromCompose = nil;
|
||||||
|
self.composeMessage = NO;
|
||||||
}
|
}
|
||||||
else if (self.groupFromCompose) {
|
else if (self.groupFromCompose) {
|
||||||
[vc setupWithTSGroup:self.groupFromCompose];
|
[vc setupWithTSGroup:self.groupFromCompose];
|
||||||
|
[vc setComposeOnOpen:self.composeMessage];
|
||||||
self.groupFromCompose = nil;
|
self.groupFromCompose = nil;
|
||||||
|
self.composeMessage = NO;
|
||||||
}
|
}
|
||||||
else if (thread) {
|
else if (thread) {
|
||||||
[vc setupWithThread:thread];
|
[vc setupWithThread:thread];
|
||||||
|
[vc setComposeOnOpen:NO];
|
||||||
|
}
|
||||||
|
else if([sender isKindOfClass:[TSGroupThread class]]){
|
||||||
|
[vc setupWithThread:sender];
|
||||||
|
[vc setComposeOnOpen:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ([segue.identifier isEqualToString:kCallSegue]) {
|
else if ([segue.identifier isEqualToString:kCallSegue]) {
|
||||||
InCallViewController* vc = [segue destinationViewController];
|
InCallViewController* vc = [segue destinationViewController];
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue