mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
UX and Notifications fixes
- Removes large confusing UX bar and related assets. Replaced with UISwitch. - Enhanced user experience for missed calls. - Fixes issue where missed call would appear as incoming call in call log. - Fixing issues where PushKit handler not called on launch.
This commit is contained in:
parent
93de0a4326
commit
57f86008d1
76 changed files with 404 additions and 2768 deletions
|
@ -898,7 +898,6 @@
|
||||||
B633C54C1A1D190B0059AC12 /* quit@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quit@2x.png"; sourceTree = "<group>"; };
|
B633C54C1A1D190B0059AC12 /* quit@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quit@2x.png"; sourceTree = "<group>"; };
|
||||||
B633C5501A1D190B0059AC12 /* savephoto@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "savephoto@2x.png"; sourceTree = "<group>"; };
|
B633C5501A1D190B0059AC12 /* savephoto@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "savephoto@2x.png"; sourceTree = "<group>"; };
|
||||||
B634CBB31AB10D2300C49B99 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = translations/hr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B634CBB31AB10D2300C49B99 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = translations/hr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B634CBB41AB10D3700C49B99 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
|
||||||
B634CBB51AB10D5400C49B99 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = translations/ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B634CBB51AB10D5400C49B99 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = translations/ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B63761E119E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AFHTTPSessionManager+SignalMethods.h"; sourceTree = "<group>"; };
|
B63761E119E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AFHTTPSessionManager+SignalMethods.h"; sourceTree = "<group>"; };
|
||||||
B63761E219E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AFHTTPSessionManager+SignalMethods.m"; sourceTree = "<group>"; };
|
B63761E219E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AFHTTPSessionManager+SignalMethods.m"; sourceTree = "<group>"; };
|
||||||
|
@ -942,7 +941,6 @@
|
||||||
B640C4761A477B0F005C7C8A /* TSAttachementsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachementsTest.m; sourceTree = "<group>"; };
|
B640C4761A477B0F005C7C8A /* TSAttachementsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachementsTest.m; sourceTree = "<group>"; };
|
||||||
B646D10E1AA5461A004133BA /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = translations/fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B646D10E1AA5461A004133BA /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = translations/fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B646D10F1AA54626004133BA /* fil */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fil; path = translations/fil.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B646D10F1AA54626004133BA /* fil */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fil; path = translations/fil.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B646D1131AA54667004133BA /* hi_IN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi_IN; path = translations/hi_IN.lproj/Localizable.strings; sourceTree = "<group>"; };
|
|
||||||
B646D1141AA54674004133BA /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = translations/hu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B646D1141AA54674004133BA /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = translations/hu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B646D1151AA5467E004133BA /* it_IT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it_IT; path = translations/it_IT.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B646D1151AA5467E004133BA /* it_IT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it_IT; path = translations/it_IT.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B65031CE1A7862AA002EBBBD /* SignedPreKeyDeletionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignedPreKeyDeletionTests.m; sourceTree = "<group>"; };
|
B65031CE1A7862AA002EBBBD /* SignedPreKeyDeletionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignedPreKeyDeletionTests.m; sourceTree = "<group>"; };
|
||||||
|
@ -982,7 +980,6 @@
|
||||||
B68CB7E21AA5485B0065AC3F /* sv_SE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv_SE; path = translations/sv_SE.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B68CB7E21AA5485B0065AC3F /* sv_SE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv_SE; path = translations/sv_SE.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B68CB7E31AA548660065AC3F /* th_TH */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th_TH; path = translations/th_TH.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B68CB7E31AA548660065AC3F /* th_TH */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th_TH; path = translations/th_TH.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B68CB7E41AA548700065AC3F /* tr_TR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr_TR; path = translations/tr_TR.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B68CB7E41AA548700065AC3F /* tr_TR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr_TR; path = translations/tr_TR.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B68CB7E51AA5487D0065AC3F /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = translations/uk.lproj/Localizable.strings; sourceTree = "<group>"; };
|
|
||||||
B68CB7E61AA548870065AC3F /* zh_CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_CN; path = translations/zh_CN.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B68CB7E61AA548870065AC3F /* zh_CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_CN; path = translations/zh_CN.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B692BF051A76EF0F002786DA /* TSDatabaseSecondaryIndexes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSDatabaseSecondaryIndexes.h; sourceTree = "<group>"; };
|
B692BF051A76EF0F002786DA /* TSDatabaseSecondaryIndexes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSDatabaseSecondaryIndexes.h; sourceTree = "<group>"; };
|
||||||
B692BF061A76EF0F002786DA /* TSDatabaseSecondaryIndexes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSDatabaseSecondaryIndexes.m; sourceTree = "<group>"; };
|
B692BF061A76EF0F002786DA /* TSDatabaseSecondaryIndexes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSDatabaseSecondaryIndexes.m; sourceTree = "<group>"; };
|
||||||
|
@ -1090,7 +1087,6 @@
|
||||||
B6C93C4D199567AD00EDF894 /* DebugLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugLogger.m; sourceTree = "<group>"; };
|
B6C93C4D199567AD00EDF894 /* DebugLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugLogger.m; sourceTree = "<group>"; };
|
||||||
B6E314C71A38FAAF00A41AFB /* TSFingerprintGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSFingerprintGenerator.h; sourceTree = "<group>"; };
|
B6E314C71A38FAAF00A41AFB /* TSFingerprintGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSFingerprintGenerator.h; sourceTree = "<group>"; };
|
||||||
B6E314C81A38FAAF00A41AFB /* TSFingerprintGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSFingerprintGenerator.m; sourceTree = "<group>"; };
|
B6E314C81A38FAAF00A41AFB /* TSFingerprintGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSFingerprintGenerator.m; sourceTree = "<group>"; };
|
||||||
B6E80FA61AA5453C0000253B /* et_EE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et_EE; path = translations/et_EE.lproj/Localizable.strings; sourceTree = "<group>"; };
|
|
||||||
B6F509961AA53F760068F56A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = translations/en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B6F509961AA53F760068F56A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = translations/en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B6FAAAE61A41BC6C007FEC1D /* TSAttachmentPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSAttachmentPointer.h; path = Attachements/TSAttachmentPointer.h; sourceTree = "<group>"; };
|
B6FAAAE61A41BC6C007FEC1D /* TSAttachmentPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSAttachmentPointer.h; path = Attachements/TSAttachmentPointer.h; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
|
@ -2793,10 +2789,8 @@
|
||||||
sv_SE,
|
sv_SE,
|
||||||
th_TH,
|
th_TH,
|
||||||
tr_TR,
|
tr_TR,
|
||||||
uk,
|
|
||||||
zh_CN,
|
zh_CN,
|
||||||
hr,
|
hr,
|
||||||
fa,
|
|
||||||
ro,
|
ro,
|
||||||
);
|
);
|
||||||
mainGroup = D221A07E169C9E5E00537ABF;
|
mainGroup = D221A07E169C9E5E00537ABF;
|
||||||
|
@ -3435,11 +3429,9 @@
|
||||||
B676BCEF1AA544E7009637B8 /* de */,
|
B676BCEF1AA544E7009637B8 /* de */,
|
||||||
B676BCF01AA544F5009637B8 /* el_GR */,
|
B676BCF01AA544F5009637B8 /* el_GR */,
|
||||||
B676BCF11AA5451E009637B8 /* es */,
|
B676BCF11AA5451E009637B8 /* es */,
|
||||||
B6E80FA61AA5453C0000253B /* et_EE */,
|
|
||||||
B63FBC9E1AA545CB00548746 /* fi */,
|
B63FBC9E1AA545CB00548746 /* fi */,
|
||||||
B646D10E1AA5461A004133BA /* fr */,
|
B646D10E1AA5461A004133BA /* fr */,
|
||||||
B646D10F1AA54626004133BA /* fil */,
|
B646D10F1AA54626004133BA /* fil */,
|
||||||
B646D1131AA54667004133BA /* hi_IN */,
|
|
||||||
B646D1141AA54674004133BA /* hu */,
|
B646D1141AA54674004133BA /* hu */,
|
||||||
B646D1151AA5467E004133BA /* it_IT */,
|
B646D1151AA5467E004133BA /* it_IT */,
|
||||||
B60341CD1AA5469800A01E42 /* ja_JP */,
|
B60341CD1AA5469800A01E42 /* ja_JP */,
|
||||||
|
@ -3455,10 +3447,8 @@
|
||||||
B68CB7E21AA5485B0065AC3F /* sv_SE */,
|
B68CB7E21AA5485B0065AC3F /* sv_SE */,
|
||||||
B68CB7E31AA548660065AC3F /* th_TH */,
|
B68CB7E31AA548660065AC3F /* th_TH */,
|
||||||
B68CB7E41AA548700065AC3F /* tr_TR */,
|
B68CB7E41AA548700065AC3F /* tr_TR */,
|
||||||
B68CB7E51AA5487D0065AC3F /* uk */,
|
|
||||||
B68CB7E61AA548870065AC3F /* zh_CN */,
|
B68CB7E61AA548870065AC3F /* zh_CN */,
|
||||||
B634CBB31AB10D2300C49B99 /* hr */,
|
B634CBB31AB10D2300C49B99 /* hr */,
|
||||||
B634CBB41AB10D3700C49B99 /* fa */,
|
|
||||||
B634CBB51AB10D5400C49B99 /* ro */,
|
B634CBB51AB10D5400C49B99 /* ro */,
|
||||||
);
|
);
|
||||||
name = Localizable.strings;
|
name = Localizable.strings;
|
||||||
|
@ -3607,8 +3597,8 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -3662,8 +3652,8 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
|
|
@ -65,7 +65,8 @@
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable>
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "D221A088169C9E5E00537ABF"
|
BlueprintIdentifier = "D221A088169C9E5E00537ABF"
|
||||||
|
@ -83,7 +84,8 @@
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
buildConfiguration = "App Store Release"
|
buildConfiguration = "App Store Release"
|
||||||
debugDocumentVersioning = "YES">
|
debugDocumentVersioning = "YES">
|
||||||
<BuildableProductRunnable>
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "D221A088169C9E5E00537ABF"
|
BlueprintIdentifier = "D221A088169C9E5E00537ABF"
|
||||||
|
|
|
@ -82,5 +82,8 @@
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"version" : 1,
|
||||||
"author" : "xcode"
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"pre-rendered" : true
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "archive_active.pdf"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "archive_inactive.pdf"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "inbox_active.pdf"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "inbox_inactive.pdf"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -40,7 +40,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2.1.0</string>
|
<string>2.1.35</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>
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
[self setupAppearance];
|
[self setupAppearance];
|
||||||
|
|
||||||
[[PushManager sharedManager] registerPushKitNotificationFuture];
|
[[PushManager sharedManager] registerPushKitNotificationFuture];
|
||||||
|
|
||||||
if (getenv("runningTests_dontStartApp")) {
|
if (getenv("runningTests_dontStartApp")) {
|
||||||
|
@ -89,9 +88,14 @@
|
||||||
[self prepareScreenshotProtection];
|
[self prepareScreenshotProtection];
|
||||||
|
|
||||||
if ([TSAccountManager isRegistered]) {
|
if ([TSAccountManager isRegistered]) {
|
||||||
if ([self applicationIsActive]) {
|
if (application.applicationState == UIApplicationStateInactive) {
|
||||||
[TSSocketManager becomeActiveFromForeground];
|
[TSSocketManager becomeActiveFromForeground];
|
||||||
|
} else if (application.applicationState == UIApplicationStateBackground) {
|
||||||
|
[TSSocketManager becomeActiveFromBackgroundExpectMessage:NO];
|
||||||
|
} else {
|
||||||
|
DDLogWarn(@"The app was launched in an unknown way");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[PushManager sharedManager] validateUserNotificationSettings];
|
[[PushManager sharedManager] validateUserNotificationSettings];
|
||||||
[self refreshContacts];
|
[self refreshContacts];
|
||||||
[TSPreKeyManager refreshPreKeys];
|
[TSPreKeyManager refreshPreKeys];
|
||||||
|
@ -157,7 +161,6 @@
|
||||||
[self protectScreen];
|
[self protectScreen];
|
||||||
|
|
||||||
if ([TSAccountManager isRegistered]) {
|
if ([TSAccountManager isRegistered]) {
|
||||||
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
|
|
||||||
[self updateBadge];
|
[self updateBadge];
|
||||||
[TSSocketManager resignActivity];
|
[TSSocketManager resignActivity];
|
||||||
}
|
}
|
||||||
|
@ -165,6 +168,8 @@
|
||||||
|
|
||||||
- (void)updateBadge {
|
- (void)updateBadge {
|
||||||
if ([TSAccountManager isRegistered]) {
|
if ([TSAccountManager isRegistered]) {
|
||||||
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
|
||||||
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
|
||||||
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:(NSInteger)[[TSMessagesManager sharedManager] unreadMessagesCount]];
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:(NSInteger)[[TSMessagesManager sharedManager] unreadMessagesCount]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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="7702" systemVersion="14D136" 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="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="tuk-0x-yCb">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||||
<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"/>
|
||||||
|
@ -19,219 +19,6 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uoq-UX-3fJ" userLabel="toolbar like view">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
||||||
<subviews>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DfA-eN-PyK" userLabel="box icon">
|
|
||||||
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="66" id="XZ0-7V-0w0"/>
|
|
||||||
<constraint firstAttribute="height" constant="66" id="a8F-hg-6gc"/>
|
|
||||||
<constraint firstAttribute="width" constant="180" id="sZf-gg-kCA"/>
|
|
||||||
</constraints>
|
|
||||||
<state key="normal" image="inbox-inactive@1x">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<state key="selected" image="inbox-active@1x"/>
|
|
||||||
<state key="highlighted" image="inbox-active@1x"/>
|
|
||||||
<variation key="default">
|
|
||||||
<mask key="constraints">
|
|
||||||
<exclude reference="XZ0-7V-0w0"/>
|
|
||||||
<exclude reference="a8F-hg-6gc"/>
|
|
||||||
<exclude reference="sZf-gg-kCA"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
<variation key="heightClass=regular-widthClass=compact">
|
|
||||||
<mask key="constraints">
|
|
||||||
<include reference="XZ0-7V-0w0"/>
|
|
||||||
<include reference="a8F-hg-6gc"/>
|
|
||||||
<exclude reference="sZf-gg-kCA"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
<connections>
|
|
||||||
<action selector="selectedInbox:" destination="MY2-bB-USa" eventType="touchUpInside" id="mFX-FS-Ofg"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WVY-Zl-dpP">
|
|
||||||
<rect key="frame" x="-23" y="-15" width="46" height="30"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="66" id="alU-LZ-piL"/>
|
|
||||||
<constraint firstAttribute="height" constant="66" id="mRu-04-FYf"/>
|
|
||||||
<constraint firstAttribute="width" constant="180" id="s5u-fl-v0s"/>
|
|
||||||
<constraint firstAttribute="height" constant="66" id="sc4-SD-Hae"/>
|
|
||||||
</constraints>
|
|
||||||
<state key="normal" image="archive-inactive@1x">
|
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</state>
|
|
||||||
<state key="selected" image="archive-active@1x"/>
|
|
||||||
<state key="highlighted" image="archive-active@1x"/>
|
|
||||||
<variation key="default">
|
|
||||||
<mask key="constraints">
|
|
||||||
<exclude reference="alU-LZ-piL"/>
|
|
||||||
<exclude reference="mRu-04-FYf"/>
|
|
||||||
<exclude reference="s5u-fl-v0s"/>
|
|
||||||
<exclude reference="sc4-SD-Hae"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
<variation key="heightClass=regular-widthClass=compact">
|
|
||||||
<mask key="constraints">
|
|
||||||
<include reference="alU-LZ-piL"/>
|
|
||||||
<exclude reference="mRu-04-FYf"/>
|
|
||||||
<exclude reference="s5u-fl-v0s"/>
|
|
||||||
<include reference="sc4-SD-Hae"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
<connections>
|
|
||||||
<action selector="selectedArchive:" destination="MY2-bB-USa" eventType="touchUpInside" id="Spp-Ns-lKG"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hSN-Ka-PzS" userLabel="Line">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
||||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<rect key="contentStretch" x="0.0" y="0.0" width="1" height="0.5"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" id="WuF-7s-PGe">
|
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="1"/>
|
|
||||||
</constraint>
|
|
||||||
</constraints>
|
|
||||||
<variation key="default">
|
|
||||||
<mask key="constraints">
|
|
||||||
<exclude reference="WuF-7s-PGe"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
<variation key="heightClass=regular-widthClass=compact">
|
|
||||||
<mask key="constraints">
|
|
||||||
<include reference="WuF-7s-PGe"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
</view>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="4" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GV1-fp-iPR">
|
|
||||||
<rect key="frame" x="0.0" y="-21" width="42" height="21"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="24" id="HGR-Rl-oe8"/>
|
|
||||||
<constraint firstAttribute="height" constant="21" id="lqu-cE-Dfh"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="15"/>
|
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
<variation key="default">
|
|
||||||
<mask key="constraints">
|
|
||||||
<exclude reference="HGR-Rl-oe8"/>
|
|
||||||
<exclude reference="lqu-cE-Dfh"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
<variation key="heightClass=regular-widthClass=compact">
|
|
||||||
<mask key="constraints">
|
|
||||||
<include reference="HGR-Rl-oe8"/>
|
|
||||||
<include reference="lqu-cE-Dfh"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
</label>
|
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q8M-tN-1ve">
|
|
||||||
<rect key="frame" x="20" y="60" width="400" height="1"/>
|
|
||||||
<color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<variation key="heightClass=regular" ambiguous="YES">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="0.0" height="0.0"/>
|
|
||||||
</variation>
|
|
||||||
</view>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="Q8M-tN-1ve" firstAttribute="bottom" secondItem="hSN-Ka-PzS" secondAttribute="bottom" id="2lB-4O-ZD9"/>
|
|
||||||
<constraint firstItem="WVY-Zl-dpP" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="uoq-UX-3fJ" secondAttribute="leading" constant="220" id="5YJ-Oq-Roj"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="hSN-Ka-PzS" secondAttribute="trailing" id="615-3N-9QN"/>
|
|
||||||
<constraint firstItem="WVY-Zl-dpP" firstAttribute="top" secondItem="uoq-UX-3fJ" secondAttribute="top" id="77j-Xx-EHO"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="WVY-Zl-dpP" secondAttribute="trailing" constant="66" id="8iQ-re-cvy"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="Q8M-tN-1ve" secondAttribute="bottom" constant="65" id="8x2-HZ-R58"/>
|
|
||||||
<constraint firstItem="Q8M-tN-1ve" firstAttribute="top" secondItem="DfA-eN-PyK" secondAttribute="top" id="99q-Q4-CHy"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="hSN-Ka-PzS" secondAttribute="centerX" id="AGV-i5-F3D"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="Q8M-tN-1ve" secondAttribute="trailing" constant="-40" id="BOJ-NL-FPg"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="WVY-Zl-dpP" secondAttribute="bottom" id="HWa-M6-gjL"/>
|
|
||||||
<constraint firstItem="Q8M-tN-1ve" firstAttribute="top" secondItem="uoq-UX-3fJ" secondAttribute="top" id="INk-NO-2j1"/>
|
|
||||||
<constraint firstItem="hSN-Ka-PzS" firstAttribute="top" secondItem="uoq-UX-3fJ" secondAttribute="top" id="Pq1-0y-L80"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="DfA-eN-PyK" secondAttribute="bottom" id="SJd-sZ-n13"/>
|
|
||||||
<constraint firstItem="DfA-eN-PyK" firstAttribute="centerX" secondItem="GV1-fp-iPR" secondAttribute="centerX" id="UgY-Jr-rPo"/>
|
|
||||||
<constraint firstItem="DfA-eN-PyK" firstAttribute="centerX" secondItem="GV1-fp-iPR" secondAttribute="centerX" id="WOe-oP-TIu"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="WVY-Zl-dpP" secondAttribute="trailing" id="YSd-C9-yEn"/>
|
|
||||||
<constraint firstItem="WVY-Zl-dpP" firstAttribute="leading" secondItem="uoq-UX-3fJ" secondAttribute="leading" constant="220" id="Ydg-FL-fwr"/>
|
|
||||||
<constraint firstItem="hSN-Ka-PzS" firstAttribute="leading" secondItem="uoq-UX-3fJ" secondAttribute="leading" id="cJB-rq-7bY"/>
|
|
||||||
<constraint firstItem="Q8M-tN-1ve" firstAttribute="leading" secondItem="hSN-Ka-PzS" secondAttribute="leading" id="eIX-uj-15n"/>
|
|
||||||
<constraint firstItem="DfA-eN-PyK" firstAttribute="top" secondItem="GV1-fp-iPR" secondAttribute="top" constant="-15" id="fp7-UH-t0O">
|
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="-21"/>
|
|
||||||
</constraint>
|
|
||||||
<constraint firstAttribute="height" constant="66" id="lM2-AA-dzm"/>
|
|
||||||
<constraint firstItem="DfA-eN-PyK" firstAttribute="top" secondItem="GV1-fp-iPR" secondAttribute="top" constant="-18" id="lZW-eB-ucq"/>
|
|
||||||
<constraint firstItem="DfA-eN-PyK" firstAttribute="leading" secondItem="uoq-UX-3fJ" secondAttribute="leading" constant="66" id="tIb-ee-zav"/>
|
|
||||||
</constraints>
|
|
||||||
<variation key="default">
|
|
||||||
<mask key="subviews">
|
|
||||||
<exclude reference="DfA-eN-PyK"/>
|
|
||||||
<exclude reference="WVY-Zl-dpP"/>
|
|
||||||
<exclude reference="hSN-Ka-PzS"/>
|
|
||||||
<exclude reference="GV1-fp-iPR"/>
|
|
||||||
<exclude reference="Q8M-tN-1ve"/>
|
|
||||||
</mask>
|
|
||||||
<mask key="constraints">
|
|
||||||
<exclude reference="lM2-AA-dzm"/>
|
|
||||||
<exclude reference="SJd-sZ-n13"/>
|
|
||||||
<exclude reference="UgY-Jr-rPo"/>
|
|
||||||
<exclude reference="WOe-oP-TIu"/>
|
|
||||||
<exclude reference="fp7-UH-t0O"/>
|
|
||||||
<exclude reference="lZW-eB-ucq"/>
|
|
||||||
<exclude reference="tIb-ee-zav"/>
|
|
||||||
<exclude reference="5YJ-Oq-Roj"/>
|
|
||||||
<exclude reference="77j-Xx-EHO"/>
|
|
||||||
<exclude reference="8iQ-re-cvy"/>
|
|
||||||
<exclude reference="HWa-M6-gjL"/>
|
|
||||||
<exclude reference="YSd-C9-yEn"/>
|
|
||||||
<exclude reference="Ydg-FL-fwr"/>
|
|
||||||
<exclude reference="2lB-4O-ZD9"/>
|
|
||||||
<exclude reference="8x2-HZ-R58"/>
|
|
||||||
<exclude reference="99q-Q4-CHy"/>
|
|
||||||
<exclude reference="BOJ-NL-FPg"/>
|
|
||||||
<exclude reference="INk-NO-2j1"/>
|
|
||||||
<exclude reference="eIX-uj-15n"/>
|
|
||||||
<exclude reference="615-3N-9QN"/>
|
|
||||||
<exclude reference="AGV-i5-F3D"/>
|
|
||||||
<exclude reference="Pq1-0y-L80"/>
|
|
||||||
<exclude reference="cJB-rq-7bY"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
<variation key="heightClass=regular-widthClass=compact">
|
|
||||||
<mask key="subviews">
|
|
||||||
<include reference="DfA-eN-PyK"/>
|
|
||||||
<include reference="WVY-Zl-dpP"/>
|
|
||||||
<include reference="hSN-Ka-PzS"/>
|
|
||||||
<include reference="GV1-fp-iPR"/>
|
|
||||||
<include reference="Q8M-tN-1ve"/>
|
|
||||||
</mask>
|
|
||||||
<mask key="constraints">
|
|
||||||
<include reference="lM2-AA-dzm"/>
|
|
||||||
<include reference="SJd-sZ-n13"/>
|
|
||||||
<exclude reference="UgY-Jr-rPo"/>
|
|
||||||
<include reference="WOe-oP-TIu"/>
|
|
||||||
<include reference="fp7-UH-t0O"/>
|
|
||||||
<exclude reference="lZW-eB-ucq"/>
|
|
||||||
<include reference="tIb-ee-zav"/>
|
|
||||||
<exclude reference="5YJ-Oq-Roj"/>
|
|
||||||
<include reference="77j-Xx-EHO"/>
|
|
||||||
<include reference="8iQ-re-cvy"/>
|
|
||||||
<exclude reference="HWa-M6-gjL"/>
|
|
||||||
<exclude reference="YSd-C9-yEn"/>
|
|
||||||
<exclude reference="Ydg-FL-fwr"/>
|
|
||||||
<include reference="2lB-4O-ZD9"/>
|
|
||||||
<exclude reference="8x2-HZ-R58"/>
|
|
||||||
<include reference="99q-Q4-CHy"/>
|
|
||||||
<include reference="BOJ-NL-FPg"/>
|
|
||||||
<exclude reference="INk-NO-2j1"/>
|
|
||||||
<include reference="eIX-uj-15n"/>
|
|
||||||
<include reference="615-3N-9QN"/>
|
|
||||||
<include reference="AGV-i5-F3D"/>
|
|
||||||
<include reference="Pq1-0y-L80"/>
|
|
||||||
<include reference="cJB-rq-7bY"/>
|
|
||||||
</mask>
|
|
||||||
</variation>
|
|
||||||
</view>
|
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lKc-rv-FH5" userLabel="empty state view">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lKc-rv-FH5" userLabel="empty state view">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
|
@ -261,7 +48,7 @@
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="centerX" secondItem="Srx-i1-WhD" secondAttribute="centerX" id="JId-fq-hNc"/>
|
<constraint firstAttribute="centerX" secondItem="Srx-i1-WhD" secondAttribute="centerX" id="JId-fq-hNc"/>
|
||||||
<constraint firstItem="Srx-i1-WhD" firstAttribute="top" secondItem="lKc-rv-FH5" secondAttribute="top" constant="240" id="uWX-dT-9XP"/>
|
<constraint firstAttribute="centerY" secondItem="Srx-i1-WhD" secondAttribute="centerY" constant="95" id="XST-YY-qXT"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<variation key="default">
|
<variation key="default">
|
||||||
<mask key="subviews">
|
<mask key="subviews">
|
||||||
|
@ -269,7 +56,7 @@
|
||||||
</mask>
|
</mask>
|
||||||
<mask key="constraints">
|
<mask key="constraints">
|
||||||
<exclude reference="JId-fq-hNc"/>
|
<exclude reference="JId-fq-hNc"/>
|
||||||
<exclude reference="uWX-dT-9XP"/>
|
<exclude reference="XST-YY-qXT"/>
|
||||||
</mask>
|
</mask>
|
||||||
</variation>
|
</variation>
|
||||||
<variation key="heightClass=regular-widthClass=compact">
|
<variation key="heightClass=regular-widthClass=compact">
|
||||||
|
@ -278,7 +65,7 @@
|
||||||
</mask>
|
</mask>
|
||||||
<mask key="constraints">
|
<mask key="constraints">
|
||||||
<include reference="JId-fq-hNc"/>
|
<include reference="JId-fq-hNc"/>
|
||||||
<include reference="uWX-dT-9XP"/>
|
<include reference="XST-YY-qXT"/>
|
||||||
</mask>
|
</mask>
|
||||||
</variation>
|
</variation>
|
||||||
</view>
|
</view>
|
||||||
|
@ -304,94 +91,63 @@
|
||||||
</tableView>
|
</tableView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="centerX" secondItem="uoq-UX-3fJ" secondAttribute="centerX" constant="-5" id="6gc-oZ-IMJ"/>
|
<constraint firstItem="PaA-ol-uQT" firstAttribute="leading" secondItem="lKc-rv-FH5" secondAttribute="leading" id="0co-lj-Jsm"/>
|
||||||
<constraint firstItem="7uh-gm-z8v" firstAttribute="top" secondItem="uoq-UX-3fJ" secondAttribute="bottom" id="7iL-hd-xP7"/>
|
|
||||||
<constraint firstAttribute="width" secondItem="uoq-UX-3fJ" secondAttribute="width" id="AP2-DE-zts"/>
|
|
||||||
<constraint firstAttribute="width" secondItem="lKc-rv-FH5" secondAttribute="width" id="Bu7-qv-yue"/>
|
<constraint firstAttribute="width" secondItem="lKc-rv-FH5" secondAttribute="width" id="Bu7-qv-yue"/>
|
||||||
<constraint firstAttribute="width" secondItem="lKc-rv-FH5" secondAttribute="width" id="EYc-tW-W2D">
|
<constraint firstAttribute="width" secondItem="lKc-rv-FH5" secondAttribute="width" id="EYc-tW-W2D">
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="0.0"/>
|
<variation key="heightClass=regular-widthClass=compact" constant="0.0"/>
|
||||||
</constraint>
|
</constraint>
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="PaA-ol-uQT" secondAttribute="trailing" constant="-16" id="EdI-ia-IjN">
|
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="-26"/>
|
|
||||||
</constraint>
|
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="uoq-UX-3fJ" secondAttribute="trailing" constant="-16" id="Fc5-tN-hro">
|
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="-16"/>
|
|
||||||
</constraint>
|
|
||||||
<constraint firstItem="7uh-gm-z8v" firstAttribute="top" secondItem="uoq-UX-3fJ" secondAttribute="bottom" id="GCa-EH-8Vh"/>
|
|
||||||
<constraint firstItem="lKc-rv-FH5" firstAttribute="top" secondItem="lZK-q4-iwt" secondAttribute="bottom" id="KiY-Ag-0iP"/>
|
<constraint firstItem="lKc-rv-FH5" firstAttribute="top" secondItem="lZK-q4-iwt" secondAttribute="bottom" id="KiY-Ag-0iP"/>
|
||||||
<constraint firstItem="uoq-UX-3fJ" firstAttribute="leading" secondItem="EFA-Fu-XJm" secondAttribute="leadingMargin" constant="-16" id="La3-rh-BpY"/>
|
|
||||||
<constraint firstItem="PaA-ol-uQT" firstAttribute="leading" secondItem="EFA-Fu-XJm" secondAttribute="leadingMargin" constant="-16" id="OD6-Pc-Zug"/>
|
<constraint firstItem="PaA-ol-uQT" firstAttribute="leading" secondItem="EFA-Fu-XJm" secondAttribute="leadingMargin" constant="-16" id="OD6-Pc-Zug"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="uoq-UX-3fJ" secondAttribute="centerX" id="fEl-Ut-x0g"/>
|
<constraint firstItem="lKc-rv-FH5" firstAttribute="centerY" secondItem="PaA-ol-uQT" secondAttribute="centerY" id="OOk-XM-IMs"/>
|
||||||
<constraint firstItem="7uh-gm-z8v" firstAttribute="top" secondItem="lKc-rv-FH5" secondAttribute="bottom" constant="66" id="lCx-f0-NYv"/>
|
<constraint firstAttribute="trailingMargin" secondItem="PaA-ol-uQT" secondAttribute="trailing" constant="-26" id="ZkG-Yf-ISG"/>
|
||||||
|
<constraint firstItem="PaA-ol-uQT" firstAttribute="top" secondItem="lKc-rv-FH5" secondAttribute="top" id="gdn-tV-9au"/>
|
||||||
|
<constraint firstItem="PaA-ol-uQT" firstAttribute="bottom" secondItem="7uh-gm-z8v" secondAttribute="top" id="jLN-Fv-npv"/>
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="lKc-rv-FH5" secondAttribute="trailing" constant="-26" id="luy-6c-SFS">
|
<constraint firstAttribute="trailingMargin" secondItem="lKc-rv-FH5" secondAttribute="trailing" constant="-26" id="luy-6c-SFS">
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="-10"/>
|
<variation key="heightClass=regular-widthClass=compact" constant="-10"/>
|
||||||
</constraint>
|
</constraint>
|
||||||
|
<constraint firstAttribute="trailingMargin" secondItem="PaA-ol-uQT" secondAttribute="trailing" constant="-26" id="mrL-SK-eKx"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="lKc-rv-FH5" secondAttribute="centerX" constant="-5" id="obF-St-qwu">
|
<constraint firstAttribute="centerX" secondItem="lKc-rv-FH5" secondAttribute="centerX" constant="-5" id="obF-St-qwu">
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="0.0"/>
|
<variation key="heightClass=regular-widthClass=compact" constant="0.0"/>
|
||||||
</constraint>
|
</constraint>
|
||||||
<constraint firstItem="PaA-ol-uQT" firstAttribute="top" secondItem="lZK-q4-iwt" secondAttribute="bottom" id="ouV-vM-Vyv">
|
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="0.0"/>
|
|
||||||
</constraint>
|
|
||||||
<constraint firstItem="7uh-gm-z8v" firstAttribute="top" secondItem="PaA-ol-uQT" secondAttribute="bottom" constant="66" id="s5v-Hl-a3k"/>
|
|
||||||
<constraint firstItem="PaA-ol-uQT" firstAttribute="width" secondItem="EFA-Fu-XJm" secondAttribute="width" id="wn4-O9-ILm">
|
|
||||||
<variation key="heightClass=regular-widthClass=compact" constant="10"/>
|
|
||||||
</constraint>
|
|
||||||
<constraint firstItem="uoq-UX-3fJ" firstAttribute="top" secondItem="lZK-q4-iwt" secondAttribute="bottom" constant="-1" id="xlM-od-Zuu"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
<variation key="default">
|
<variation key="default">
|
||||||
<mask key="subviews">
|
<mask key="subviews">
|
||||||
<exclude reference="uoq-UX-3fJ"/>
|
|
||||||
<exclude reference="lKc-rv-FH5"/>
|
<exclude reference="lKc-rv-FH5"/>
|
||||||
<exclude reference="PaA-ol-uQT"/>
|
<exclude reference="PaA-ol-uQT"/>
|
||||||
</mask>
|
</mask>
|
||||||
<mask key="constraints">
|
<mask key="constraints">
|
||||||
<exclude reference="7iL-hd-xP7"/>
|
<exclude reference="0co-lj-Jsm"/>
|
||||||
<exclude reference="GCa-EH-8Vh"/>
|
|
||||||
<exclude reference="lCx-f0-NYv"/>
|
|
||||||
<exclude reference="s5v-Hl-a3k"/>
|
|
||||||
<exclude reference="EdI-ia-IjN"/>
|
|
||||||
<exclude reference="OD6-Pc-Zug"/>
|
<exclude reference="OD6-Pc-Zug"/>
|
||||||
<exclude reference="ouV-vM-Vyv"/>
|
<exclude reference="ZkG-Yf-ISG"/>
|
||||||
<exclude reference="wn4-O9-ILm"/>
|
<exclude reference="gdn-tV-9au"/>
|
||||||
|
<exclude reference="jLN-Fv-npv"/>
|
||||||
|
<exclude reference="mrL-SK-eKx"/>
|
||||||
<exclude reference="Bu7-qv-yue"/>
|
<exclude reference="Bu7-qv-yue"/>
|
||||||
<exclude reference="EYc-tW-W2D"/>
|
<exclude reference="EYc-tW-W2D"/>
|
||||||
<exclude reference="KiY-Ag-0iP"/>
|
<exclude reference="KiY-Ag-0iP"/>
|
||||||
|
<exclude reference="OOk-XM-IMs"/>
|
||||||
<exclude reference="luy-6c-SFS"/>
|
<exclude reference="luy-6c-SFS"/>
|
||||||
<exclude reference="obF-St-qwu"/>
|
<exclude reference="obF-St-qwu"/>
|
||||||
<exclude reference="6gc-oZ-IMJ"/>
|
|
||||||
<exclude reference="AP2-DE-zts"/>
|
|
||||||
<exclude reference="Fc5-tN-hro"/>
|
|
||||||
<exclude reference="La3-rh-BpY"/>
|
|
||||||
<exclude reference="fEl-Ut-x0g"/>
|
|
||||||
<exclude reference="xlM-od-Zuu"/>
|
|
||||||
</mask>
|
</mask>
|
||||||
</variation>
|
</variation>
|
||||||
<variation key="heightClass=regular-widthClass=compact">
|
<variation key="heightClass=regular-widthClass=compact">
|
||||||
<mask key="subviews">
|
<mask key="subviews">
|
||||||
<include reference="uoq-UX-3fJ"/>
|
|
||||||
<include reference="lKc-rv-FH5"/>
|
<include reference="lKc-rv-FH5"/>
|
||||||
<include reference="PaA-ol-uQT"/>
|
<include reference="PaA-ol-uQT"/>
|
||||||
</mask>
|
</mask>
|
||||||
<mask key="constraints">
|
<mask key="constraints">
|
||||||
<include reference="7iL-hd-xP7"/>
|
<include reference="0co-lj-Jsm"/>
|
||||||
<exclude reference="GCa-EH-8Vh"/>
|
|
||||||
<include reference="lCx-f0-NYv"/>
|
|
||||||
<include reference="s5v-Hl-a3k"/>
|
|
||||||
<include reference="EdI-ia-IjN"/>
|
|
||||||
<exclude reference="OD6-Pc-Zug"/>
|
<exclude reference="OD6-Pc-Zug"/>
|
||||||
<include reference="ouV-vM-Vyv"/>
|
<include reference="ZkG-Yf-ISG"/>
|
||||||
<include reference="wn4-O9-ILm"/>
|
<include reference="gdn-tV-9au"/>
|
||||||
|
<include reference="jLN-Fv-npv"/>
|
||||||
|
<include reference="mrL-SK-eKx"/>
|
||||||
<include reference="Bu7-qv-yue"/>
|
<include reference="Bu7-qv-yue"/>
|
||||||
<exclude reference="EYc-tW-W2D"/>
|
<exclude reference="EYc-tW-W2D"/>
|
||||||
<include reference="KiY-Ag-0iP"/>
|
<include reference="KiY-Ag-0iP"/>
|
||||||
|
<include reference="OOk-XM-IMs"/>
|
||||||
<exclude reference="luy-6c-SFS"/>
|
<exclude reference="luy-6c-SFS"/>
|
||||||
<include reference="obF-St-qwu"/>
|
<include reference="obF-St-qwu"/>
|
||||||
<exclude reference="6gc-oZ-IMJ"/>
|
|
||||||
<include reference="AP2-DE-zts"/>
|
|
||||||
<exclude reference="Fc5-tN-hro"/>
|
|
||||||
<exclude reference="La3-rh-BpY"/>
|
|
||||||
<include reference="fEl-Ut-x0g"/>
|
|
||||||
<exclude reference="xlM-od-Zuu"/>
|
|
||||||
</mask>
|
</mask>
|
||||||
</variation>
|
</variation>
|
||||||
</view>
|
</view>
|
||||||
|
@ -413,10 +169,7 @@
|
||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="archiveButton" destination="WVY-Zl-dpP" id="IdE-Kz-1r0"/>
|
|
||||||
<outlet property="emptyBoxLabel" destination="Srx-i1-WhD" id="wap-un-Cz5"/>
|
<outlet property="emptyBoxLabel" destination="Srx-i1-WhD" id="wap-un-Cz5"/>
|
||||||
<outlet property="inboxButton" destination="DfA-eN-PyK" id="p0D-Qj-YzC"/>
|
|
||||||
<outlet property="inboxCountLabel" destination="GV1-fp-iPR" id="MHq-Gs-bgt"/>
|
|
||||||
<outlet property="tableView" destination="PaA-ol-uQT" id="nQU-tR-wbL"/>
|
<outlet property="tableView" destination="PaA-ol-uQT" id="nQU-tR-wbL"/>
|
||||||
<segue destination="Duq-aU-MmN" kind="presentation" identifier="2.0_6.0_Call_Segue" id="gHJ-y4-zWg"/>
|
<segue destination="Duq-aU-MmN" kind="presentation" identifier="2.0_6.0_Call_Segue" id="gHJ-y4-zWg"/>
|
||||||
<segue destination="lIF-0m-2N3" kind="presentation" identifier="showSignupFlow" id="DR8-fx-0PD"/>
|
<segue destination="lIF-0m-2N3" kind="presentation" identifier="showSignupFlow" id="DR8-fx-0PD"/>
|
||||||
|
@ -4798,6 +4551,9 @@ A0 09 9A FF A8 8A 09 99</string>
|
||||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||||
<color key="textColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
|
<variation key="heightClass=regular-widthClass=compact" misplaced="YES">
|
||||||
|
<rect key="frame" x="10" y="274" width="130" height="21"/>
|
||||||
|
</variation>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
@ -4950,8 +4706,6 @@ A0 09 9A FF A8 8A 09 99</string>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="_arrow_button" width="12" height="23"/>
|
<image name="_arrow_button" width="12" height="23"/>
|
||||||
<image name="add-conversation" width="44" height="44"/>
|
<image name="add-conversation" width="44" height="44"/>
|
||||||
<image name="archive-active@1x" width="66" height="66"/>
|
|
||||||
<image name="archive-inactive@1x" width="66" height="66"/>
|
|
||||||
<image name="btnCamera--white" width="52" height="40"/>
|
<image name="btnCamera--white" width="52" height="40"/>
|
||||||
<image name="btnCancel--white" width="44" height="44"/>
|
<image name="btnCancel--white" width="44" height="44"/>
|
||||||
<image name="btnGroup--white" width="44" height="44"/>
|
<image name="btnGroup--white" width="44" height="44"/>
|
||||||
|
@ -4962,8 +4716,6 @@ A0 09 9A FF A8 8A 09 99</string>
|
||||||
<image name="contact-options-action" width="44" height="44"/>
|
<image name="contact-options-action" width="44" height="44"/>
|
||||||
<image name="empty-group-avatar" width="53" height="53"/>
|
<image name="empty-group-avatar" width="53" height="53"/>
|
||||||
<image name="endcall.png" width="100" height="100"/>
|
<image name="endcall.png" width="100" height="100"/>
|
||||||
<image name="inbox-active@1x" width="66" height="66"/>
|
|
||||||
<image name="inbox-inactive@1x" width="66" height="66"/>
|
|
||||||
<image name="logoSignal" width="138" height="139"/>
|
<image name="logoSignal" width="138" height="139"/>
|
||||||
<image name="mute-active" width="80" height="80"/>
|
<image name="mute-active" width="80" height="80"/>
|
||||||
<image name="mute-inactive" width="80" height="80"/>
|
<image name="mute-inactive" width="80" height="80"/>
|
||||||
|
@ -4973,8 +4725,8 @@ A0 09 9A FF A8 8A 09 99</string>
|
||||||
<image name="speaker-inactive" width="80" height="80"/>
|
<image name="speaker-inactive" width="80" height="80"/>
|
||||||
</resources>
|
</resources>
|
||||||
<inferredMetricsTieBreakers>
|
<inferredMetricsTieBreakers>
|
||||||
<segue reference="D0d-4f-lcI"/>
|
<segue reference="DR8-fx-0PD"/>
|
||||||
<segue reference="ZcV-Ck-baL"/>
|
|
||||||
<segue reference="xo7-5J-BJb"/>
|
<segue reference="xo7-5J-BJb"/>
|
||||||
|
<segue reference="D0d-4f-lcI"/>
|
||||||
</inferredMetricsTieBreakers>
|
</inferredMetricsTieBreakers>
|
||||||
</document>
|
</document>
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
#import "FunctionalUtil.h"
|
#import "FunctionalUtil.h"
|
||||||
#import "ObservableValue.h"
|
#import "ObservableValue.h"
|
||||||
#import "PreferencesUtil.h"
|
#import "PreferencesUtil.h"
|
||||||
|
#import "PushManager.h"
|
||||||
#import "NSDate+millisecondTimeStamp.h"
|
#import "NSDate+millisecondTimeStamp.h"
|
||||||
#import "TSCall.h"
|
#import "TSCall.h"
|
||||||
#import "TSStorageManager.h"
|
|
||||||
#import "TSContactThread.h"
|
#import "TSContactThread.h"
|
||||||
|
#import "TSMessagesManager.h"
|
||||||
|
#import "TSStorageManager.h"
|
||||||
|
|
||||||
@interface RecentCallManager ()
|
@interface RecentCallManager ()
|
||||||
@property YapDatabaseConnection *dbConnection;
|
@property YapDatabaseConnection *dbConnection;
|
||||||
|
@ -41,7 +42,8 @@
|
||||||
|
|
||||||
[call.futureTermination finallyDo:^(TOCFuture* interactionCompletion) {
|
[call.futureTermination finallyDo:^(TOCFuture* interactionCompletion) {
|
||||||
bool isOutgoingCall = call.initiatedLocally;
|
bool isOutgoingCall = call.initiatedLocally;
|
||||||
bool isMissedCall = interactionCompletion.hasFailed;
|
bool isMissedCall = [self isMissedCall:interactionCompletion];
|
||||||
|
|
||||||
Contact* contact = [self tryGetContactForCall:call];
|
Contact* contact = [self tryGetContactForCall:call];
|
||||||
|
|
||||||
RPRecentCallType callType = isOutgoingCall ? RPRecentCallTypeOutgoing
|
RPRecentCallType callType = isOutgoingCall ? RPRecentCallTypeOutgoing
|
||||||
|
@ -54,6 +56,18 @@
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)isMissedCall:(TOCFuture*)interactionCompletion {
|
||||||
|
if ([interactionCompletion hasResult]) {
|
||||||
|
if ([[interactionCompletion forceGetResult] isKindOfClass:[CallTermination class]]) {
|
||||||
|
CallTermination *termination = (CallTermination*)interactionCompletion.forceGetResult;
|
||||||
|
if (termination.type == CallTerminationType_HangupRemote) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
- (Contact*)tryGetContactForCall:(CallState*)call {
|
- (Contact*)tryGetContactForCall:(CallState*)call {
|
||||||
if (call.potentiallySpecifiedContact != nil) return call.potentiallySpecifiedContact;
|
if (call.potentiallySpecifiedContact != nil) return call.potentiallySpecifiedContact;
|
||||||
return [self tryGetContactForNumber:call.remoteNumber];
|
return [self tryGetContactForNumber:call.remoteNumber];
|
||||||
|
@ -82,7 +96,10 @@
|
||||||
NSDate *date = [NSDate dateWithTimeIntervalSince1970:(callDateSeconds+60)]; // archive has to happen in the future of the original call
|
NSDate *date = [NSDate dateWithTimeIntervalSince1970:(callDateSeconds+60)]; // archive has to happen in the future of the original call
|
||||||
[thread archiveThreadWithTransaction:transaction referenceDate:date];
|
[thread archiveThreadWithTransaction:transaction referenceDate:date];
|
||||||
}
|
}
|
||||||
|
|
||||||
[call saveWithTransaction:transaction];
|
[call saveWithTransaction:transaction];
|
||||||
|
|
||||||
|
[[TSMessagesManager sharedManager] notifyUserForCall:call inThread:thread];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#import "HostNameEndPoint.h"
|
#import "HostNameEndPoint.h"
|
||||||
#import "RecentCallManager.h"
|
#import "RecentCallManager.h"
|
||||||
#import "ContactsManager.h"
|
#import "ContactsManager.h"
|
||||||
|
#import "MessagesViewController.h"
|
||||||
#import "PreferencesUtil.h"
|
#import "PreferencesUtil.h"
|
||||||
#import "PhoneNumberDirectoryFilterManager.h"
|
#import "PhoneNumberDirectoryFilterManager.h"
|
||||||
#import "SignalKeyingStorage.h"
|
#import "SignalKeyingStorage.h"
|
||||||
|
@ -197,6 +198,17 @@ phoneDirectoryManager;
|
||||||
if ([thread isGroupThread]) {
|
if ([thread isGroupThread]) {
|
||||||
[self messageGroup:(TSGroupThread*)thread];
|
[self messageGroup:(TSGroupThread*)thread];
|
||||||
} else {
|
} else {
|
||||||
|
Environment *env = [self getCurrent];
|
||||||
|
SignalsViewController *vc = env.signalsViewController;
|
||||||
|
UIViewController *topvc = vc.navigationController.topViewController;
|
||||||
|
|
||||||
|
if ([topvc isKindOfClass:[MessagesViewController class]]) {
|
||||||
|
MessagesViewController *mvc = (MessagesViewController*)topvc;
|
||||||
|
if ([mvc.thread.uniqueId isEqualToString:threadId]) {
|
||||||
|
[mvc popKeyBoard];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
[self messageIdentifier:((TSContactThread*)thread).contactIdentifier withCompose:YES];
|
[self messageIdentifier:((TSContactThread*)thread).contactIdentifier withCompose:YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +221,7 @@ phoneDirectoryManager;
|
||||||
[vc.presentedViewController dismissViewControllerAnimated:YES completion:nil];
|
[vc.presentedViewController dismissViewControllerAnimated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
[vc.navigationController popToRootViewControllerAnimated:YES];
|
[vc.navigationController popToRootViewControllerAnimated:NO];
|
||||||
vc.contactIdentifierFromCompose = identifier;
|
vc.contactIdentifierFromCompose = identifier;
|
||||||
vc.composeMessage = compose;
|
vc.composeMessage = compose;
|
||||||
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
||||||
|
@ -223,7 +235,7 @@ phoneDirectoryManager;
|
||||||
[vc.presentedViewController dismissViewControllerAnimated:YES completion:nil];
|
[vc.presentedViewController dismissViewControllerAnimated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
[vc.navigationController popToRootViewControllerAnimated:YES];
|
[vc.navigationController popToRootViewControllerAnimated:NO];
|
||||||
[vc performSegueWithIdentifier:@"showSegue" sender:groupThread];
|
[vc performSegueWithIdentifier:@"showSegue" sender:groupThread];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +247,7 @@ phoneDirectoryManager;
|
||||||
[vc.presentedViewController dismissViewControllerAnimated:YES completion:nil];
|
[vc.presentedViewController dismissViewControllerAnimated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
[vc.navigationController popToRootViewControllerAnimated:YES];
|
[vc.navigationController popToRootViewControllerAnimated:NO];
|
||||||
vc.groupFromCompose = model;
|
vc.groupFromCompose = model;
|
||||||
vc.composeMessage = compose;
|
vc.composeMessage = compose;
|
||||||
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
[vc performSegueWithIdentifier:@"showSegue" sender:nil];
|
||||||
|
|
|
@ -257,6 +257,7 @@
|
||||||
|
|
||||||
[[PushManager sharedManager] requestPushTokenWithSuccess:^(NSData *pushToken, NSData *voipToken) {
|
[[PushManager sharedManager] requestPushTokenWithSuccess:^(NSData *pushToken, NSData *voipToken) {
|
||||||
[TSAccountManager registerForPushNotifications:pushToken voipToken:voipToken success:^{
|
[TSAccountManager registerForPushNotifications:pushToken voipToken:voipToken success:^{
|
||||||
|
[UIApplication.sharedApplication setNetworkActivityIndicatorVisible:NO];
|
||||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:NEEDS_TO_REGISTER_PUSH_KEY];
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:NEEDS_TO_REGISTER_PUSH_KEY];
|
||||||
[waitingController dismissViewControllerAnimated:YES completion:nil];
|
[waitingController dismissViewControllerAnimated:YES completion:nil];
|
||||||
} failure:failure];
|
} failure:failure];
|
||||||
|
|
|
@ -10,12 +10,16 @@
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#define Signal_Thread_UserInfo_Key @"Signal_Thread_Id"
|
#define Signal_Thread_UserInfo_Key @"Signal_Thread_Id"
|
||||||
|
#define Signal_Call_UserInfo_Key @"Signal_Call_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"
|
||||||
|
|
||||||
|
#define Signal_CallBack_Identifier @"Signal_CallBack"
|
||||||
|
|
||||||
#define Signal_Call_Category @"Signal_IncomingCall"
|
#define Signal_Call_Category @"Signal_IncomingCall"
|
||||||
#define Signal_Message_Category @"Signal_Message"
|
#define Signal_Message_Category @"Signal_Message"
|
||||||
|
#define Signal_CallBack_Category @"Signal_CallBack"
|
||||||
|
|
||||||
#define Signal_Message_View_Identifier @"Signal_Message_Read"
|
#define Signal_Message_View_Identifier @"Signal_Message_Read"
|
||||||
#define Signal_Message_MarkAsRead_Identifier @"Signal_Message_MarkAsRead"
|
#define Signal_Message_MarkAsRead_Identifier @"Signal_Message_MarkAsRead"
|
||||||
|
@ -66,6 +70,7 @@ typedef void (^registrationTokensSuccessBlock)(NSData *pushToken, NSData *voipTo
|
||||||
|
|
||||||
-(TOCFuture*)registerPushKitNotificationFuture;
|
-(TOCFuture*)registerPushKitNotificationFuture;
|
||||||
- (BOOL)supportsVOIPPush;
|
- (BOOL)supportsVOIPPush;
|
||||||
|
- (UILocalNotification*)closeVOIPBackgroundTask;
|
||||||
|
|
||||||
#pragma mark Push Notifications Delegate Methods
|
#pragma mark Push Notifications Delegate Methods
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#import "PreferencesUtil.h"
|
#import "PreferencesUtil.h"
|
||||||
#import "PushManager.h"
|
#import "PushManager.h"
|
||||||
#import "Environment.h"
|
#import "Environment.h"
|
||||||
|
#import "PreferencesUtil.h"
|
||||||
#import "RPServerRequestsManager.h"
|
#import "RPServerRequestsManager.h"
|
||||||
#import "TSAccountManager.h"
|
#import "TSAccountManager.h"
|
||||||
#import "TSSocketManager.h"
|
#import "TSSocketManager.h"
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
@property TOCFutureSource *registerWithServerFutureSource;
|
@property TOCFutureSource *registerWithServerFutureSource;
|
||||||
@property UIAlertView *missingPermissionsAlertView;
|
@property UIAlertView *missingPermissionsAlertView;
|
||||||
@property (nonatomic, strong) NotificationTracker *notificationTracker;
|
@property (nonatomic, strong) NotificationTracker *notificationTracker;
|
||||||
|
@property UILocalNotification *lastCallNotification;
|
||||||
|
|
||||||
@property (nonatomic) UIBackgroundTaskIdentifier callBackgroundTask;
|
@property (nonatomic) UIBackgroundTaskIdentifier callBackgroundTask;
|
||||||
@end
|
@end
|
||||||
|
@ -53,6 +55,7 @@
|
||||||
delegate:nil
|
delegate:nil
|
||||||
cancelButtonTitle:NSLocalizedString(@"OK", @"")
|
cancelButtonTitle:NSLocalizedString(@"OK", @"")
|
||||||
otherButtonTitles:nil, nil];
|
otherButtonTitles:nil, nil];
|
||||||
|
_callBackgroundTask = UIBackgroundTaskInvalid;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +63,6 @@
|
||||||
#pragma mark Manage Incoming Push
|
#pragma mark Manage Incoming Push
|
||||||
|
|
||||||
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
|
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
|
||||||
|
|
||||||
if ([self isRedPhonePush:userInfo]) {
|
if ([self isRedPhonePush:userInfo]) {
|
||||||
ResponderSessionDescriptor* call;
|
ResponderSessionDescriptor* call;
|
||||||
if (![self.notificationTracker shouldProcessNotification:userInfo]){
|
if (![self.notificationTracker shouldProcessNotification:userInfo]){
|
||||||
|
@ -82,35 +84,51 @@
|
||||||
|
|
||||||
[Environment.phoneManager incomingCallWithSession:call];
|
[Environment.phoneManager incomingCallWithSession:call];
|
||||||
|
|
||||||
|
|
||||||
if (![self applicationIsActive]) {
|
if (![self applicationIsActive]) {
|
||||||
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
||||||
|
|
||||||
NSString *callerId = call.initiatorNumber.toE164;
|
NSString *callerId = call.initiatorNumber.toE164;
|
||||||
NSString *nameString = [[Environment getCurrent].contactsManager nameStringForPhoneIdentifier:callerId];
|
NSString *nameString = [[Environment getCurrent].contactsManager nameStringForPhoneIdentifier:callerId];
|
||||||
|
|
||||||
NSString *displayName = nameString?nameString:callerId;
|
NSString *displayName = nameString?nameString:callerId;
|
||||||
|
PropertyListPreferences *prefs = [Environment preferences];
|
||||||
|
|
||||||
|
if ([prefs notificationPreviewType] == NotificationNoNameNoPreview) {
|
||||||
|
notification.alertBody = NSLocalizedString(@"INCOMING_CALL", nil);
|
||||||
|
} else {
|
||||||
|
notification.alertBody = [NSString stringWithFormat:NSLocalizedString(@"INCOMING_CALL_FROM", nil), displayName];
|
||||||
|
}
|
||||||
|
|
||||||
notification.alertBody = [NSString stringWithFormat:@"Incoming call from %@", displayName];
|
|
||||||
notification.category = Signal_Call_Category;
|
notification.category = Signal_Call_Category;
|
||||||
notification.soundName = @"r.caf";
|
notification.soundName = @"r.caf";
|
||||||
|
|
||||||
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
||||||
|
_lastCallNotification = notification;
|
||||||
|
|
||||||
if (_callBackgroundTask == 0) {
|
if (_callBackgroundTask == UIBackgroundTaskInvalid) {
|
||||||
_callBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
_callBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||||
_callBackgroundTask = 0;
|
[Environment.phoneManager backgroundTimeExpired];
|
||||||
[Environment.phoneManager hangupOrDenyCall];
|
[self closeVOIPBackgroundTask];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (![self applicationIsActive]) {
|
if (![self applicationIsActive]) {
|
||||||
[TSSocketManager becomeActiveFromBackground];
|
[TSSocketManager becomeActiveFromBackgroundExpectMessage:YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UILocalNotification*)closeVOIPBackgroundTask {
|
||||||
|
[[UIApplication sharedApplication] endBackgroundTask:_callBackgroundTask];
|
||||||
|
_callBackgroundTask = UIBackgroundTaskInvalid;
|
||||||
|
|
||||||
|
UILocalNotification *notif = _lastCallNotification;
|
||||||
|
_lastCallNotification = nil;
|
||||||
|
|
||||||
|
return notif;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
* 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
|
||||||
*
|
*
|
||||||
|
@ -147,6 +165,11 @@
|
||||||
dispatch_get_main_queue(), ^{
|
dispatch_get_main_queue(), ^{
|
||||||
completionHandler();
|
completionHandler();
|
||||||
});
|
});
|
||||||
|
} else if([identifier isEqualToString:Signal_CallBack_Identifier]){
|
||||||
|
NSString * contactId = [notification.userInfo objectForKeyedSubscript:Signal_Call_UserInfo_Key];
|
||||||
|
PhoneNumber *number = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:contactId];
|
||||||
|
Contact *contact = [[Environment.getCurrent contactsManager] latestContactForPhoneNumber:number];
|
||||||
|
[Environment.phoneManager initiateOutgoingCallToContact:contact atRemoteNumber:number];
|
||||||
} else{
|
} else{
|
||||||
NSString *threadId = [notification.userInfo objectForKey:Signal_Thread_UserInfo_Key];
|
NSString *threadId = [notification.userInfo objectForKey:Signal_Thread_UserInfo_Key];
|
||||||
[Environment messageThreadId:threadId];
|
[Environment messageThreadId:threadId];
|
||||||
|
@ -294,7 +317,9 @@
|
||||||
|
|
||||||
UIUserNotificationSettings *settings =
|
UIUserNotificationSettings *settings =
|
||||||
[UIUserNotificationSettings settingsForTypes:(UIUserNotificationType)[self allNotificationTypes]
|
[UIUserNotificationSettings settingsForTypes:(UIUserNotificationType)[self allNotificationTypes]
|
||||||
categories:[NSSet setWithObjects:[self userNotificationsCallCategory], [self userNotificationsMessageCategory], nil]];
|
categories:[NSSet setWithObjects:[self userNotificationsCallCategory],
|
||||||
|
[self userNotificationsMessageCategory],
|
||||||
|
[self userNotificationsCallBackCategory], nil]];
|
||||||
|
|
||||||
[UIApplication.sharedApplication registerUserNotificationSettings:settings];
|
[UIApplication.sharedApplication registerUserNotificationSettings:settings];
|
||||||
return self.userNotificationFutureSource.future;
|
return self.userNotificationFutureSource.future;
|
||||||
|
@ -303,7 +328,7 @@
|
||||||
- (UIUserNotificationCategory*)userNotificationsMessageCategory{
|
- (UIUserNotificationCategory*)userNotificationsMessageCategory{
|
||||||
UIMutableUserNotificationAction *action_view = [UIMutableUserNotificationAction new];
|
UIMutableUserNotificationAction *action_view = [UIMutableUserNotificationAction new];
|
||||||
action_view.identifier = Signal_Message_View_Identifier;
|
action_view.identifier = Signal_Message_View_Identifier;
|
||||||
action_view.title = NSLocalizedString(@"View", @"");
|
action_view.title = NSLocalizedString(@"PUSH_MANAGER_VIEW", @"");
|
||||||
action_view.activationMode = UIUserNotificationActivationModeForeground;
|
action_view.activationMode = UIUserNotificationActivationModeForeground;
|
||||||
action_view.destructive = NO;
|
action_view.destructive = NO;
|
||||||
action_view.authenticationRequired = YES;
|
action_view.authenticationRequired = YES;
|
||||||
|
@ -339,6 +364,22 @@
|
||||||
return callCategory;
|
return callCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIUserNotificationCategory*)userNotificationsCallBackCategory{
|
||||||
|
UIMutableUserNotificationAction *action_accept = [UIMutableUserNotificationAction new];
|
||||||
|
action_accept.identifier = Signal_CallBack_Identifier;
|
||||||
|
action_accept.title = NSLocalizedString(@"CALLBACK_BUTTON_TITLE", @"");
|
||||||
|
action_accept.activationMode = UIUserNotificationActivationModeForeground;
|
||||||
|
action_accept.destructive = NO;
|
||||||
|
action_accept.authenticationRequired = NO;
|
||||||
|
|
||||||
|
UIMutableUserNotificationCategory *callCategory = [UIMutableUserNotificationCategory new];
|
||||||
|
callCategory.identifier = Signal_CallBack_Category;
|
||||||
|
[callCategory setActions:@[action_accept] forContext:UIUserNotificationActionContextMinimal];
|
||||||
|
[callCategory setActions:@[action_accept] forContext:UIUserNotificationActionContextDefault];
|
||||||
|
|
||||||
|
return callCategory;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)needToRegisterForRemoteNotifications
|
- (BOOL)needToRegisterForRemoteNotifications
|
||||||
{
|
{
|
||||||
return self.wantRemoteNotifications && (!UIApplication.sharedApplication.isRegisteredForRemoteNotifications);
|
return self.wantRemoteNotifications && (!UIApplication.sharedApplication.isRegisteredForRemoteNotifications);
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
-(void) hangupOrDenyCall;
|
-(void) hangupOrDenyCall;
|
||||||
-(void) answerCall;
|
-(void) answerCall;
|
||||||
-(BOOL) toggleMute;
|
-(BOOL) toggleMute;
|
||||||
|
-(void) backgroundTimeExpired;
|
||||||
|
|
||||||
-(ObservableValue*) currentCallObservable;
|
-(ObservableValue*) currentCallObservable;
|
||||||
|
|
||||||
+(PhoneManager*) phoneManagerWithErrorHandler:(ErrorHandlerBlock)errorHandler;
|
+(PhoneManager*) phoneManagerWithErrorHandler:(ErrorHandlerBlock)errorHandler;
|
||||||
|
|
|
@ -135,13 +135,19 @@
|
||||||
-(CallController*) curCallController {
|
-(CallController*) curCallController {
|
||||||
return currentCallControllerObservable.currentValue;
|
return currentCallControllerObservable.currentValue;
|
||||||
}
|
}
|
||||||
-(void) answerCall {
|
|
||||||
|
-(void)answerCall {
|
||||||
[[self curCallController] acceptCall];
|
[[self curCallController] acceptCall];
|
||||||
}
|
}
|
||||||
-(void) hangupOrDenyCall {
|
|
||||||
|
- (void)hangupOrDenyCall {
|
||||||
[[self curCallController] hangupOrDenyCall];
|
[[self curCallController] hangupOrDenyCall];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)backgroundTimeExpired {
|
||||||
|
[[self curCallController] backgroundTimeExpired];
|
||||||
|
}
|
||||||
|
|
||||||
-(BOOL) toggleMute{
|
-(BOOL) toggleMute{
|
||||||
return [self.curCallController toggleMute];
|
return [self.curCallController toggleMute];
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
-(void)advanceCallProgressTo:(enum CallProgressType)type;
|
-(void)advanceCallProgressTo:(enum CallProgressType)type;
|
||||||
-(void)hangupOrDenyCall;
|
-(void)hangupOrDenyCall;
|
||||||
-(void)acceptCall;
|
-(void)acceptCall;
|
||||||
|
- (void)backgroundTimeExpired;
|
||||||
-(void)advanceCallProgressToConversingWithShortAuthenticationString:(NSString*)sas;
|
-(void)advanceCallProgressToConversingWithShortAuthenticationString:(NSString*)sas;
|
||||||
-(void)terminateWithReason:(enum CallTerminationType)reason
|
-(void)terminateWithReason:(enum CallTerminationType)reason
|
||||||
withFailureInfo:(id)failureInfo
|
withFailureInfo:(id)failureInfo
|
||||||
|
|
|
@ -90,6 +90,13 @@
|
||||||
|
|
||||||
[self unrestrictedAdvanceCallProgressTo:type];
|
[self unrestrictedAdvanceCallProgressTo:type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)backgroundTimeExpired {
|
||||||
|
[self terminateWithReason:CallTerminationType_BackgroundTimeExpired
|
||||||
|
withFailureInfo:nil
|
||||||
|
andRelatedInfo:nil];
|
||||||
|
}
|
||||||
|
|
||||||
-(void)hangupOrDenyCall {
|
-(void)hangupOrDenyCall {
|
||||||
bool didDeny = [interactiveCallAcceptedOrDenied trySetResult:@NO];
|
bool didDeny = [interactiveCallAcceptedOrDenied trySetResult:@NO];
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ enum CallTerminationType {
|
||||||
// -- uh oh --
|
// -- uh oh --
|
||||||
CallTerminationType_BadInteractionWithServer, /// The signaling or relay server did something we didn't expect or understand.
|
CallTerminationType_BadInteractionWithServer, /// The signaling or relay server did something we didn't expect or understand.
|
||||||
CallTerminationType_UncategorizedFailure, /// Something went wrong. We didn't handle it properly, so we don't know what exactly it was.
|
CallTerminationType_UncategorizedFailure, /// Something went wrong. We didn't handle it properly, so we don't know what exactly it was.
|
||||||
|
CallTerminationType_BackgroundTimeExpired, /// The application expired available time while in background.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
self = [super initWithTimestamp:timeStamp inThread:thread];
|
self = [super initWithTimestamp:timeStamp inThread:thread];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
_callType = callType;
|
_callType = callType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#import "TSErrorMessage.h"
|
#import "TSErrorMessage.h"
|
||||||
#import "NSDate+millisecondTimeStamp.h"
|
#import "NSDate+millisecondTimeStamp.h"
|
||||||
|
#import "TSMessagesManager.h"
|
||||||
|
|
||||||
#import "TSErrorMessage_privateConstructor.h"
|
#import "TSErrorMessage_privateConstructor.h"
|
||||||
|
|
||||||
|
@ -20,11 +21,14 @@
|
||||||
_errorType = errorMessageType;
|
_errorType = errorMessageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[TSMessagesManager sharedManager] notifyUserForError:self inThread:thread];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithSignal:(IncomingPushMessageSignal*)signal transaction:(YapDatabaseReadWriteTransaction*)transaction failedMessageType:(TSErrorMessageType)errorMessageType{
|
- (instancetype)initWithSignal:(IncomingPushMessageSignal*)signal transaction:(YapDatabaseReadWriteTransaction*)transaction failedMessageType:(TSErrorMessageType)errorMessageType{
|
||||||
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:signal.source transaction:transaction];
|
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:signal.source transaction:transaction];
|
||||||
|
|
||||||
return [self initWithTimestamp:signal.timestamp inThread:contactThread failedMessageType:errorMessageType];
|
return [self initWithTimestamp:signal.timestamp inThread:contactThread failedMessageType:errorMessageType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ NSString * const TSAttachementsRelationshipEdgeName = @"TSAttachmentEdge";
|
||||||
self = [super initWithTimestamp:timestamp inThread:thread];
|
self = [super initWithTimestamp:timestamp inThread:thread];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
_body = body;
|
_body = body;
|
||||||
_attachments = [attachments mutableCopy];
|
_attachments = [attachments mutableCopy];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -62,7 +62,7 @@ NSString * const TSAttachementsRelationshipEdgeName = @"TSAttachmentEdge";
|
||||||
|
|
||||||
- (NSString *)description{
|
- (NSString *)description{
|
||||||
if(self.attachments > 0){
|
if(self.attachments > 0){
|
||||||
return @"Attachment";
|
return NSLocalizedString(@"ATTACHMENT", nil);
|
||||||
} else {
|
} else {
|
||||||
return self.body;
|
return self.body;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#import "TSIncomingMessage.h"
|
#import "TSIncomingMessage.h"
|
||||||
#import "TSOutgoingMessage.h"
|
#import "TSOutgoingMessage.h"
|
||||||
#import "TSInvalidIdentityKeySendingErrorMessage.h"
|
#import "TSInvalidIdentityKeySendingErrorMessage.h"
|
||||||
|
@class TSCall;
|
||||||
|
|
||||||
@interface TSMessagesManager : NSObject
|
@interface TSMessagesManager : NSObject
|
||||||
|
|
||||||
|
@ -21,6 +22,8 @@
|
||||||
- (void)handleMessageSignal:(IncomingPushMessageSignal*)messageSignal;
|
- (void)handleMessageSignal:(IncomingPushMessageSignal*)messageSignal;
|
||||||
|
|
||||||
- (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread;
|
- (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread;
|
||||||
|
- (void)notifyUserForError:(TSErrorMessage*)message inThread:(TSThread*)thread;
|
||||||
|
- (void)notifyUserForCall:(TSCall*)call inThread:(TSThread*)thread;
|
||||||
|
|
||||||
- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachments:(NSArray*)attachments;
|
- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachments:(NSArray*)attachments;
|
||||||
- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachments:(NSArray*)attachments completionBlock:(void (^)(NSString* messageIdentifier))completionBlock ;
|
- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachments:(NSArray*)attachments completionBlock:(void (^)(NSString* messageIdentifier))completionBlock ;
|
||||||
|
@ -28,5 +31,6 @@
|
||||||
- (void)handleSendToMyself:(TSOutgoingMessage*)outgoingMessage;
|
- (void)handleSendToMyself:(TSOutgoingMessage*)outgoingMessage;
|
||||||
|
|
||||||
- (NSUInteger)unreadMessagesCount;
|
- (NSUInteger)unreadMessagesCount;
|
||||||
|
- (NSUInteger)unreadMessagesCountExcept:(TSThread*)thread;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#import "Environment.h"
|
#import "Environment.h"
|
||||||
#import "PreferencesUtil.h"
|
#import "PreferencesUtil.h"
|
||||||
#import "ContactsManager.h"
|
#import "ContactsManager.h"
|
||||||
|
#import "TSCall.h"
|
||||||
|
|
||||||
#import <CocoaLumberjack/DDLog.h>
|
#import <CocoaLumberjack/DDLog.h>
|
||||||
#import <YapDatabase/YapDatabaseSecondaryIndex.h>
|
#import <YapDatabase/YapDatabaseSecondaryIndex.h>
|
||||||
|
@ -348,7 +349,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *name = [thread name];
|
NSString *name = [thread name];
|
||||||
[self notifyUserForIncomingMessage:incomingMessage from:name inThread:thread];
|
|
||||||
|
if (incomingMessage && thread) {
|
||||||
|
[self notifyUserForIncomingMessage:incomingMessage
|
||||||
|
from:name
|
||||||
|
inThread:thread];
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,6 +413,67 @@
|
||||||
return numberOfItems;
|
return numberOfItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)unreadMessagesCountExcept:(TSThread*)thread {
|
||||||
|
__block NSUInteger numberOfItems;
|
||||||
|
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||||
|
numberOfItems = [[transaction ext:TSUnreadDatabaseViewExtensionName] numberOfItemsInAllGroups];
|
||||||
|
numberOfItems = numberOfItems - [[transaction ext:TSUnreadDatabaseViewExtensionName] numberOfItemsInGroup:thread.uniqueId];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return numberOfItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)notifyUserForCall:(TSCall*)call inThread:(TSThread*)thread {
|
||||||
|
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive){
|
||||||
|
// Remove previous notification of call and show missed notification.
|
||||||
|
UILocalNotification *notif = [[PushManager sharedManager] closeVOIPBackgroundTask];
|
||||||
|
TSContactThread *cThread = (TSContactThread*)thread;
|
||||||
|
|
||||||
|
if (call.callType == RPRecentCallTypeMissed) {
|
||||||
|
[[UIApplication sharedApplication] cancelLocalNotification:notif];
|
||||||
|
|
||||||
|
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
||||||
|
notification.category = Signal_CallBack_Category;
|
||||||
|
notification.userInfo = @{Signal_Call_UserInfo_Key:cThread.contactIdentifier};
|
||||||
|
notification.soundName = @"NewMessage.aifc";
|
||||||
|
notification.alertBody = [NSString stringWithFormat:NSLocalizedString(@"MSGVIEW_MISSED_CALL", nil), [thread name]];
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)notifyUserForError:(TSErrorMessage*)message inThread:(TSThread*)thread {
|
||||||
|
NSString *messageDescription = message.description;
|
||||||
|
|
||||||
|
if (([UIApplication sharedApplication].applicationState != UIApplicationStateActive) && messageDescription) {
|
||||||
|
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
||||||
|
notification.category = Signal_Message_Category;
|
||||||
|
notification.userInfo = @{Signal_Thread_UserInfo_Key:thread.uniqueId};
|
||||||
|
notification.soundName = @"NewMessage.aifc";
|
||||||
|
|
||||||
|
NSString *alertBodyString = @"";
|
||||||
|
|
||||||
|
NSString *authorName = [thread name];
|
||||||
|
switch ([[Environment preferences] notificationPreviewType]) {
|
||||||
|
case NotificationNamePreview:
|
||||||
|
case NotificationNameNoPreview:
|
||||||
|
alertBodyString = [NSString stringWithFormat:@"%@: %@", authorName,messageDescription];
|
||||||
|
break;
|
||||||
|
case NotificationNoNameNoPreview:
|
||||||
|
alertBodyString = messageDescription;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
notification.alertBody = alertBodyString;
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
||||||
|
} else {
|
||||||
|
if ([Environment.preferences soundInForeground]) {
|
||||||
|
AudioServicesPlayAlertSound(_newMessageSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)notifyUserForIncomingMessage:(TSIncomingMessage*)message from:(NSString*)name inThread:(TSThread*)thread {
|
- (void)notifyUserForIncomingMessage:(TSIncomingMessage*)message from:(NSString*)name inThread:(TSThread*)thread {
|
||||||
NSString *messageDescription = message.description;
|
NSString *messageDescription = message.description;
|
||||||
|
|
||||||
|
@ -424,7 +491,8 @@
|
||||||
sender = message.authorId;
|
sender = message.authorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
notification.alertBody = [NSString stringWithFormat:@"New message from %@ in group \"%@\": %@", sender, name, messageDescription];
|
NSString *threadName = [NSString stringWithFormat:@"\"%@\"", name];
|
||||||
|
notification.alertBody = [NSString stringWithFormat:NSLocalizedString(@"APN_MESSAGE_IN_GROUP_DETAILED", nil), sender, threadName, messageDescription];
|
||||||
} else {
|
} else {
|
||||||
notification.alertBody = [NSString stringWithFormat:@"%@: %@", name, messageDescription];
|
notification.alertBody = [NSString stringWithFormat:@"%@: %@", name, messageDescription];
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@", textSecureKeysAPI, recipientInformation, deviceId]]];
|
self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@", textSecureKeysAPI, recipientInformation, deviceId]]];
|
||||||
|
|
||||||
[self setHTTPMethod:@"GET"];
|
self.HTTPMethod = @"GET";
|
||||||
|
self.parameters = nil;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern NSString * const SocketConnectingNotification;
|
||||||
@interface TSSocketManager : NSObject <SRWebSocketDelegate>
|
@interface TSSocketManager : NSObject <SRWebSocketDelegate>
|
||||||
|
|
||||||
+ (void)becomeActiveFromForeground;
|
+ (void)becomeActiveFromForeground;
|
||||||
+ (void)becomeActiveFromBackground;
|
+ (void)becomeActiveFromBackgroundExpectMessage:(BOOL)expected;
|
||||||
|
|
||||||
+ (void)resignActivity;
|
+ (void)resignActivity;
|
||||||
+ (void)sendNotification;
|
+ (void)sendNotification;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#define kWebSocketHeartBeat 30
|
#define kWebSocketHeartBeat 30
|
||||||
#define kWebSocketReconnectTry 5
|
#define kWebSocketReconnectTry 5
|
||||||
#define kBackgroundConnectTimer 10
|
#define kBackgroundConnectTimer 25
|
||||||
#define kBackgroundConnectKeepAlive 15
|
#define kBackgroundConnectKeepAlive 15
|
||||||
|
|
||||||
NSString * const SocketOpenedNotification = @"SocketOpenedNotification";
|
NSString * const SocketOpenedNotification = @"SocketOpenedNotification";
|
||||||
|
@ -38,7 +38,10 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
|
|
||||||
@property (nonatomic) UIBackgroundTaskIdentifier fetchingTaskIdentifier;
|
@property (nonatomic) UIBackgroundTaskIdentifier fetchingTaskIdentifier;
|
||||||
|
|
||||||
@property BOOL didFetchInBackground;
|
@property BOOL didConnectBg;
|
||||||
|
@property BOOL didRetreiveMessageBg;
|
||||||
|
@property BOOL shouldDownloadMessage;
|
||||||
|
|
||||||
@property (nonatomic, retain) NSTimer *backgroundKeepAliveTimer;
|
@property (nonatomic, retain) NSTimer *backgroundKeepAliveTimer;
|
||||||
@property (nonatomic, retain) NSTimer *backgroundConnectTimer;
|
@property (nonatomic, retain) NSTimer *backgroundConnectTimer;
|
||||||
|
|
||||||
|
@ -51,7 +54,10 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
self.websocket = nil;
|
self.websocket = nil;
|
||||||
[self addObserver:self forKeyPath:@"status" options:0 context:kSocketStatusObservationContext];
|
[self addObserver:self
|
||||||
|
forKeyPath:@"status"
|
||||||
|
options:0
|
||||||
|
context:kSocketStatusObservationContext];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -63,7 +69,9 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
sharedMyManager = [[self alloc] init];
|
sharedMyManager = [[self alloc] init];
|
||||||
sharedMyManager.fetchingTaskIdentifier = UIBackgroundTaskInvalid;
|
sharedMyManager.fetchingTaskIdentifier = UIBackgroundTaskInvalid;
|
||||||
sharedMyManager.didFetchInBackground = NO;
|
sharedMyManager.didConnectBg = NO;
|
||||||
|
sharedMyManager.shouldDownloadMessage = NO;
|
||||||
|
sharedMyManager.didRetreiveMessageBg = NO;
|
||||||
});
|
});
|
||||||
return sharedMyManager;
|
return sharedMyManager;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +126,7 @@ 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
|
self.pingTimer = [NSTimer timerWithTimeInterval:kWebSocketHeartBeat
|
||||||
target:self
|
target:self
|
||||||
selector:@selector(webSocketHeartBeat)
|
selector:@selector(webSocketHeartBeat)
|
||||||
userInfo:nil
|
userInfo:nil
|
||||||
|
@ -131,6 +139,7 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
self.status = kSocketStatusOpen;
|
self.status = kSocketStatusOpen;
|
||||||
[self.reconnectTimer invalidate];
|
[self.reconnectTimer invalidate];
|
||||||
self.reconnectTimer = nil;
|
self.reconnectTimer = nil;
|
||||||
|
self.didConnectBg = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
|
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
|
||||||
|
@ -143,7 +152,7 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
|
|
||||||
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(NSData*)data {
|
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(NSData*)data {
|
||||||
WebSocketMessage *wsMessage = [WebSocketMessage parseFromData:data];
|
WebSocketMessage *wsMessage = [WebSocketMessage parseFromData:data];
|
||||||
self.didFetchInBackground = YES;
|
self.didRetreiveMessageBg = YES;
|
||||||
|
|
||||||
if (wsMessage.type == WebSocketMessageTypeRequest) {
|
if (wsMessage.type == WebSocketMessageTypeRequest) {
|
||||||
[self processWebSocketRequestMessage:wsMessage.request];
|
[self processWebSocketRequestMessage:wsMessage.request];
|
||||||
|
@ -158,7 +167,6 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
DDLogInfo(@"Got message with verb: %@ and path: %@", message.verb, message.path);
|
DDLogInfo(@"Got message with verb: %@ and path: %@", message.verb, message.path);
|
||||||
|
|
||||||
[self sendWebSocketMessageAcknowledgement:message];
|
[self sendWebSocketMessageAcknowledgement:message];
|
||||||
|
|
||||||
[self keepAliveBackground];
|
[self keepAliveBackground];
|
||||||
|
|
||||||
if ([message.path isEqualToString:@"/api/v1/message"] && [message.verb isEqualToString:@"PUT"]){
|
if ([message.path isEqualToString:@"/api/v1/message"] && [message.verb isEqualToString:@"PUT"]){
|
||||||
|
@ -184,7 +192,7 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
if (self.fetchingTaskIdentifier) {
|
if (self.fetchingTaskIdentifier) {
|
||||||
[self.backgroundKeepAliveTimer invalidate];
|
[self.backgroundKeepAliveTimer invalidate];
|
||||||
|
|
||||||
self.backgroundKeepAliveTimer = [NSTimer scheduledTimerWithTimeInterval:kBackgroundConnectKeepAlive
|
self.backgroundKeepAliveTimer = [NSTimer timerWithTimeInterval:kBackgroundConnectKeepAlive
|
||||||
target:self
|
target:self
|
||||||
selector:@selector(backgroundTimeExpired)
|
selector:@selector(backgroundTimeExpired)
|
||||||
userInfo:nil
|
userInfo:nil
|
||||||
|
@ -243,8 +251,8 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scheduleRetry {
|
- (void)scheduleRetry {
|
||||||
if (!self.reconnectTimer || ![self.reconnectTimer isValid]) {
|
if (![self.reconnectTimer isValid]) {
|
||||||
self.reconnectTimer = [NSTimer scheduledTimerWithTimeInterval:kWebSocketReconnectTry
|
self.reconnectTimer = [NSTimer timerWithTimeInterval:kWebSocketReconnectTry
|
||||||
target:[self class]
|
target:[self class]
|
||||||
selector:@selector(becomeActive)
|
selector:@selector(becomeActive)
|
||||||
userInfo:nil
|
userInfo:nil
|
||||||
|
@ -252,6 +260,8 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
// Additionally, we want the reconnect timer to work in the background too.
|
// Additionally, we want the reconnect timer to work in the background too.
|
||||||
[[NSRunLoop mainRunLoop] addTimer:self.reconnectTimer
|
[[NSRunLoop mainRunLoop] addTimer:self.reconnectTimer
|
||||||
forMode:NSDefaultRunLoopMode];
|
forMode:NSDefaultRunLoopMode];
|
||||||
|
} else {
|
||||||
|
DDLogWarn(@"Not scheduling retry, valid timer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +269,6 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
|
|
||||||
+ (void)becomeActiveFromForeground {
|
+ (void)becomeActiveFromForeground {
|
||||||
TSSocketManager *sharedInstance = [self sharedManager];
|
TSSocketManager *sharedInstance = [self sharedManager];
|
||||||
[sharedInstance.backgroundKeepAliveTimer invalidate];
|
|
||||||
|
|
||||||
if (sharedInstance.fetchingTaskIdentifier != UIBackgroundTaskInvalid) {
|
if (sharedInstance.fetchingTaskIdentifier != UIBackgroundTaskInvalid) {
|
||||||
[sharedInstance closeBackgroundTask];
|
[sharedInstance closeBackgroundTask];
|
||||||
|
@ -268,26 +277,23 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
[self becomeActive];
|
[self becomeActive];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (void)becomeActiveFromBackgroundExpectMessage:(BOOL)expected {
|
||||||
+ (void)becomeActiveFromBackground {
|
|
||||||
TSSocketManager *sharedInstance = [TSSocketManager sharedManager];
|
TSSocketManager *sharedInstance = [TSSocketManager sharedManager];
|
||||||
|
|
||||||
if (sharedInstance.fetchingTaskIdentifier == UIBackgroundTaskInvalid) {
|
if (sharedInstance.fetchingTaskIdentifier == UIBackgroundTaskInvalid) {
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
sharedInstance.backgroundConnectTimer = [NSTimer timerWithTimeInterval:kBackgroundConnectTimer
|
||||||
sharedInstance.backgroundConnectTimer = [NSTimer scheduledTimerWithTimeInterval:kBackgroundConnectTimer
|
|
||||||
target:sharedInstance
|
target:sharedInstance
|
||||||
selector:@selector(backgroundConnectTimerExpired)
|
selector:@selector(backgroundConnectTimerExpired)
|
||||||
userInfo:nil
|
userInfo:nil
|
||||||
repeats:NO];
|
repeats:NO];
|
||||||
|
NSRunLoop *loop = [NSRunLoop mainRunLoop];
|
||||||
NSRunLoop *loop = [NSRunLoop currentRunLoop];
|
[loop addTimer:[TSSocketManager sharedManager].backgroundConnectTimer
|
||||||
[loop addTimer:[TSSocketManager sharedManager].backgroundConnectTimer
|
forMode:NSDefaultRunLoopMode];
|
||||||
forMode:NSDefaultRunLoopMode];
|
|
||||||
[loop run];
|
|
||||||
});
|
|
||||||
|
|
||||||
[sharedInstance.backgroundKeepAliveTimer invalidate];
|
[sharedInstance.backgroundKeepAliveTimer invalidate];
|
||||||
sharedInstance.didFetchInBackground = NO;
|
sharedInstance.didConnectBg = NO;
|
||||||
|
sharedInstance.didRetreiveMessageBg = NO;
|
||||||
|
sharedInstance.shouldDownloadMessage = expected;
|
||||||
sharedInstance.fetchingTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
sharedInstance.fetchingTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||||
[TSSocketManager resignActivity];
|
[TSSocketManager resignActivity];
|
||||||
[[TSSocketManager sharedManager] closeBackgroundTask];
|
[[TSSocketManager sharedManager] closeBackgroundTask];
|
||||||
|
@ -312,9 +318,16 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
[self.backgroundKeepAliveTimer invalidate];
|
[self.backgroundKeepAliveTimer invalidate];
|
||||||
[self.backgroundConnectTimer invalidate];
|
[self.backgroundConnectTimer invalidate];
|
||||||
|
|
||||||
if (!self.didFetchInBackground) {
|
/*
|
||||||
|
If VOIP Push worked, we should just have to check if message was retreived and if not, alert the user.
|
||||||
|
But we have to rely on the server for the fallback in failed cases since background push is unreliable.
|
||||||
|
https://devforums.apple.com/message/1135227
|
||||||
|
|
||||||
|
if ((self.shouldDownloadMessage && !self.didRetreiveMessageBg) || !self.didConnectBg) {
|
||||||
[self backgroundConnectTimedOut];
|
[self backgroundConnectTimedOut];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
[[UIApplication sharedApplication] endBackgroundTask:self.fetchingTaskIdentifier];
|
[[UIApplication sharedApplication] endBackgroundTask:self.fetchingTaskIdentifier];
|
||||||
self.fetchingTaskIdentifier = UIBackgroundTaskInvalid;
|
self.fetchingTaskIdentifier = UIBackgroundTaskInvalid;
|
||||||
|
@ -323,6 +336,7 @@ NSString * const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||||
- (void)backgroundConnectTimedOut {
|
- (void)backgroundConnectTimedOut {
|
||||||
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
UILocalNotification *notification = [[UILocalNotification alloc] init];
|
||||||
notification.alertBody = NSLocalizedString(@"APN_FETCHED_FAILED", nil);
|
notification.alertBody = NSLocalizedString(@"APN_FETCHED_FAILED", nil);
|
||||||
|
notification.soundName = @"NewMessage.aifc";
|
||||||
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,11 @@ typedef enum {
|
||||||
|
|
||||||
#define textSecureHTTPTimeOut 10
|
#define textSecureHTTPTimeOut 10
|
||||||
|
|
||||||
#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/"
|
#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/"
|
||||||
#define textSecureServerURL @"https://textsecure-service.whispersystems.org/"
|
#define textSecureServerURL @"https://textsecure-service.whispersystems.org/"
|
||||||
|
|
||||||
//#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/"
|
//#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/"
|
||||||
//#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/"
|
//#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/"
|
||||||
|
|
||||||
#define textSecureGeneralAPI @"v1"
|
#define textSecureGeneralAPI @"v1"
|
||||||
#define textSecureAccountsAPI @"v1/accounts"
|
#define textSecureAccountsAPI @"v1/accounts"
|
||||||
|
|
|
@ -24,10 +24,14 @@
|
||||||
@property (nonatomic,strong) MPMoviePlayerController* videoPlayer;
|
@property (nonatomic,strong) MPMoviePlayerController* videoPlayer;
|
||||||
@property (nonatomic,strong) AVAudioPlayer* audioPlayer;
|
@property (nonatomic,strong) AVAudioPlayer* audioPlayer;
|
||||||
@property (nonatomic,strong) AVAudioRecorder* audioRecorder;
|
@property (nonatomic,strong) AVAudioRecorder* audioRecorder;
|
||||||
|
|
||||||
- (void)setupWithThread:(TSThread*)thread;
|
- (void)setupWithThread:(TSThread*)thread;
|
||||||
- (void)setupWithTSIdentifier:(NSString*)identifier;
|
- (void)setupWithTSIdentifier:(NSString*)identifier;
|
||||||
- (void)setupWithTSGroup:(TSGroupModel*)model;
|
- (void)setupWithTSGroup:(TSGroupModel*)model;
|
||||||
|
|
||||||
- (void)setComposeOnOpen:(BOOL)compose;
|
- (void)setComposeOnOpen:(BOOL)compose;
|
||||||
|
|
||||||
|
- (TSThread*)thread;
|
||||||
|
- (void)popKeyBoard;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
#import <AddressBookUI/AddressBookUI.h>
|
#import <AddressBookUI/AddressBookUI.h>
|
||||||
|
|
||||||
#import "MessagesViewController.h"
|
#import "MessagesViewController.h"
|
||||||
#import "FullImageViewController.h"
|
#import "FullImageViewController.h"
|
||||||
#import "FingerprintViewController.h"
|
#import "FingerprintViewController.h"
|
||||||
|
@ -82,9 +83,13 @@ typedef enum : NSUInteger {
|
||||||
@interface MessagesViewController () {
|
@interface MessagesViewController () {
|
||||||
UIImage* tappedImage;
|
UIImage* tappedImage;
|
||||||
BOOL isGroupConversation;
|
BOOL isGroupConversation;
|
||||||
|
|
||||||
|
UIView *_unreadContainer;
|
||||||
|
UIImageView *_unreadBackground;
|
||||||
|
UILabel *_unreadLabel;
|
||||||
|
NSUInteger _unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@property (nonatomic, weak) UIView *navView;
|
@property (nonatomic, weak) UIView *navView;
|
||||||
@property (nonatomic, retain) TSThread *thread;
|
@property (nonatomic, retain) TSThread *thread;
|
||||||
@property (nonatomic, strong) YapDatabaseConnection *editingDatabaseConnection;
|
@property (nonatomic, strong) YapDatabaseConnection *editingDatabaseConnection;
|
||||||
|
@ -113,6 +118,11 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface UINavigationItem(){
|
||||||
|
UIView *backButtonView;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation MessagesViewController
|
@implementation MessagesViewController
|
||||||
|
|
||||||
- (void)setupWithTSIdentifier:(NSString *)identifier {
|
- (void)setupWithTSIdentifier:(NSString *)identifier {
|
||||||
|
@ -146,6 +156,9 @@ typedef enum : NSUInteger {
|
||||||
isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]];
|
isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (TSThread *)thread {
|
||||||
|
return _thread;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)hideInputIfNeeded {
|
- (void)hideInputIfNeeded {
|
||||||
if([_thread isKindOfClass:[TSGroupThread class]] && ![((TSGroupThread*)_thread).groupModel.groupMemberIds containsObject:[SignalKeyingStorage.localNumber toE164]]) {
|
if([_thread isKindOfClass:[TSGroupThread class]] && ![((TSGroupThread*)_thread).groupModel.groupMemberIds containsObject:[SignalKeyingStorage.localNumber toE164]]) {
|
||||||
|
@ -229,7 +242,7 @@ typedef enum : NSUInteger {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startReadTimer {
|
- (void)startReadTimer {
|
||||||
self.readTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(markAllMessagesAsRead) userInfo:nil repeats:YES];
|
self.readTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(markAllMessagesAsRead) userInfo:nil repeats:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)cancelReadTimer {
|
- (void)cancelReadTimer {
|
||||||
|
@ -237,23 +250,32 @@ typedef enum : NSUInteger {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidAppear:(BOOL)animated {
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
|
[self updateBackButton];
|
||||||
[super viewDidAppear:animated];
|
[super viewDidAppear:animated];
|
||||||
[self markAllMessagesAsRead];
|
[self markAllMessagesAsRead];
|
||||||
[self startReadTimer];
|
[self startReadTimer];
|
||||||
_isVisible = YES;
|
_isVisible = YES;
|
||||||
[self initializeTitleLabelGestureRecognizer];
|
[self initializeTitleLabelGestureRecognizer];
|
||||||
|
|
||||||
|
[self updateBackButton];
|
||||||
|
|
||||||
if (_composeOnOpen) {
|
if (_composeOnOpen) {
|
||||||
[self popKeyBoard];
|
[self popKeyBoard];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateBackButton {
|
||||||
|
[self setUnreadCount:[[TSMessagesManager sharedManager] unreadMessagesCountExcept:self.thread]];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated {
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
|
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
|
||||||
// back button was pressed.
|
// back button was pressed.
|
||||||
[self.navController hideDropDown:self];
|
[self.navController hideDropDown:self];
|
||||||
}
|
}
|
||||||
[super viewWillDisappear:animated];
|
[super viewWillDisappear:animated];
|
||||||
|
[_unreadContainer removeFromSuperview];
|
||||||
|
_unreadContainer = nil;
|
||||||
|
|
||||||
[_audioPlayerPoller invalidate];
|
[_audioPlayerPoller invalidate];
|
||||||
[_audioPlayer stop];
|
[_audioPlayer stop];
|
||||||
|
@ -1328,6 +1350,9 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
|
|
||||||
- (void)yapDatabaseModified:(NSNotification *)notification {
|
- (void)yapDatabaseModified:(NSNotification *)notification {
|
||||||
|
|
||||||
|
[self updateBackButton];
|
||||||
|
|
||||||
if(isGroupConversation) {
|
if(isGroupConversation) {
|
||||||
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||||
TSGroupThread* gThread = (TSGroupThread*)self.thread;
|
TSGroupThread* gThread = (TSGroupThread*)self.thread;
|
||||||
|
@ -1657,6 +1682,58 @@ typedef enum : NSUInteger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark Unread Badge
|
||||||
|
|
||||||
|
- (void)setUnreadCount:(NSUInteger)unreadCount {
|
||||||
|
if (_unreadCount != unreadCount) {
|
||||||
|
_unreadCount = unreadCount;
|
||||||
|
|
||||||
|
if (_unreadCount > 0) {
|
||||||
|
if (_unreadContainer == nil) {
|
||||||
|
static UIImage *backgroundImage = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^
|
||||||
|
{
|
||||||
|
UIGraphicsBeginImageContextWithOptions(CGSizeMake(17.0f, 17.0f), false, 0.0f);
|
||||||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
|
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
|
||||||
|
CGContextFillEllipseInRect(context, CGRectMake(0.0f, 0.0f, 17.0f, 17.0f));
|
||||||
|
backgroundImage = [UIGraphicsGetImageFromCurrentImageContext() stretchableImageWithLeftCapWidth:8 topCapHeight:8];
|
||||||
|
UIGraphicsEndImageContext();
|
||||||
|
});
|
||||||
|
|
||||||
|
_unreadContainer = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 10.0f, 10.0f)];
|
||||||
|
_unreadContainer.userInteractionEnabled = NO;
|
||||||
|
_unreadContainer.layer.zPosition = 2000;
|
||||||
|
[self.navigationController.navigationBar addSubview:_unreadContainer];
|
||||||
|
|
||||||
|
_unreadBackground = [[UIImageView alloc] initWithImage:backgroundImage];
|
||||||
|
[_unreadContainer addSubview:_unreadBackground];
|
||||||
|
|
||||||
|
_unreadLabel = [[UILabel alloc] init];
|
||||||
|
_unreadLabel.backgroundColor = [UIColor clearColor];
|
||||||
|
_unreadLabel.textColor = [UIColor whiteColor];
|
||||||
|
_unreadLabel.font = [UIFont systemFontOfSize:12];
|
||||||
|
[_unreadContainer addSubview:_unreadLabel];
|
||||||
|
}
|
||||||
|
_unreadContainer.hidden = false;
|
||||||
|
|
||||||
|
_unreadLabel.text = [NSString stringWithFormat:@"%lu", (unsigned long)unreadCount];
|
||||||
|
[_unreadLabel sizeToFit];
|
||||||
|
|
||||||
|
CGPoint offset = CGPointMake(17.0f, 2.0f);
|
||||||
|
|
||||||
|
_unreadBackground.frame = CGRectMake(offset.x, offset.y,
|
||||||
|
MAX(_unreadLabel.frame.size.width + 8.0f, 17.0f), 17.0f);
|
||||||
|
_unreadLabel.frame = CGRectMake(offset.x + floor((2.0f*(_unreadBackground.frame.size.width - _unreadLabel.frame.size.width)/ 2.0f)/2.0f), offset.y + 1.0f,
|
||||||
|
_unreadLabel.frame.size.width, _unreadLabel.frame.size.height);
|
||||||
|
|
||||||
|
} else if (_unreadContainer != nil) {
|
||||||
|
_unreadContainer.hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
self.options = @[@(NotificationNamePreview),
|
self.options = @[@(NotificationNamePreview),
|
||||||
@(NotificationNameNoPreview),
|
@(NotificationNameNoPreview),
|
||||||
@(NotificationNoNameNoPreview)];
|
@(NotificationNoNameNoPreview)];
|
||||||
|
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +42,22 @@
|
||||||
{
|
{
|
||||||
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"NotificationSettingsOption"];
|
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"NotificationSettingsOption"];
|
||||||
PropertyListPreferences *prefs = [Environment preferences];
|
PropertyListPreferences *prefs = [Environment preferences];
|
||||||
[[cell textLabel] setText:[prefs nameForNotificationPreviewType:[[self.options objectAtIndex:(NSUInteger)indexPath.row] unsignedIntegerValue]]];
|
NSUInteger notifType = [[self.options objectAtIndex:(NSUInteger)indexPath.row] unsignedIntegerValue];
|
||||||
|
[[cell textLabel] setText:[prefs nameForNotificationPreviewType:notifType]];
|
||||||
|
|
||||||
|
NotificationType selectedNotifType = [prefs notificationPreviewType];
|
||||||
|
|
||||||
|
if (selectedNotifType == notifType) {
|
||||||
|
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||||
|
}
|
||||||
|
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
|
||||||
|
return NSLocalizedString(@"NOTIFICATIONS_FOOTER_WARNING", nil);
|
||||||
|
}
|
||||||
|
|
||||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
{
|
{
|
||||||
[Environment.preferences setNotificationPreviewType:[[self.options objectAtIndex:(NSUInteger)indexPath.row] unsignedIntegerValue]];
|
[Environment.preferences setNotificationPreviewType:[[self.options objectAtIndex:(NSUInteger)indexPath.row] unsignedIntegerValue]];
|
||||||
|
|
|
@ -20,13 +20,11 @@
|
||||||
@property (nonatomic) BOOL composeMessage;
|
@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 *archiveButton;
|
|
||||||
@property (nonatomic, retain) IBOutlet UILabel *inboxCountLabel;
|
|
||||||
@property (nonatomic, strong) IBOutlet UILabel *emptyBoxLabel;
|
@property (nonatomic, strong) IBOutlet UILabel *emptyBoxLabel;
|
||||||
|
|
||||||
@property (nonatomic, retain) CallState* latestCall;
|
@property (nonatomic, retain) CallState* latestCall;
|
||||||
|
|
||||||
-(IBAction)selectedInbox:(id)sender;
|
-(IBAction)selectedInbox:(id)sender;
|
||||||
-(IBAction)selectedArchive:(id)sender;
|
-(IBAction)selectedArchive:(id)sender;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -48,6 +48,7 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
@property (nonatomic, strong) YapDatabaseViewMappings *threadMappings;
|
@property (nonatomic, strong) YapDatabaseViewMappings *threadMappings;
|
||||||
@property (nonatomic) CellState viewingThreadsIn;
|
@property (nonatomic) CellState viewingThreadsIn;
|
||||||
@property (nonatomic) long inboxCount;
|
@property (nonatomic) long inboxCount;
|
||||||
|
@property (nonatomic, retain) UISegmentedControl *segmentedControl;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -76,8 +77,21 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
[[[Environment getCurrent] contactsManager].getObservableContacts watchLatestValue:^(id latestValue) {
|
[[[Environment getCurrent] contactsManager].getObservableContacts watchLatestValue:^(id latestValue) {
|
||||||
[self.tableView reloadData];
|
[self.tableView reloadData];
|
||||||
} onThread:[NSThread mainThread] untilCancelled:nil];
|
} onThread:[NSThread mainThread] untilCancelled:nil];
|
||||||
self.title = NSLocalizedString(@"CONVERSATIONS_VIEW_TITLE", @"");
|
|
||||||
|
self.segmentedControl = [[UISegmentedControl alloc] initWithItems:@[NSLocalizedString(@"WHISPER_NAV_BAR_TITLE", nil),
|
||||||
|
NSLocalizedString(@"ARCHIVE_NAV_BAR_TITLE", nil)]];
|
||||||
|
|
||||||
|
[self.segmentedControl addTarget:self action:@selector(swappedSegmentedControl) forControlEvents:UIControlEventValueChanged];
|
||||||
|
self.navigationItem.titleView = self.segmentedControl;
|
||||||
|
[self.segmentedControl setSelectedSegmentIndex:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)swappedSegmentedControl {
|
||||||
|
if (self.segmentedControl.selectedSegmentIndex == 0) {
|
||||||
|
[self selectedInbox:nil];
|
||||||
|
} else {
|
||||||
|
[self selectedArchive:nil];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)viewWillAppear:(BOOL)animated
|
-(void)viewWillAppear:(BOOL)animated
|
||||||
|
@ -186,7 +200,6 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
- (void)tableViewCellTappedDelete:(NSIndexPath*)indexPath {
|
- (void)tableViewCellTappedDelete:(NSIndexPath*)indexPath {
|
||||||
TSThread *thread = [self threadForIndexPath:indexPath];
|
TSThread *thread = [self threadForIndexPath:indexPath];
|
||||||
if([thread isKindOfClass:[TSGroupThread class]]) {
|
if([thread isKindOfClass:[TSGroupThread class]]) {
|
||||||
DDLogDebug(@"leaving the group");
|
|
||||||
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread messageBody:@"" attachments:[[NSMutableArray alloc] init]];
|
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread messageBody:@"" attachments:[[NSMutableArray alloc] init]];
|
||||||
message.groupMetaMessage = TSGroupMessageQuit;
|
message.groupMetaMessage = TSGroupMessageQuit;
|
||||||
[[TSMessagesManager sharedManager] sendMessage:message inThread:thread];
|
[[TSMessagesManager sharedManager] sendMessage:message inThread:thread];
|
||||||
|
@ -210,17 +223,20 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
-(void) updateInboxCountLabel {
|
- (NSNumber*)updateInboxCountLabel {
|
||||||
NSUInteger numberOfItems = [[TSMessagesManager sharedManager] unreadMessagesCount];
|
NSUInteger numberOfItems = [[TSMessagesManager sharedManager] unreadMessagesCount];
|
||||||
NSNumber *badgeNumber = [NSNumber numberWithUnsignedInteger:numberOfItems];
|
NSNumber *badgeNumber = [NSNumber numberWithUnsignedInteger:numberOfItems];
|
||||||
NSString *badgeValue = nil;
|
NSString *unreadString = NSLocalizedString(@"WHISPER_NAV_BAR_TITLE", nil);
|
||||||
|
|
||||||
if (![badgeNumber isEqualToNumber:@0]) {
|
if (![badgeNumber isEqualToNumber:@0]) {
|
||||||
badgeValue = [badgeNumber stringValue];
|
NSString *badgeValue = [badgeNumber stringValue];
|
||||||
|
unreadString = [unreadString stringByAppendingFormat:@" (%@)", badgeValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[_segmentedControl setTitle:unreadString forSegmentAtIndex:0];
|
||||||
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeNumber.integerValue];
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeNumber.integerValue];
|
||||||
self.inboxCountLabel.text = badgeValue;
|
|
||||||
|
return badgeNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath{
|
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath{
|
||||||
|
@ -267,15 +283,11 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
|
|
||||||
-(IBAction)selectedInbox:(id)sender {
|
-(IBAction)selectedInbox:(id)sender {
|
||||||
self.viewingThreadsIn = kInboxState;
|
self.viewingThreadsIn = kInboxState;
|
||||||
[self.inboxButton setSelected:YES];
|
|
||||||
[self.archiveButton setSelected:NO];
|
|
||||||
[self changeToGrouping:TSInboxGroup];
|
[self changeToGrouping:TSInboxGroup];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(IBAction)selectedArchive:(id)sender {
|
-(IBAction)selectedArchive:(id)sender {
|
||||||
self.viewingThreadsIn = kArchiveState;
|
self.viewingThreadsIn = kArchiveState;
|
||||||
[self.inboxButton setSelected:NO];
|
|
||||||
[self.archiveButton setSelected:YES];
|
|
||||||
[self changeToGrouping:TSArchiveGroup];
|
[self changeToGrouping:TSArchiveGroup];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,8 +336,6 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self updateInboxCountLabel];
|
|
||||||
|
|
||||||
[self.tableView beginUpdates];
|
[self.tableView beginUpdates];
|
||||||
|
|
||||||
for (YapDatabaseViewSectionChange *sectionChange in sectionChanges)
|
for (YapDatabaseViewSectionChange *sectionChange in sectionChanges)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue