commit
6c52d46926
|
@ -196,7 +196,6 @@
|
||||||
B8566C6C256F60F50045A0B9 /* OWSUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF2D1255B6DAF007E1867 /* OWSUserProfile.m */; };
|
B8566C6C256F60F50045A0B9 /* OWSUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF2D1255B6DAF007E1867 /* OWSUserProfile.m */; };
|
||||||
B8566C7D256F62030045A0B9 /* OWSUserProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2D3255B6DAF007E1867 /* OWSUserProfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
B8566C7D256F62030045A0B9 /* OWSUserProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF2D3255B6DAF007E1867 /* OWSUserProfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
B8569AC325CB5D2900DBA3DB /* ConversationVC+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */; };
|
B8569AC325CB5D2900DBA3DB /* ConversationVC+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */; };
|
||||||
B8569AD325CBA13D00DBA3DB /* MediaTextOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AD225CBA13D00DBA3DB /* MediaTextOverlayView.swift */; };
|
|
||||||
B8569AE325CBB19A00DBA3DB /* DocumentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AE225CBB19A00DBA3DB /* DocumentView.swift */; };
|
B8569AE325CBB19A00DBA3DB /* DocumentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8569AE225CBB19A00DBA3DB /* DocumentView.swift */; };
|
||||||
B866CE112581C1A900535CC4 /* Sodium+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E7134E251C867C009649BB /* Sodium+Conversion.swift */; };
|
B866CE112581C1A900535CC4 /* Sodium+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E7134E251C867C009649BB /* Sodium+Conversion.swift */; };
|
||||||
B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; };
|
B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; };
|
||||||
|
@ -241,8 +240,6 @@
|
||||||
B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0742339EDCF00B4D94D /* NukeDataModal.swift */; };
|
B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0742339EDCF00B4D94D /* NukeDataModal.swift */; };
|
||||||
B897621C25D201F7004F83B2 /* ScrollToBottomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B897621B25D201F7004F83B2 /* ScrollToBottomButton.swift */; };
|
B897621C25D201F7004F83B2 /* ScrollToBottomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B897621B25D201F7004F83B2 /* ScrollToBottomButton.swift */; };
|
||||||
B8AE75A425A6C6A6001A84D2 /* Data+Trimming.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8AE75A325A6C6A6001A84D2 /* Data+Trimming.swift */; };
|
B8AE75A425A6C6A6001A84D2 /* Data+Trimming.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8AE75A325A6C6A6001A84D2 /* Data+Trimming.swift */; };
|
||||||
B8AE760B25ABFB5A001A84D2 /* GeneralUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = B8AE760A25ABFB5A001A84D2 /* GeneralUtilities.m */; };
|
|
||||||
B8AE761425ABFBB9001A84D2 /* GeneralUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = B8AE760925ABFB00001A84D2 /* GeneralUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
B8AF4BB426A5204600583500 /* SendSeedModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8AF4BB326A5204600583500 /* SendSeedModal.swift */; };
|
B8AF4BB426A5204600583500 /* SendSeedModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8AF4BB326A5204600583500 /* SendSeedModal.swift */; };
|
||||||
B8B32021258B1A650020074B /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32020258B1A650020074B /* Contact.swift */; };
|
B8B32021258B1A650020074B /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32020258B1A650020074B /* Contact.swift */; };
|
||||||
B8B32033258B235D0020074B /* Storage+Contacts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32032258B235D0020074B /* Storage+Contacts.swift */; };
|
B8B32033258B235D0020074B /* Storage+Contacts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B32032258B235D0020074B /* Storage+Contacts.swift */; };
|
||||||
|
@ -1226,7 +1223,6 @@
|
||||||
B8544E3223D50E4900299F14 /* SNAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SNAppearance.swift; sourceTree = "<group>"; };
|
B8544E3223D50E4900299F14 /* SNAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SNAppearance.swift; sourceTree = "<group>"; };
|
||||||
B8566C62256F55930045A0B9 /* OWSLinkPreview+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OWSLinkPreview+Conversion.swift"; sourceTree = "<group>"; };
|
B8566C62256F55930045A0B9 /* OWSLinkPreview+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OWSLinkPreview+Conversion.swift"; sourceTree = "<group>"; };
|
||||||
B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConversationVC+Interaction.swift"; sourceTree = "<group>"; };
|
B8569AC225CB5D2900DBA3DB /* ConversationVC+Interaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConversationVC+Interaction.swift"; sourceTree = "<group>"; };
|
||||||
B8569AD225CBA13D00DBA3DB /* MediaTextOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaTextOverlayView.swift; sourceTree = "<group>"; };
|
|
||||||
B8569AE225CBB19A00DBA3DB /* DocumentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentView.swift; sourceTree = "<group>"; };
|
B8569AE225CBB19A00DBA3DB /* DocumentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentView.swift; sourceTree = "<group>"; };
|
||||||
B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
|
B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
|
||||||
B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = "<group>"; };
|
B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1249,8 +1245,6 @@
|
||||||
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NukeDataModal.swift; sourceTree = "<group>"; };
|
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NukeDataModal.swift; sourceTree = "<group>"; };
|
||||||
B897621B25D201F7004F83B2 /* ScrollToBottomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollToBottomButton.swift; sourceTree = "<group>"; };
|
B897621B25D201F7004F83B2 /* ScrollToBottomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollToBottomButton.swift; sourceTree = "<group>"; };
|
||||||
B8AE75A325A6C6A6001A84D2 /* Data+Trimming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Trimming.swift"; sourceTree = "<group>"; };
|
B8AE75A325A6C6A6001A84D2 /* Data+Trimming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Trimming.swift"; sourceTree = "<group>"; };
|
||||||
B8AE760925ABFB00001A84D2 /* GeneralUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneralUtilities.h; sourceTree = "<group>"; };
|
|
||||||
B8AE760A25ABFB5A001A84D2 /* GeneralUtilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneralUtilities.m; sourceTree = "<group>"; };
|
|
||||||
B8AF4BB326A5204600583500 /* SendSeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendSeedModal.swift; sourceTree = "<group>"; };
|
B8AF4BB326A5204600583500 /* SendSeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendSeedModal.swift; sourceTree = "<group>"; };
|
||||||
B8B32020258B1A650020074B /* Contact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contact.swift; sourceTree = "<group>"; };
|
B8B32020258B1A650020074B /* Contact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contact.swift; sourceTree = "<group>"; };
|
||||||
B8B32032258B235D0020074B /* Storage+Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+Contacts.swift"; sourceTree = "<group>"; };
|
B8B32032258B235D0020074B /* Storage+Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+Contacts.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -2175,7 +2169,6 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
34A8B3502190A40E00218A25 /* MediaAlbumView.swift */,
|
34A8B3502190A40E00218A25 /* MediaAlbumView.swift */,
|
||||||
B8569AD225CBA13D00DBA3DB /* MediaTextOverlayView.swift */,
|
|
||||||
3488F9352191CC4000E524CC /* MediaView.swift */,
|
3488F9352191CC4000E524CC /* MediaView.swift */,
|
||||||
B8041A9425C8FA1D003C2166 /* MediaLoaderView.swift */,
|
B8041A9425C8FA1D003C2166 /* MediaLoaderView.swift */,
|
||||||
B8F5F71925F1B35C003BF8D4 /* MediaPlaceholderView.swift */,
|
B8F5F71925F1B35C003BF8D4 /* MediaPlaceholderView.swift */,
|
||||||
|
@ -3225,8 +3218,6 @@
|
||||||
C3BBE0C62554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift */,
|
C3BBE0C62554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift */,
|
||||||
C33FDB7F255A581100E217F9 /* FullTextSearchFinder.swift */,
|
C33FDB7F255A581100E217F9 /* FullTextSearchFinder.swift */,
|
||||||
C33FDBC1255A581700E217F9 /* General.swift */,
|
C33FDBC1255A581700E217F9 /* General.swift */,
|
||||||
B8AE760925ABFB00001A84D2 /* GeneralUtilities.h */,
|
|
||||||
B8AE760A25ABFB5A001A84D2 /* GeneralUtilities.m */,
|
|
||||||
B82A0C3726B9098200C1BCE3 /* MessageInvalidator.swift */,
|
B82A0C3726B9098200C1BCE3 /* MessageInvalidator.swift */,
|
||||||
C3A71D0A2558989C0043A11F /* MessageWrapper.swift */,
|
C3A71D0A2558989C0043A11F /* MessageWrapper.swift */,
|
||||||
C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */,
|
C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */,
|
||||||
|
@ -3789,7 +3780,6 @@
|
||||||
C32C5BF8256DC8F6003C73A2 /* OWSDisappearingMessagesJob.h in Headers */,
|
C32C5BF8256DC8F6003C73A2 /* OWSDisappearingMessagesJob.h in Headers */,
|
||||||
C32C5AAA256DBE8F003C73A2 /* TSIncomingMessage.h in Headers */,
|
C32C5AAA256DBE8F003C73A2 /* TSIncomingMessage.h in Headers */,
|
||||||
B8856D72256F1421001CE70E /* OWSWindowManager.h in Headers */,
|
B8856D72256F1421001CE70E /* OWSWindowManager.h in Headers */,
|
||||||
B8AE761425ABFBB9001A84D2 /* GeneralUtilities.h in Headers */,
|
|
||||||
C32C5B6B256DC357003C73A2 /* OWSDisappearingConfigurationUpdateInfoMessage.h in Headers */,
|
C32C5B6B256DC357003C73A2 /* OWSDisappearingConfigurationUpdateInfoMessage.h in Headers */,
|
||||||
C32C5BBA256DC7E3003C73A2 /* ProfileManagerProtocol.h in Headers */,
|
C32C5BBA256DC7E3003C73A2 /* ProfileManagerProtocol.h in Headers */,
|
||||||
C3A3A193256E20D4004D228D /* SignalRecipient.h in Headers */,
|
C3A3A193256E20D4004D228D /* SignalRecipient.h in Headers */,
|
||||||
|
@ -4782,7 +4772,6 @@
|
||||||
C32C5E5B256DDF45003C73A2 /* OWSStorage.m in Sources */,
|
C32C5E5B256DDF45003C73A2 /* OWSStorage.m in Sources */,
|
||||||
C32C5E15256DDC78003C73A2 /* SSKPreferences.swift in Sources */,
|
C32C5E15256DDC78003C73A2 /* SSKPreferences.swift in Sources */,
|
||||||
C32C5D9C256DD6DC003C73A2 /* OWSOutgoingReceiptManager.m in Sources */,
|
C32C5D9C256DD6DC003C73A2 /* OWSOutgoingReceiptManager.m in Sources */,
|
||||||
B8AE760B25ABFB5A001A84D2 /* GeneralUtilities.m in Sources */,
|
|
||||||
C32C5C4F256DCC36003C73A2 /* Storage+OpenGroups.swift in Sources */,
|
C32C5C4F256DCC36003C73A2 /* Storage+OpenGroups.swift in Sources */,
|
||||||
C3DA9C0725AE7396008F7C7E /* ConfigurationMessage.swift in Sources */,
|
C3DA9C0725AE7396008F7C7E /* ConfigurationMessage.swift in Sources */,
|
||||||
B8856CEE256F1054001CE70E /* OWSAudioPlayer.m in Sources */,
|
B8856CEE256F1054001CE70E /* OWSAudioPlayer.m in Sources */,
|
||||||
|
@ -4949,7 +4938,6 @@
|
||||||
341341EF2187467A00192D59 /* ConversationViewModel.m in Sources */,
|
341341EF2187467A00192D59 /* ConversationViewModel.m in Sources */,
|
||||||
4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */,
|
4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */,
|
||||||
C331FFF32558FF0300070591 /* PathStatusView.swift in Sources */,
|
C331FFF32558FF0300070591 /* PathStatusView.swift in Sources */,
|
||||||
B8569AD325CBA13D00DBA3DB /* MediaTextOverlayView.swift in Sources */,
|
|
||||||
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
|
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
|
||||||
B848A4C5269EAAA200617031 /* UserDetailsSheet.swift in Sources */,
|
B848A4C5269EAAA200617031 /* UserDetailsSheet.swift in Sources */,
|
||||||
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,
|
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,
|
||||||
|
@ -5185,7 +5173,7 @@
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 327;
|
CURRENT_PROJECT_VERSION = 329;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||||
|
@ -5210,7 +5198,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.11.22;
|
MARKETING_VERSION = 1.11.23;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -5258,7 +5246,7 @@
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 327;
|
CURRENT_PROJECT_VERSION = 329;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
@ -5288,7 +5276,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.11.22;
|
MARKETING_VERSION = 1.11.23;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -5324,7 +5312,7 @@
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 327;
|
CURRENT_PROJECT_VERSION = 329;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||||
|
@ -5347,7 +5335,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.11.22;
|
MARKETING_VERSION = 1.11.23;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
|
||||||
|
@ -5398,7 +5386,7 @@
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 327;
|
CURRENT_PROJECT_VERSION = 329;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
@ -5426,7 +5414,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.11.22;
|
MARKETING_VERSION = 1.11.23;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
|
||||||
|
@ -6334,7 +6322,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CURRENT_PROJECT_VERSION = 327;
|
CURRENT_PROJECT_VERSION = 329;
|
||||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -6373,7 +6361,7 @@
|
||||||
"$(SRCROOT)",
|
"$(SRCROOT)",
|
||||||
);
|
);
|
||||||
LLVM_LTO = NO;
|
LLVM_LTO = NO;
|
||||||
MARKETING_VERSION = 1.11.22;
|
MARKETING_VERSION = 1.11.23;
|
||||||
OTHER_LDFLAGS = "$(inherited)";
|
OTHER_LDFLAGS = "$(inherited)";
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
|
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
|
||||||
|
@ -6405,7 +6393,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CURRENT_PROJECT_VERSION = 327;
|
CURRENT_PROJECT_VERSION = 329;
|
||||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -6444,7 +6432,7 @@
|
||||||
"$(SRCROOT)",
|
"$(SRCROOT)",
|
||||||
);
|
);
|
||||||
LLVM_LTO = NO;
|
LLVM_LTO = NO;
|
||||||
MARKETING_VERSION = 1.11.22;
|
MARKETING_VERSION = 1.11.23;
|
||||||
OTHER_LDFLAGS = "$(inherited)";
|
OTHER_LDFLAGS = "$(inherited)";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
|
||||||
PRODUCT_NAME = Session;
|
PRODUCT_NAME = Session;
|
||||||
|
|
|
@ -544,14 +544,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
||||||
} else {
|
} else {
|
||||||
guard let albumView = cell.albumView else { return }
|
guard let albumView = cell.albumView else { return }
|
||||||
let locationInCell = gestureRecognizer.location(in: cell)
|
let locationInCell = gestureRecognizer.location(in: cell)
|
||||||
// Figure out whether the "read more" button was tapped
|
// Figure out which of the media views was tapped
|
||||||
if let overlayView = cell.mediaTextOverlayView {
|
|
||||||
let locationInOverlayView = cell.convert(locationInCell, to: overlayView)
|
|
||||||
if let readMoreButton = overlayView.readMoreButton, readMoreButton.frame.contains(locationInOverlayView) {
|
|
||||||
return showFullText(viewItem) // HACK: This is a dirty way to do this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Otherwise, figure out which of the media views was tapped
|
|
||||||
let locationInAlbumView = cell.convert(locationInCell, to: albumView)
|
let locationInAlbumView = cell.convert(locationInCell, to: albumView)
|
||||||
guard let mediaView = albumView.mediaView(forLocation: locationInAlbumView) else { return }
|
guard let mediaView = albumView.mediaView(forLocation: locationInAlbumView) else { return }
|
||||||
if albumView.isMoreItemsView(mediaView: mediaView) && viewItem.mediaAlbumHasFailedAttachment() {
|
if albumView.isMoreItemsView(mediaView: mediaView) && viewItem.mediaAlbumHasFailedAttachment() {
|
||||||
|
@ -590,10 +583,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
||||||
navigationController!.present(shareVC, animated: true, completion: nil)
|
navigationController!.present(shareVC, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
case .textOnlyMessage:
|
case .textOnlyMessage:
|
||||||
if let preview = viewItem.linkPreview, let urlAsString = preview.urlString, let url = URL(string: urlAsString) {
|
if let reply = viewItem.quotedReply {
|
||||||
// Open the link preview URL
|
|
||||||
openURL(url)
|
|
||||||
} else if let reply = viewItem.quotedReply {
|
|
||||||
// Scroll to the source of the reply
|
// Scroll to the source of the reply
|
||||||
guard let indexPath = viewModel.ensureLoadWindowContainsQuotedReply(reply) else { return }
|
guard let indexPath = viewModel.ensureLoadWindowContainsQuotedReply(reply) else { return }
|
||||||
messagesTableView.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.middle, animated: true)
|
messagesTableView.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.middle, animated: true)
|
||||||
|
|
|
@ -12,6 +12,7 @@ final class LinkPreviewView : UIView {
|
||||||
let isOutgoing = (viewItem!.interaction.interactionType() == .outgoingMessage)
|
let isOutgoing = (viewItem!.interaction.interactionType() == .outgoingMessage)
|
||||||
switch (isOutgoing, AppModeManager.shared.currentAppMode) {
|
switch (isOutgoing, AppModeManager.shared.currentAppMode) {
|
||||||
case (true, .dark), (false, .light): return .black
|
case (true, .dark), (false, .light): return .black
|
||||||
|
case (true, .light): return Colors.grey
|
||||||
default: return .white
|
default: return .white
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -57,6 +58,8 @@ final class LinkPreviewView : UIView {
|
||||||
result.addTarget(self, action: #selector(cancel), for: UIControl.Event.touchUpInside)
|
result.addTarget(self, action: #selector(cancel), for: UIControl.Event.touchUpInside)
|
||||||
return result
|
return result
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var bodyTextView: UITextView?
|
||||||
|
|
||||||
// MARK: Settings
|
// MARK: Settings
|
||||||
private static let loaderSize: CGFloat = 24
|
private static let loaderSize: CGFloat = 24
|
||||||
|
@ -133,15 +136,7 @@ final class LinkPreviewView : UIView {
|
||||||
loader.alpha = (image != nil) ? 0 : 1
|
loader.alpha = (image != nil) ? 0 : 1
|
||||||
if image != nil { loader.stopAnimating() } else { loader.startAnimating() }
|
if image != nil { loader.stopAnimating() } else { loader.startAnimating() }
|
||||||
// Title
|
// Title
|
||||||
let isSent = (linkPreviewState is LinkPreviewSent)
|
titleLabel.textColor = sentLinkPreviewTextColor
|
||||||
let isOutgoing = (viewItem?.interaction.interactionType() == .outgoingMessage)
|
|
||||||
let textColor: UIColor
|
|
||||||
if isSent && isOutgoing && isLightMode {
|
|
||||||
textColor = .white
|
|
||||||
} else {
|
|
||||||
textColor = isDarkMode ? .white : .black
|
|
||||||
}
|
|
||||||
titleLabel.textColor = textColor
|
|
||||||
titleLabel.text = linkPreviewState.title()
|
titleLabel.text = linkPreviewState.title()
|
||||||
// Horizontal stack view
|
// Horizontal stack view
|
||||||
switch linkPreviewState {
|
switch linkPreviewState {
|
||||||
|
@ -152,6 +147,7 @@ final class LinkPreviewView : UIView {
|
||||||
bodyTextViewContainer.subviews.forEach { $0.removeFromSuperview() }
|
bodyTextViewContainer.subviews.forEach { $0.removeFromSuperview() }
|
||||||
if let viewItem = viewItem {
|
if let viewItem = viewItem {
|
||||||
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: sentLinkPreviewTextColor, searchText: delegate.lastSearchedText, delegate: delegate)
|
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: sentLinkPreviewTextColor, searchText: delegate.lastSearchedText, delegate: delegate)
|
||||||
|
self.bodyTextView = bodyTextView
|
||||||
bodyTextViewContainer.addSubview(bodyTextView)
|
bodyTextViewContainer.addSubview(bodyTextView)
|
||||||
bodyTextView.pin(to: bodyTextViewContainer, withInset: 12)
|
bodyTextView.pin(to: bodyTextViewContainer, withInset: 12)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
import UIKit
|
|
||||||
|
|
||||||
/// Shown over a media message if it has a message body.
|
|
||||||
final class MediaTextOverlayView : UIView {
|
|
||||||
private let viewItem: ConversationViewItem
|
|
||||||
private let albumViewWidth: CGFloat
|
|
||||||
private let delegate: MessageCellDelegate
|
|
||||||
private let textColor: UIColor
|
|
||||||
var readMoreButton: UIButton?
|
|
||||||
|
|
||||||
// MARK: Settings
|
|
||||||
private static let maxHeight: CGFloat = 88;
|
|
||||||
|
|
||||||
// MARK: Lifecycle
|
|
||||||
init(viewItem: ConversationViewItem, albumViewWidth: CGFloat, textColor: UIColor, delegate: MessageCellDelegate) {
|
|
||||||
self.viewItem = viewItem
|
|
||||||
self.albumViewWidth = albumViewWidth
|
|
||||||
self.delegate = delegate
|
|
||||||
self.textColor = textColor
|
|
||||||
super.init(frame: CGRect.zero)
|
|
||||||
setUpViewHierarchy()
|
|
||||||
}
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
preconditionFailure("Use init(text:) instead.")
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
preconditionFailure("Use init(text:) instead.")
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setUpViewHierarchy() {
|
|
||||||
guard let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0 else { return }
|
|
||||||
// Body label
|
|
||||||
let bodyLabel = UILabel()
|
|
||||||
bodyLabel.numberOfLines = 0
|
|
||||||
bodyLabel.lineBreakMode = .byTruncatingTail
|
|
||||||
bodyLabel.text = given(body) { MentionUtilities.highlightMentions(in: $0, threadID: viewItem.interaction.uniqueThreadId) }
|
|
||||||
bodyLabel.textColor = self.textColor
|
|
||||||
bodyLabel.font = .systemFont(ofSize: Values.mediumFontSize)
|
|
||||||
// Content stack view
|
|
||||||
let contentStackView = UIStackView(arrangedSubviews: [ bodyLabel ])
|
|
||||||
contentStackView.axis = .horizontal
|
|
||||||
contentStackView.spacing = Values.smallSpacing
|
|
||||||
addSubview(contentStackView)
|
|
||||||
let inset: CGFloat = 12
|
|
||||||
contentStackView.pin(.left, to: .left, of: self, withInset: inset)
|
|
||||||
contentStackView.pin(.top, to: .top, of: self)
|
|
||||||
contentStackView.pin(.right, to: .right, of: self, withInset: -inset)
|
|
||||||
// Max height
|
|
||||||
bodyLabel.heightAnchor.constraint(lessThanOrEqualToConstant: MediaTextOverlayView.maxHeight).isActive = true
|
|
||||||
// Overflow button
|
|
||||||
let bodyLabelTargetSize = bodyLabel.sizeThatFits(CGSize(width: albumViewWidth - 2 * inset, height: .greatestFiniteMagnitude))
|
|
||||||
if bodyLabelTargetSize.height > MediaTextOverlayView.maxHeight {
|
|
||||||
let readMoreButton = UIButton()
|
|
||||||
self.readMoreButton = readMoreButton
|
|
||||||
readMoreButton.setTitle("Read More", for: UIControl.State.normal)
|
|
||||||
readMoreButton.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize)
|
|
||||||
readMoreButton.setTitleColor(self.textColor, for: UIControl.State.normal)
|
|
||||||
readMoreButton.addTarget(self, action: #selector(readMore), for: UIControl.Event.touchUpInside)
|
|
||||||
addSubview(readMoreButton)
|
|
||||||
readMoreButton.pin(.left, to: .left, of: self, withInset: inset)
|
|
||||||
readMoreButton.pin(.top, to: .bottom, of: contentStackView, withInset: Values.smallSpacing)
|
|
||||||
readMoreButton.pin(.bottom, to: .bottom, of: self, withInset: -Values.smallSpacing)
|
|
||||||
} else {
|
|
||||||
contentStackView.pin(.bottom, to: .bottom, of: self, withInset: -inset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Interaction
|
|
||||||
@objc private func readMore() {
|
|
||||||
delegate.showFullText(viewItem)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,6 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
||||||
private var previousX: CGFloat = 0
|
private var previousX: CGFloat = 0
|
||||||
var albumView: MediaAlbumView?
|
var albumView: MediaAlbumView?
|
||||||
var bodyTextView: UITextView?
|
var bodyTextView: UITextView?
|
||||||
var mediaTextOverlayView: MediaTextOverlayView?
|
|
||||||
// Constraints
|
// Constraints
|
||||||
private lazy var headerViewTopConstraint = headerView.pin(.top, to: .top, of: self, withInset: 1)
|
private lazy var headerViewTopConstraint = headerView.pin(.top, to: .top, of: self, withInset: 1)
|
||||||
private lazy var authorLabelHeightConstraint = authorLabel.set(.height, to: 0)
|
private lazy var authorLabelHeightConstraint = authorLabel.set(.height, to: 0)
|
||||||
|
@ -254,8 +253,9 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
||||||
let authorLabelSize = authorLabel.sizeThatFits(authorLabelAvailableSpace)
|
let authorLabelSize = authorLabel.sizeThatFits(authorLabelAvailableSpace)
|
||||||
authorLabelHeightConstraint.constant = (viewItem.senderName != nil) ? authorLabelSize.height : 0
|
authorLabelHeightConstraint.constant = (viewItem.senderName != nil) ? authorLabelSize.height : 0
|
||||||
// Message status image view
|
// Message status image view
|
||||||
let (image, backgroundColor) = getMessageStatusImage(for: message)
|
let (image, tintColor, backgroundColor) = getMessageStatusImage(for: message)
|
||||||
messageStatusImageView.image = image
|
messageStatusImageView.image = image
|
||||||
|
messageStatusImageView.tintColor = tintColor
|
||||||
messageStatusImageView.backgroundColor = backgroundColor
|
messageStatusImageView.backgroundColor = backgroundColor
|
||||||
if let message = message as? TSOutgoingMessage {
|
if let message = message as? TSOutgoingMessage {
|
||||||
messageStatusImageView.isHidden = (message.messageState == .sent && thread?.lastInteraction != message)
|
messageStatusImageView.isHidden = (message.messageState == .sent && thread?.lastInteraction != message)
|
||||||
|
@ -312,7 +312,6 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
||||||
}
|
}
|
||||||
albumView = nil
|
albumView = nil
|
||||||
bodyTextView = nil
|
bodyTextView = nil
|
||||||
mediaTextOverlayView = nil
|
|
||||||
let isOutgoing = (viewItem.interaction.interactionType() == .outgoingMessage)
|
let isOutgoing = (viewItem.interaction.interactionType() == .outgoingMessage)
|
||||||
switch viewItem.messageCellType {
|
switch viewItem.messageCellType {
|
||||||
case .textOnlyMessage:
|
case .textOnlyMessage:
|
||||||
|
@ -324,6 +323,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
||||||
snContentView.addSubview(linkPreviewView)
|
snContentView.addSubview(linkPreviewView)
|
||||||
linkPreviewView.pin(to: snContentView)
|
linkPreviewView.pin(to: snContentView)
|
||||||
linkPreviewView.layer.mask = bubbleViewMaskLayer
|
linkPreviewView.layer.mask = bubbleViewMaskLayer
|
||||||
|
self.bodyTextView = linkPreviewView.bodyTextView
|
||||||
} else if let openGroupInvitationName = message.openGroupInvitationName, let openGroupInvitationURL = message.openGroupInvitationURL {
|
} else if let openGroupInvitationName = message.openGroupInvitationName, let openGroupInvitationURL = message.openGroupInvitationURL {
|
||||||
let openGroupInvitationView = OpenGroupInvitationView(name: openGroupInvitationName, url: openGroupInvitationURL, textColor: bodyLabelTextColor, isOutgoing: isOutgoing)
|
let openGroupInvitationView = OpenGroupInvitationView(name: openGroupInvitationName, url: openGroupInvitationURL, textColor: bodyLabelTextColor, isOutgoing: isOutgoing)
|
||||||
snContentView.addSubview(openGroupInvitationView)
|
snContentView.addSubview(openGroupInvitationView)
|
||||||
|
@ -372,11 +372,12 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
||||||
albumView.layer.mask = bubbleViewMaskLayer
|
albumView.layer.mask = bubbleViewMaskLayer
|
||||||
stackView.addArrangedSubview(albumView)
|
stackView.addArrangedSubview(albumView)
|
||||||
// Body text view
|
// Body text view
|
||||||
if let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0,
|
if let message = viewItem.interaction as? TSMessage, let body = message.body, body.count > 0 {
|
||||||
let delegate = delegate { // delegate should always be set at this point
|
let inset: CGFloat = 12
|
||||||
let overlayView = MediaTextOverlayView(viewItem: viewItem, albumViewWidth: size.width, textColor: bodyLabelTextColor, delegate: delegate)
|
let maxWidth = size.width - 2 * inset
|
||||||
self.mediaTextOverlayView = overlayView
|
let bodyTextView = VisibleMessageCell.getBodyTextView(for: viewItem, with: maxWidth, textColor: bodyLabelTextColor, searchText: delegate?.lastSearchedText, delegate: self)
|
||||||
stackView.addArrangedSubview(overlayView)
|
self.bodyTextView = bodyTextView
|
||||||
|
stackView.addArrangedSubview(UIView(wrapping: bodyTextView, withInsets: UIEdgeInsets(top: 0, left: inset, bottom: inset, right: inset)))
|
||||||
}
|
}
|
||||||
unloadContent = { albumView.unloadMedia() }
|
unloadContent = { albumView.unloadMedia() }
|
||||||
// Constraints
|
// Constraints
|
||||||
|
@ -612,20 +613,33 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getMessageStatusImage(for message: TSMessage) -> (image: UIImage?, backgroundColor: UIColor?) {
|
private func getMessageStatusImage(for message: TSMessage) -> (image: UIImage?, tintColor: UIColor?, backgroundColor: UIColor?) {
|
||||||
guard let message = message as? TSOutgoingMessage else { return (nil, nil) }
|
guard let message = message as? TSOutgoingMessage else { return (nil, nil, nil) }
|
||||||
|
|
||||||
let image: UIImage
|
let image: UIImage
|
||||||
|
var tintColor: UIColor? = nil
|
||||||
var backgroundColor: UIColor? = nil
|
var backgroundColor: UIColor? = nil
|
||||||
let status = MessageRecipientStatusUtils.recipientStatus(outgoingMessage: message)
|
let status = MessageRecipientStatusUtils.recipientStatus(outgoingMessage: message)
|
||||||
|
|
||||||
switch status {
|
switch status {
|
||||||
case .uploading, .sending: image = #imageLiteral(resourceName: "CircleDotDotDot").asTintedImage(color: Colors.text)!
|
case .uploading, .sending:
|
||||||
case .sent, .skipped, .delivered: image = #imageLiteral(resourceName: "CircleCheck").asTintedImage(color: Colors.text)!
|
image = #imageLiteral(resourceName: "CircleDotDotDot").withRenderingMode(.alwaysTemplate)
|
||||||
case .read:
|
tintColor = Colors.text
|
||||||
backgroundColor = isLightMode ? .black : .white
|
|
||||||
image = isLightMode ? #imageLiteral(resourceName: "FilledCircleCheckLightMode") : #imageLiteral(resourceName: "FilledCircleCheckDarkMode")
|
case .sent, .skipped, .delivered:
|
||||||
case .failed: image = #imageLiteral(resourceName: "message_status_failed").asTintedImage(color: Colors.destructive)!
|
image = #imageLiteral(resourceName: "CircleCheck").withRenderingMode(.alwaysTemplate)
|
||||||
|
tintColor = Colors.text
|
||||||
|
|
||||||
|
case .read:
|
||||||
|
image = isLightMode ? #imageLiteral(resourceName: "FilledCircleCheckLightMode") : #imageLiteral(resourceName: "FilledCircleCheckDarkMode")
|
||||||
|
backgroundColor = isLightMode ? .black : .white
|
||||||
|
|
||||||
|
case .failed:
|
||||||
|
image = #imageLiteral(resourceName: "message_status_failed").withRenderingMode(.alwaysTemplate)
|
||||||
|
tintColor = Colors.destructive
|
||||||
}
|
}
|
||||||
return (image, backgroundColor)
|
|
||||||
|
return (image, tintColor, backgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getSize(for viewItem: ConversationViewItem) -> CGSize {
|
private func getSize(for viewItem: ConversationViewItem) -> CGSize {
|
||||||
|
|
|
@ -25,7 +25,7 @@ final class NewConversationButtonSet : UIView {
|
||||||
private lazy var newDMLabel: UILabel = {
|
private lazy var newDMLabel: UILabel = {
|
||||||
let result: UILabel = UILabel()
|
let result: UILabel = UILabel()
|
||||||
result.translatesAutoresizingMaskIntoConstraints = false
|
result.translatesAutoresizingMaskIntoConstraints = false
|
||||||
result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize)
|
result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize, weight: .bold)
|
||||||
result.text = NSLocalizedString("NEW_CONVERSATION_MENU_DIRECT_MESSAGE", comment: "").uppercased()
|
result.text = NSLocalizedString("NEW_CONVERSATION_MENU_DIRECT_MESSAGE", comment: "").uppercased()
|
||||||
result.textColor = Colors.grey
|
result.textColor = Colors.grey
|
||||||
result.textAlignment = .center
|
result.textAlignment = .center
|
||||||
|
@ -36,7 +36,7 @@ final class NewConversationButtonSet : UIView {
|
||||||
private lazy var createClosedGroupLabel: UILabel = {
|
private lazy var createClosedGroupLabel: UILabel = {
|
||||||
let result: UILabel = UILabel()
|
let result: UILabel = UILabel()
|
||||||
result.translatesAutoresizingMaskIntoConstraints = false
|
result.translatesAutoresizingMaskIntoConstraints = false
|
||||||
result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize)
|
result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize, weight: .bold)
|
||||||
result.text = NSLocalizedString("NEW_CONVERSATION_MENU_CLOSED_GROUP", comment: "").uppercased()
|
result.text = NSLocalizedString("NEW_CONVERSATION_MENU_CLOSED_GROUP", comment: "").uppercased()
|
||||||
result.textColor = Colors.grey
|
result.textColor = Colors.grey
|
||||||
result.textAlignment = .center
|
result.textAlignment = .center
|
||||||
|
@ -47,7 +47,7 @@ final class NewConversationButtonSet : UIView {
|
||||||
private lazy var joinOpenGroupLabel: UILabel = {
|
private lazy var joinOpenGroupLabel: UILabel = {
|
||||||
let result: UILabel = UILabel()
|
let result: UILabel = UILabel()
|
||||||
result.translatesAutoresizingMaskIntoConstraints = false
|
result.translatesAutoresizingMaskIntoConstraints = false
|
||||||
result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize)
|
result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize, weight: .bold)
|
||||||
result.text = NSLocalizedString("NEW_CONVERSATION_MENU_OPEN_GROUP", comment: "").uppercased()
|
result.text = NSLocalizedString("NEW_CONVERSATION_MENU_OPEN_GROUP", comment: "").uppercased()
|
||||||
result.textColor = Colors.grey
|
result.textColor = Colors.grey
|
||||||
result.textAlignment = .center
|
result.textAlignment = .center
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
import UIKit
|
||||||
|
import SessionUIKit
|
||||||
import SessionSnodeKit
|
import SessionSnodeKit
|
||||||
|
import SessionMessagingKit
|
||||||
|
|
||||||
@objc(LKNukeDataModal)
|
@objc(LKNukeDataModal)
|
||||||
final class NukeDataModal : Modal {
|
final class NukeDataModal : Modal {
|
||||||
|
@ -125,6 +128,7 @@ final class NukeDataModal : Modal {
|
||||||
appDelegate.forceSyncConfigurationNowIfNeeded().ensure(on: DispatchQueue.main) {
|
appDelegate.forceSyncConfigurationNowIfNeeded().ensure(on: DispatchQueue.main) {
|
||||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||||
UserDefaults.removeAll() // Not done in the nuke data implementation as unlinking requires this to happen later
|
UserDefaults.removeAll() // Not done in the nuke data implementation as unlinking requires this to happen later
|
||||||
|
General.Cache.cachedEncodedPublicKey = nil // Remove the cached key so it gets re-cached on next access
|
||||||
NotificationCenter.default.post(name: .dataNukeRequested, object: nil)
|
NotificationCenter.default.post(name: .dataNukeRequested, object: nil)
|
||||||
}.retainUntilComplete()
|
}.retainUntilComplete()
|
||||||
}
|
}
|
||||||
|
@ -136,6 +140,7 @@ final class NukeDataModal : Modal {
|
||||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||||
let potentiallyMaliciousSnodes = confirmations.compactMap { $0.value == false ? $0.key : nil }
|
let potentiallyMaliciousSnodes = confirmations.compactMap { $0.value == false ? $0.key : nil }
|
||||||
if potentiallyMaliciousSnodes.isEmpty {
|
if potentiallyMaliciousSnodes.isEmpty {
|
||||||
|
General.Cache.cachedEncodedPublicKey = nil // Remove the cached key so it gets re-cached on next access
|
||||||
UserDefaults.removeAll() // Not done in the nuke data implementation as unlinking requires this to happen later
|
UserDefaults.removeAll() // Not done in the nuke data implementation as unlinking requires this to happen later
|
||||||
NotificationCenter.default.post(name: .dataNukeRequested, object: nil)
|
NotificationCenter.default.post(name: .dataNukeRequested, object: nil)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -106,6 +106,9 @@ class BaseVC : UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
SNLog("Current trait collection: \(UITraitCollection.current), previous trait collection: \(previousTraitCollection)")
|
||||||
|
}
|
||||||
if LKAppModeUtilities.isSystemDefault {
|
if LKAppModeUtilities.isSystemDefault {
|
||||||
NotificationCenter.default.post(name: .appModeChanged, object: nil)
|
NotificationCenter.default.post(name: .appModeChanged, object: nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,19 +321,30 @@ final class ConversationCell : UITableViewCell {
|
||||||
statusIndicatorView.backgroundColor = nil
|
statusIndicatorView.backgroundColor = nil
|
||||||
let lastMessage = threadViewModel.lastMessageForInbox
|
let lastMessage = threadViewModel.lastMessageForInbox
|
||||||
if let lastMessage = lastMessage as? TSOutgoingMessage {
|
if let lastMessage = lastMessage as? TSOutgoingMessage {
|
||||||
let image: UIImage
|
|
||||||
let status = MessageRecipientStatusUtils.recipientStatus(outgoingMessage: lastMessage)
|
let status = MessageRecipientStatusUtils.recipientStatus(outgoingMessage: lastMessage)
|
||||||
|
|
||||||
switch status {
|
switch status {
|
||||||
case .uploading, .sending: image = #imageLiteral(resourceName: "CircleDotDotDot").asTintedImage(color: Colors.text)!
|
case .uploading, .sending:
|
||||||
case .sent, .skipped, .delivered: image = #imageLiteral(resourceName: "CircleCheck").asTintedImage(color: Colors.text)!
|
statusIndicatorView.image = #imageLiteral(resourceName: "CircleDotDotDot").withRenderingMode(.alwaysTemplate)
|
||||||
case .read:
|
statusIndicatorView.tintColor = Colors.text
|
||||||
statusIndicatorView.backgroundColor = isLightMode ? .black : .white
|
|
||||||
image = isLightMode ? #imageLiteral(resourceName: "FilledCircleCheckLightMode") : #imageLiteral(resourceName: "FilledCircleCheckDarkMode")
|
case .sent, .skipped, .delivered:
|
||||||
case .failed: image = #imageLiteral(resourceName: "message_status_failed").asTintedImage(color: Colors.text)!
|
statusIndicatorView.image = #imageLiteral(resourceName: "CircleCheck").withRenderingMode(.alwaysTemplate)
|
||||||
|
statusIndicatorView.tintColor = Colors.text
|
||||||
|
|
||||||
|
case .read:
|
||||||
|
statusIndicatorView.image = isLightMode ? #imageLiteral(resourceName: "FilledCircleCheckLightMode") : #imageLiteral(resourceName: "FilledCircleCheckDarkMode")
|
||||||
|
statusIndicatorView.tintColor = nil
|
||||||
|
statusIndicatorView.backgroundColor = (isLightMode ? .black : .white)
|
||||||
|
|
||||||
|
case .failed:
|
||||||
|
statusIndicatorView.image = #imageLiteral(resourceName: "message_status_failed").withRenderingMode(.alwaysTemplate)
|
||||||
|
statusIndicatorView.tintColor = Colors.destructive
|
||||||
}
|
}
|
||||||
statusIndicatorView.image = image
|
|
||||||
statusIndicatorView.isHidden = false
|
statusIndicatorView.isHidden = false
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
statusIndicatorView.isHidden = true
|
statusIndicatorView.isHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,16 +83,22 @@ final class UserCell : UITableViewCell {
|
||||||
profilePictureView.publicKey = publicKey
|
profilePictureView.publicKey = publicKey
|
||||||
profilePictureView.update()
|
profilePictureView.update()
|
||||||
displayNameLabel.text = Storage.shared.getContact(with: publicKey)?.displayName(for: .regular) ?? publicKey
|
displayNameLabel.text = Storage.shared.getContact(with: publicKey)?.displayName(for: .regular) ?? publicKey
|
||||||
|
|
||||||
switch accessory {
|
switch accessory {
|
||||||
case .none: accessoryImageView.isHidden = true
|
case .none: accessoryImageView.isHidden = true
|
||||||
case .lock:
|
|
||||||
accessoryImageView.isHidden = false
|
case .lock:
|
||||||
accessoryImageView.image = #imageLiteral(resourceName: "ic_lock_outline").asTintedImage(color: Colors.text.withAlphaComponent(Values.mediumOpacity))!
|
accessoryImageView.isHidden = false
|
||||||
case .tick(let isSelected):
|
accessoryImageView.image = #imageLiteral(resourceName: "ic_lock_outline").withRenderingMode(.alwaysTemplate)
|
||||||
accessoryImageView.isHidden = false
|
accessoryImageView.tintColor = Colors.text.withAlphaComponent(Values.mediumOpacity)
|
||||||
let icon = isSelected ? #imageLiteral(resourceName: "CircleCheck") : #imageLiteral(resourceName: "Circle")
|
|
||||||
accessoryImageView.image = isDarkMode ? icon : icon.asTintedImage(color: Colors.text)!
|
case .tick(let isSelected):
|
||||||
|
let icon: UIImage = (isSelected ? #imageLiteral(resourceName: "CircleCheck") : #imageLiteral(resourceName: "Circle"))
|
||||||
|
accessoryImageView.isHidden = false
|
||||||
|
accessoryImageView.image = icon.withRenderingMode(.alwaysTemplate)
|
||||||
|
accessoryImageView.tintColor = Colors.text
|
||||||
}
|
}
|
||||||
|
|
||||||
let alpha: CGFloat = isZombie ? 0.5 : 1
|
let alpha: CGFloat = isZombie ? 0.5 : 1
|
||||||
[ profilePictureView, displayNameLabel, accessoryImageView ].forEach { $0.alpha = alpha }
|
[ profilePictureView, displayNameLabel, accessoryImageView ].forEach { $0.alpha = alpha }
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ extension ConfigurationMessage {
|
||||||
hasIsApproved: true,
|
hasIsApproved: true,
|
||||||
isApproved: contact.isApproved,
|
isApproved: contact.isApproved,
|
||||||
hasIsBlocked: true,
|
hasIsBlocked: true,
|
||||||
isBlocked: contact.isBlocked,
|
isBlocked: SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(contact.sessionID),
|
||||||
hasDidApproveMe: true,
|
hasDidApproveMe: true,
|
||||||
didApproveMe: contact.didApproveMe
|
didApproveMe: contact.didApproveMe
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,6 @@ FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[];
|
||||||
|
|
||||||
#import <SessionMessagingKit/AppReadiness.h>
|
#import <SessionMessagingKit/AppReadiness.h>
|
||||||
#import <SessionMessagingKit/Environment.h>
|
#import <SessionMessagingKit/Environment.h>
|
||||||
#import <SessionMessagingKit/GeneralUtilities.h>
|
|
||||||
#import <SessionMessagingKit/NotificationsProtocol.h>
|
#import <SessionMessagingKit/NotificationsProtocol.h>
|
||||||
#import <SessionMessagingKit/NSData+messagePadding.h>
|
#import <SessionMessagingKit/NSData+messagePadding.h>
|
||||||
#import <SessionMessagingKit/OWSAudioPlayer.h>
|
#import <SessionMessagingKit/OWSAudioPlayer.h>
|
||||||
|
|
|
@ -18,6 +18,7 @@ public final class OpenGroupAPIV2 : NSObject {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// MARK: Settings
|
// MARK: Settings
|
||||||
|
public static let legacyDefaultServerDNS = "open.getsession.org"
|
||||||
public static let defaultServer = "http://116.203.70.33"
|
public static let defaultServer = "http://116.203.70.33"
|
||||||
public static let defaultServerPublicKey = "a03c383cf63c3c4efe67acc52112a6dd734b3a946b9545f488aaa93da7991238"
|
public static let defaultServerPublicKey = "a03c383cf63c3c4efe67acc52112a6dd734b3a946b9545f488aaa93da7991238"
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,57 @@ public final class OpenGroupManagerV2 : NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Adding & Removing
|
// MARK: Adding & Removing
|
||||||
|
|
||||||
|
public func hasExistingOpenGroup(room: String, server: String, publicKey: String, using transaction: YapDatabaseReadWriteTransaction) -> Bool {
|
||||||
|
guard let serverUrl: URL = URL(string: server) else { return false }
|
||||||
|
|
||||||
|
let serverHost: String = (serverUrl.host ?? server)
|
||||||
|
let serverPort: String = (serverUrl.port.map { ":\($0)" } ?? "")
|
||||||
|
let defaultServerHost: String = OpenGroupAPIV2.defaultServer.substring(from: "http://".count)
|
||||||
|
var serverOptions: Set<String> = Set([
|
||||||
|
server,
|
||||||
|
"\(serverHost)\(serverPort)",
|
||||||
|
"http://\(serverHost)\(serverPort)",
|
||||||
|
"https://\(serverHost)\(serverPort)"
|
||||||
|
])
|
||||||
|
|
||||||
|
if serverHost == OpenGroupAPIV2.legacyDefaultServerDNS {
|
||||||
|
let defaultServerOptions: Set<String> = Set([
|
||||||
|
defaultServerHost,
|
||||||
|
OpenGroupAPIV2.defaultServer,
|
||||||
|
"https://\(defaultServerHost)"
|
||||||
|
])
|
||||||
|
serverOptions = serverOptions.union(defaultServerOptions)
|
||||||
|
}
|
||||||
|
else if serverHost == defaultServerHost {
|
||||||
|
let legacyServerOptions: Set<String> = Set([
|
||||||
|
OpenGroupAPIV2.legacyDefaultServerDNS,
|
||||||
|
"http://\(OpenGroupAPIV2.legacyDefaultServerDNS)",
|
||||||
|
"https://\(OpenGroupAPIV2.legacyDefaultServerDNS)"
|
||||||
|
])
|
||||||
|
serverOptions = serverOptions.union(legacyServerOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// First check if there is no poller for the specified server
|
||||||
|
if serverOptions.first(where: { OpenGroupManagerV2.shared.pollers[$0] != nil }) == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then check if there is an existing open group thread
|
||||||
|
let hasExistingThread: Bool = serverOptions.contains(where: { serverName in
|
||||||
|
let groupId: Data = LKGroupUtilities.getEncodedOpenGroupIDAsData("\(serverName).\(room)")
|
||||||
|
|
||||||
|
return (TSGroupThread.fetch(groupId: groupId, transaction: transaction) != nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
return hasExistingThread
|
||||||
|
}
|
||||||
|
|
||||||
public func add(room: String, server: String, publicKey: String, using transaction: Any) -> Promise<Void> {
|
public func add(room: String, server: String, publicKey: String, using transaction: Any) -> Promise<Void> {
|
||||||
// If we are currently polling for this server and already have a TSGroupThread for this room the do nothing
|
// If we are currently polling for this server and already have a TSGroupThread for this room the do nothing
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
let groupId: Data = LKGroupUtilities.getEncodedOpenGroupIDAsData("\(server).\(room)")
|
|
||||||
|
if hasExistingOpenGroup(room: room, server: server, publicKey: publicKey, using: transaction) {
|
||||||
if OpenGroupManagerV2.shared.pollers[server] != nil && TSGroupThread.fetch(groupId: groupId, transaction: transaction) != nil {
|
|
||||||
SNLog("Ignoring join open group attempt (already joined)")
|
SNLog("Ignoring join open group attempt (already joined)")
|
||||||
return Promise.value(())
|
return Promise.value(())
|
||||||
}
|
}
|
||||||
|
@ -126,7 +171,10 @@ public final class OpenGroupManagerV2 : NSObject {
|
||||||
// https://143.198.213.225:443/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
// https://143.198.213.225:443/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
||||||
// 143.198.213.255:80/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
// 143.198.213.255:80/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
||||||
let useTLS = (url.scheme == "https")
|
let useTLS = (url.scheme == "https")
|
||||||
let updatedPath = (url.path.starts(with: "/r/") ? url.path.substring(from: 2) : url.path)
|
|
||||||
|
// If there is no scheme then the host is included in the path (so handle that case)
|
||||||
|
let hostFreePath = (url.host != nil || !url.path.starts(with: host) ? url.path : url.path.substring(from: host.count))
|
||||||
|
let updatedPath = (hostFreePath.starts(with: "/r/") ? hostFreePath.substring(from: 2) : hostFreePath)
|
||||||
let room = String(updatedPath.dropFirst()) // Drop the leading slash
|
let room = String(updatedPath.dropFirst()) // Drop the leading slash
|
||||||
let queryParts = query.split(separator: "=")
|
let queryParts = query.split(separator: "=")
|
||||||
guard !room.isEmpty && !room.contains("/"), queryParts.count == 2, queryParts[0] == "public_key" else { return nil }
|
guard !room.isEmpty && !room.contains("/"), queryParts.count == 2, queryParts[0] == "public_key" else { return nil }
|
||||||
|
|
|
@ -48,6 +48,7 @@ public final class OpenGroupPollerV2 : NSObject {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.isPolling = false
|
self.isPolling = false
|
||||||
bodies.forEach { self.handleCompactPollBody($0, isBackgroundPoll: isBackgroundPoll) }
|
bodies.forEach { self.handleCompactPollBody($0, isBackgroundPoll: isBackgroundPoll) }
|
||||||
|
SNLog("Open group polling finished for \(self.server).")
|
||||||
seal.fulfill(())
|
seal.fulfill(())
|
||||||
}.catch(on: OpenGroupAPIV2.workQueue) { error in
|
}.catch(on: OpenGroupAPIV2.workQueue) { error in
|
||||||
SNLog("Open group polling failed due to error: \(error).")
|
SNLog("Open group polling failed due to error: \(error).")
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public enum General {
|
||||||
|
public enum Cache {
|
||||||
|
public static var cachedEncodedPublicKey: String? = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc(SNGeneralUtilities)
|
||||||
|
public class GeneralUtilities: NSObject {
|
||||||
|
@objc public static func getUserPublicKey() -> String {
|
||||||
|
return getUserHexEncodedPublicKey()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func getUserHexEncodedPublicKey() -> String {
|
public func getUserHexEncodedPublicKey() -> String {
|
||||||
|
if let cachedKey: String = General.Cache.cachedEncodedPublicKey { return cachedKey }
|
||||||
|
|
||||||
if let keyPair = OWSIdentityManager.shared().identityKeyPair() { // Can be nil under some circumstances
|
if let keyPair = OWSIdentityManager.shared().identityKeyPair() { // Can be nil under some circumstances
|
||||||
|
General.Cache.cachedEncodedPublicKey = keyPair.hexEncodedPublicKey
|
||||||
return keyPair.hexEncodedPublicKey
|
return keyPair.hexEncodedPublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface SNGeneralUtilities : NSObject
|
|
||||||
|
|
||||||
+ (NSString *)getUserPublicKey;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,16 +0,0 @@
|
||||||
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
|
||||||
#import "GeneralUtilities.h"
|
|
||||||
#import "OWSIdentityManager.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@implementation SNGeneralUtilities
|
|
||||||
|
|
||||||
+ (NSString *)getUserPublicKey
|
|
||||||
{
|
|
||||||
return OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -13,14 +13,14 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
|
||||||
// to check if this is the only message request thread (group threads can't be message requests
|
// to check if this is the only message request thread (group threads can't be message requests
|
||||||
// so just ignore those and if the user has hidden message requests then we want to show the
|
// so just ignore those and if the user has hidden message requests then we want to show the
|
||||||
// notification regardless of how many message requests there are)
|
// notification regardless of how many message requests there are)
|
||||||
if !thread.isGroupThread() && thread.isMessageRequest() && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] {
|
if !thread.isGroupThread() && thread.isMessageRequest(using: transaction) && !CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] {
|
||||||
let threads = transaction.ext(TSThreadDatabaseViewExtensionName) as! YapDatabaseViewTransaction
|
let threads = transaction.ext(TSThreadDatabaseViewExtensionName) as! YapDatabaseViewTransaction
|
||||||
let numMessageRequests = threads.numberOfItems(inGroup: TSMessageRequestGroup)
|
let numMessageRequests = threads.numberOfItems(inGroup: TSMessageRequestGroup)
|
||||||
|
|
||||||
// Allow this to show a notification if there are no message requests (ie. this is the first one)
|
// Allow this to show a notification if there are no message requests (ie. this is the first one)
|
||||||
guard numMessageRequests == 0 else { return }
|
guard numMessageRequests == 0 else { return }
|
||||||
}
|
}
|
||||||
else if thread.isMessageRequest() && CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] {
|
else if thread.isMessageRequest(using: transaction) && CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] {
|
||||||
// If there are other interactions on this thread already then don't show the notification
|
// If there are other interactions on this thread already then don't show the notification
|
||||||
if thread.numberOfInteractions(with: transaction) > 1 { return }
|
if thread.numberOfInteractions(with: transaction) > 1 { return }
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
let senderPublicKey = incomingMessage.authorId
|
let senderPublicKey = incomingMessage.authorId
|
||||||
let userPublicKey = SNGeneralUtilities.getUserPublicKey()
|
let userPublicKey = GeneralUtilities.getUserPublicKey()
|
||||||
guard senderPublicKey != userPublicKey else {
|
guard senderPublicKey != userPublicKey else {
|
||||||
// Ignore PNs for messages sent by the current user
|
// Ignore PNs for messages sent by the current user
|
||||||
// after handling the message. Otherwise the closed
|
// after handling the message. Otherwise the closed
|
||||||
|
@ -37,7 +37,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = Contact.context(for: thread)
|
let context = Contact.context(for: thread)
|
||||||
let senderName = Storage.shared.getContact(with: senderPublicKey)?.displayName(for: context) ?? senderPublicKey
|
let senderName = Storage.shared.getContact(with: senderPublicKey, using: transaction)?.displayName(for: context) ?? senderPublicKey
|
||||||
|
|
||||||
var notificationTitle = senderName
|
var notificationTitle = senderName
|
||||||
if let group = thread as? TSGroupThread {
|
if let group = thread as? TSGroupThread {
|
||||||
|
@ -85,7 +85,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
|
||||||
|
|
||||||
// If it's a message request then overwrite the body to be something generic (only show a notification
|
// If it's a message request then overwrite the body to be something generic (only show a notification
|
||||||
// when receiving a new message request if there aren't any others or the user had hidden them)
|
// when receiving a new message request if there aren't any others or the user had hidden them)
|
||||||
if thread.isMessageRequest() {
|
if thread.isMessageRequest(using: transaction) {
|
||||||
notificationContent.title = "Session"
|
notificationContent.title = "Session"
|
||||||
notificationContent.body = "MESSAGE_REQUESTS_NOTIFICATION".localized()
|
notificationContent.body = "MESSAGE_REQUESTS_NOTIFICATION".localized()
|
||||||
}
|
}
|
||||||
|
@ -93,8 +93,16 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
|
||||||
// Add request
|
// Add request
|
||||||
let identifier = incomingMessage.notificationIdentifier ?? UUID().uuidString
|
let identifier = incomingMessage.notificationIdentifier ?? UUID().uuidString
|
||||||
let request = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: nil)
|
let request = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: nil)
|
||||||
SNLog("Add remote notification request")
|
SNLog("Add remote notification request: \(notificationContent.body)")
|
||||||
UNUserNotificationCenter.current().add(request)
|
let semaphore = DispatchSemaphore(value: 0)
|
||||||
|
UNUserNotificationCenter.current().add(request) { error in
|
||||||
|
if let error = error {
|
||||||
|
SNLog("Failed to add notification request due to error:\(error)")
|
||||||
|
}
|
||||||
|
semaphore.signal()
|
||||||
|
}
|
||||||
|
semaphore.wait()
|
||||||
|
SNLog("Finish adding remote notification request")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func cancelNotification(_ identifier: String) {
|
public func cancelNotification(_ identifier: String) {
|
||||||
|
|
|
@ -41,7 +41,10 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
|
||||||
let envelope = try? MessageWrapper.unwrap(data: data), let envelopeAsData = try? envelope.serializedData() else {
|
let envelope = try? MessageWrapper.unwrap(data: data), let envelopeAsData = try? envelope.serializedData() else {
|
||||||
return self.handleFailure(for: notificationContent)
|
return self.handleFailure(for: notificationContent)
|
||||||
}
|
}
|
||||||
Storage.write { transaction in // Intentionally capture self
|
// HACK: It is important to use writeSync() here to avoid a race condition
|
||||||
|
// where the completeSilenty() is called before the local notification request
|
||||||
|
// is added to notification center.
|
||||||
|
Storage.writeSync { transaction in // Intentionally capture self
|
||||||
do {
|
do {
|
||||||
let (message, proto) = try MessageReceiver.parse(envelopeAsData, openGroupMessageServerID: nil, using: transaction)
|
let (message, proto) = try MessageReceiver.parse(envelopeAsData, openGroupMessageServerID: nil, using: transaction)
|
||||||
switch message {
|
switch message {
|
||||||
|
|
|
@ -204,7 +204,11 @@ public enum OnionRequestAPI {
|
||||||
} else {
|
} else {
|
||||||
return buildPaths(reusing: []).map2 { paths in
|
return buildPaths(reusing: []).map2 { paths in
|
||||||
if let snode = snode {
|
if let snode = snode {
|
||||||
return paths.filter { !$0.contains(snode) }.randomElement()!
|
if let path = paths.filter({ !$0.contains(snode) }).randomElement() {
|
||||||
|
return path
|
||||||
|
} else {
|
||||||
|
throw Error.insufficientSnodes
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return paths.randomElement()!
|
return paths.randomElement()!
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue