Updated the app settings screens
Updated the MessageRequestViewModel to have the same page size as the HomeViewModel Fixed a couple minor UI discrepancies Refactored the old app settings child screens to be configuration based and all in Swift
This commit is contained in:
parent
ea32e407a9
commit
20d63d106c
|
@ -9,10 +9,7 @@
|
|||
/* Begin PBXBuildFile section */
|
||||
1FFD68A448D5A1439F2F02FD /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DBA125424EDD2417B515C63A /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionShareExtension.framework */; };
|
||||
3289CA2E9E89DA9D4D52A90C /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SignalUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BF4561630A52BE96F164CF6 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SignalUtilitiesKit.framework */; };
|
||||
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */; };
|
||||
340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */; };
|
||||
340FC8AC204DAC8D007AEB0F /* PrivacySettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87E204DAC8C007AEB0F /* PrivacySettingsTableViewController.m */; };
|
||||
340FC8AE204DAC8D007AEB0F /* OWSSoundSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC883204DAC8C007AEB0F /* OWSSoundSettingsViewController.m */; };
|
||||
340FC8B6204DAC8D007AEB0F /* OWSQRCodeScanningViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC896204DAC8C007AEB0F /* OWSQRCodeScanningViewController.m */; };
|
||||
340FC8B7204DAC8D007AEB0F /* OWSConversationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC89A204DAC8D007AEB0F /* OWSConversationSettingsViewController.m */; };
|
||||
3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3427C64220F500DF00EEC730 /* OWSMessageTimerView.m */; };
|
||||
|
@ -660,6 +657,13 @@
|
|||
FD37E9FD28A5F216003AE748 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D9E43025676D3D0040E4F3 /* Configuration.swift */; };
|
||||
FD37E9FF28A5F2CD003AE748 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37E9FE28A5F2CD003AE748 /* Configuration.swift */; };
|
||||
FD37EA0128A60473003AE748 /* UIKit+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA0028A60473003AE748 /* UIKit+Theme.swift */; };
|
||||
FD37EA0328A9FDCC003AE748 /* HelpViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA0228A9FDCC003AE748 /* HelpViewModel.swift */; };
|
||||
FD37EA0528AA00C1003AE748 /* NotificationSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA0428AA00C1003AE748 /* NotificationSettingsViewModel.swift */; };
|
||||
FD37EA0728AA2CCA003AE748 /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA0628AA2CCA003AE748 /* SettingsTableViewController.swift */; };
|
||||
FD37EA0928AA2D27003AE748 /* SettingsTableViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA0828AA2D27003AE748 /* SettingsTableViewModel.swift */; };
|
||||
FD37EA0B28AB12E2003AE748 /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA0A28AB12E2003AE748 /* SettingsCell.swift */; };
|
||||
FD37EA1728AC5605003AE748 /* NotificationContentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA1628AC5605003AE748 /* NotificationContentViewModel.swift */; };
|
||||
FD37EA1928AC5CCA003AE748 /* NotificationSoundViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37EA1828AC5CCA003AE748 /* NotificationSoundViewModel.swift */; };
|
||||
FD3AABE928306BBD00E5099A /* ThreadPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD3AABE828306BBD00E5099A /* ThreadPickerViewModel.swift */; };
|
||||
FD3C905C27E3FBEF00CD579F /* BatchRequestInfoSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD3C905B27E3FBEF00CD579F /* BatchRequestInfoSpec.swift */; };
|
||||
FD3C906027E410F700CD579F /* FileUploadResponseSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD3C905F27E410F700CD579F /* FileUploadResponseSpec.swift */; };
|
||||
|
@ -796,7 +800,7 @@
|
|||
FDD2506E283711D600198BDA /* DifferenceKit+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDD2506D283711D600198BDA /* DifferenceKit+Utilities.swift */; };
|
||||
FDD250702837199200198BDA /* GarbageCollectionJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDD2506F2837199200198BDA /* GarbageCollectionJob.swift */; };
|
||||
FDD250722837234B00198BDA /* MediaGalleryNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDD250712837234B00198BDA /* MediaGalleryNavigationController.swift */; };
|
||||
FDE72118286C156E0093DF33 /* ChatSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE72117286C156E0093DF33 /* ChatSettingsViewController.swift */; };
|
||||
FDE72118286C156E0093DF33 /* ConversationSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE72117286C156E0093DF33 /* ConversationSettingsViewController.swift */; };
|
||||
FDE72154287FE4470093DF33 /* HighlightMentionBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE72153287FE4470093DF33 /* HighlightMentionBackgroundView.swift */; };
|
||||
FDE77F6B280FEB28002CFC5D /* ControlMessageProcessRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE77F6A280FEB28002CFC5D /* ControlMessageProcessRecord.swift */; };
|
||||
FDED2E3C282E1B5D00B2CD2A /* UICollectionView+ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDED2E3B282E1B5D00B2CD2A /* UICollectionView+ReusableView.swift */; };
|
||||
|
@ -1022,15 +1026,9 @@
|
|||
2581AFACDDDC1404866D7B8C /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.app store release.xcconfig"; sourceTree = "<group>"; };
|
||||
2691123A7F231EDD8226C4B5 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionMessagingKit_SessionMessagingKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionMessagingKit_SessionMessagingKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
29CF8C79F41BF00B1C2E59A0 /* Pods-SessionUIKit.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SessionUIKit.app store release.xcconfig"; path = "Target Support Files/Pods-SessionUIKit/Pods-SessionUIKit.app store release.xcconfig"; sourceTree = "<group>"; };
|
||||
340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsOptionsViewController.m; sourceTree = "<group>"; };
|
||||
340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsViewController.m; sourceTree = "<group>"; };
|
||||
340FC87E204DAC8C007AEB0F /* PrivacySettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrivacySettingsTableViewController.m; sourceTree = "<group>"; };
|
||||
340FC883204DAC8C007AEB0F /* OWSSoundSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSSoundSettingsViewController.m; sourceTree = "<group>"; };
|
||||
340FC888204DAC8C007AEB0F /* OWSQRCodeScanningViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSQRCodeScanningViewController.h; sourceTree = "<group>"; };
|
||||
340FC88A204DAC8C007AEB0F /* NotificationSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsViewController.h; sourceTree = "<group>"; };
|
||||
340FC88B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSettingsOptionsViewController.h; sourceTree = "<group>"; };
|
||||
340FC88F204DAC8C007AEB0F /* PrivacySettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivacySettingsTableViewController.h; sourceTree = "<group>"; };
|
||||
340FC894204DAC8C007AEB0F /* OWSSoundSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSoundSettingsViewController.h; sourceTree = "<group>"; };
|
||||
340FC896204DAC8C007AEB0F /* OWSQRCodeScanningViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSQRCodeScanningViewController.m; sourceTree = "<group>"; };
|
||||
340FC899204DAC8D007AEB0F /* OWSConversationSettingsViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationSettingsViewDelegate.h; sourceTree = "<group>"; };
|
||||
340FC89A204DAC8D007AEB0F /* OWSConversationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSConversationSettingsViewController.m; sourceTree = "<group>"; };
|
||||
|
@ -1723,6 +1721,13 @@
|
|||
FD37E9F828A5F14A003AE748 /* _001_ThemePreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _001_ThemePreferences.swift; sourceTree = "<group>"; };
|
||||
FD37E9FE28A5F2CD003AE748 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
|
||||
FD37EA0028A60473003AE748 /* UIKit+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+Theme.swift"; sourceTree = "<group>"; };
|
||||
FD37EA0228A9FDCC003AE748 /* HelpViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpViewModel.swift; sourceTree = "<group>"; };
|
||||
FD37EA0428AA00C1003AE748 /* NotificationSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsViewModel.swift; sourceTree = "<group>"; };
|
||||
FD37EA0628AA2CCA003AE748 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; };
|
||||
FD37EA0828AA2D27003AE748 /* SettingsTableViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTableViewModel.swift; sourceTree = "<group>"; };
|
||||
FD37EA0A28AB12E2003AE748 /* SettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = "<group>"; };
|
||||
FD37EA1628AC5605003AE748 /* NotificationContentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationContentViewModel.swift; sourceTree = "<group>"; };
|
||||
FD37EA1828AC5CCA003AE748 /* NotificationSoundViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSoundViewModel.swift; sourceTree = "<group>"; };
|
||||
FD3AABE828306BBD00E5099A /* ThreadPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadPickerViewModel.swift; sourceTree = "<group>"; };
|
||||
FD3C905B27E3FBEF00CD579F /* BatchRequestInfoSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchRequestInfoSpec.swift; sourceTree = "<group>"; };
|
||||
FD3C905F27E410F700CD579F /* FileUploadResponseSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUploadResponseSpec.swift; sourceTree = "<group>"; };
|
||||
|
@ -1852,7 +1857,7 @@
|
|||
FDD2506D283711D600198BDA /* DifferenceKit+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DifferenceKit+Utilities.swift"; sourceTree = "<group>"; };
|
||||
FDD2506F2837199200198BDA /* GarbageCollectionJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GarbageCollectionJob.swift; sourceTree = "<group>"; };
|
||||
FDD250712837234B00198BDA /* MediaGalleryNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaGalleryNavigationController.swift; sourceTree = "<group>"; };
|
||||
FDE72117286C156E0093DF33 /* ChatSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
FDE72117286C156E0093DF33 /* ConversationSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
FDE7214F287E50D50093DF33 /* ProtoWrappers.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = ProtoWrappers.py; sourceTree = "<group>"; };
|
||||
FDE72150287E50D50093DF33 /* LintLocalizableStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LintLocalizableStrings.swift; sourceTree = "<group>"; };
|
||||
FDE72153287FE4470093DF33 /* HighlightMentionBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HighlightMentionBackgroundView.swift; sourceTree = "<group>"; };
|
||||
|
@ -2823,22 +2828,22 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
FD37E9CD28A1E682003AE748 /* Views */,
|
||||
340FC88B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.h */,
|
||||
340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */,
|
||||
340FC88A204DAC8C007AEB0F /* NotificationSettingsViewController.h */,
|
||||
340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */,
|
||||
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */,
|
||||
340FC894204DAC8C007AEB0F /* OWSSoundSettingsViewController.h */,
|
||||
340FC883204DAC8C007AEB0F /* OWSSoundSettingsViewController.m */,
|
||||
340FC88F204DAC8C007AEB0F /* PrivacySettingsTableViewController.h */,
|
||||
340FC87E204DAC8C007AEB0F /* PrivacySettingsTableViewController.m */,
|
||||
7B13E1EA2811138200BD4F64 /* PrivacySettingsTableViewController.swift */,
|
||||
B886B4A62398B23E00211ABE /* QRCodeVC.swift */,
|
||||
B86BD08523399CEF000F5AE3 /* SeedModal.swift */,
|
||||
B8CCF6422397711F0091D419 /* SettingsVC.swift */,
|
||||
B886B4A62398B23E00211ABE /* QRCodeVC.swift */,
|
||||
FD37EA0828AA2D27003AE748 /* SettingsTableViewModel.swift */,
|
||||
FD37EA0628AA2CCA003AE748 /* SettingsTableViewController.swift */,
|
||||
FD37EA0428AA00C1003AE748 /* NotificationSettingsViewModel.swift */,
|
||||
FD37EA1828AC5CCA003AE748 /* NotificationSoundViewModel.swift */,
|
||||
FD37EA1628AC5605003AE748 /* NotificationContentViewModel.swift */,
|
||||
FD37E9CB28A1E578003AE748 /* AppearanceViewController.swift */,
|
||||
FDE72117286C156E0093DF33 /* ChatSettingsViewController.swift */,
|
||||
FDE72117286C156E0093DF33 /* ConversationSettingsViewController.swift */,
|
||||
FD37EA0228A9FDCC003AE748 /* HelpViewModel.swift */,
|
||||
B86BD08523399CEF000F5AE3 /* SeedModal.swift */,
|
||||
7B7CB18A270591630079FF93 /* ShareLogsModal.swift */,
|
||||
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */,
|
||||
);
|
||||
path = Settings;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3637,6 +3642,7 @@
|
|||
FD37E9D028A1F2EB003AE748 /* ThemeSelectionView.swift */,
|
||||
FD37E9DA28A244E9003AE748 /* ThemePreviewView.swift */,
|
||||
FD37E9DC28A384EB003AE748 /* PrimaryColorSelectionView.swift */,
|
||||
FD37EA0A28AB12E2003AE748 /* SettingsCell.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5352,6 +5358,7 @@
|
|||
34D1F0501F7D45A60066283D /* GifPickerCell.swift in Sources */,
|
||||
7B13E1EB2811138200BD4F64 /* PrivacySettingsTableViewController.swift in Sources */,
|
||||
C3E5C2FA251DBABB0040DFFC /* EditClosedGroupVC.swift in Sources */,
|
||||
FD37EA0928AA2D27003AE748 /* SettingsTableViewModel.swift in Sources */,
|
||||
7BAF54D027ACCEEC003D12F8 /* EmptySearchResultCell.swift in Sources */,
|
||||
B8783E9E23EB948D00404FB8 /* UILabel+Interaction.swift in Sources */,
|
||||
FD37E9D928A230F2003AE748 /* TraitObservingWindow.swift in Sources */,
|
||||
|
@ -5362,6 +5369,7 @@
|
|||
454A84042059C787008B8C75 /* MediaTileViewController.swift in Sources */,
|
||||
451A13B11E13DED2000A50FD /* AppNotifications.swift in Sources */,
|
||||
34D99CE4217509C2000AFB39 /* AppEnvironment.swift in Sources */,
|
||||
FD37EA0528AA00C1003AE748 /* NotificationSettingsViewModel.swift in Sources */,
|
||||
C328255225CA64470062D0A7 /* ContextMenuVC+ActionView.swift in Sources */,
|
||||
450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */,
|
||||
C3548F0824456AB6009433A8 /* UIView+Wrapping.swift in Sources */,
|
||||
|
@ -5370,7 +5378,7 @@
|
|||
EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */,
|
||||
45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */,
|
||||
B83524A525C3BA4B0089A44F /* InfoMessageCell.swift in Sources */,
|
||||
FDE72118286C156E0093DF33 /* ChatSettingsViewController.swift in Sources */,
|
||||
FDE72118286C156E0093DF33 /* ConversationSettingsViewController.swift in Sources */,
|
||||
B84A89BC25DE328A0040017D /* ProfilePictureVC.swift in Sources */,
|
||||
34386A54207D271D009F5D9C /* NeverClearView.swift in Sources */,
|
||||
FDCDB8E02811007F00352A0C /* HomeViewModel.swift in Sources */,
|
||||
|
@ -5380,7 +5388,6 @@
|
|||
B83F2B88240CB75A000A54AB /* UIImage+Scaling.swift in Sources */,
|
||||
3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */,
|
||||
FDE72154287FE4470093DF33 /* HighlightMentionBackgroundView.swift in Sources */,
|
||||
340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */,
|
||||
4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */,
|
||||
34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */,
|
||||
B886B4A92398BA1500211ABE /* QRCode.swift in Sources */,
|
||||
|
@ -5392,7 +5399,6 @@
|
|||
4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */,
|
||||
3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */,
|
||||
C3A76A8D25DB83F90074CB90 /* PermissionMissingModal.swift in Sources */,
|
||||
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */,
|
||||
B849789625D4A2F500D0D0B3 /* LinkPreviewView.swift in Sources */,
|
||||
C3D0972B2510499C00F6E3E4 /* BackgroundPoller.swift in Sources */,
|
||||
C3548F0624456447009433A8 /* PNModeVC.swift in Sources */,
|
||||
|
@ -5411,6 +5417,7 @@
|
|||
34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */,
|
||||
C331FFFE2558FF3B00070591 /* FullConversationCell.swift in Sources */,
|
||||
FDFDE128282D05530098B17F /* MediaPresentationContext.swift in Sources */,
|
||||
FD37EA0328A9FDCC003AE748 /* HelpViewModel.swift in Sources */,
|
||||
FDFDE124282D04F20098B17F /* MediaDismissAnimationController.swift in Sources */,
|
||||
7BA6890F27325CE300EFC32F /* SessionCallManager+CXProvider.swift in Sources */,
|
||||
34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */,
|
||||
|
@ -5429,6 +5436,7 @@
|
|||
C374EEEB25DA3CA70073A857 /* ConversationTitleView.swift in Sources */,
|
||||
FD716E7128505E5200C96BF4 /* MessageRequestsCell.swift in Sources */,
|
||||
B88FA7F2260C3EB10049422F /* OpenGroupSuggestionGrid.swift in Sources */,
|
||||
FD37EA1928AC5CCA003AE748 /* NotificationSoundViewModel.swift in Sources */,
|
||||
4CA485BB2232339F004B9E7D /* PhotoCaptureViewController.swift in Sources */,
|
||||
34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */,
|
||||
C328254925CA60E60062D0A7 /* ContextMenuVC+Action.swift in Sources */,
|
||||
|
@ -5442,6 +5450,7 @@
|
|||
B848A4C5269EAAA200617031 /* UserDetailsSheet.swift in Sources */,
|
||||
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,
|
||||
7BAF54CF27ACCEEC003D12F8 /* GlobalSearchViewController.swift in Sources */,
|
||||
FD37EA1728AC5605003AE748 /* NotificationContentViewModel.swift in Sources */,
|
||||
B886B4A72398B23E00211ABE /* QRCodeVC.swift in Sources */,
|
||||
4C586926224FAB83003FD070 /* AVAudioSession+OWS.m in Sources */,
|
||||
C331FFF42558FF0300070591 /* PNOptionView.swift in Sources */,
|
||||
|
@ -5452,6 +5461,7 @@
|
|||
B8CCF63F23975CFB0091D419 /* JoinOpenGroupVC.swift in Sources */,
|
||||
FD848B9828422F1A000E298B /* Date+Utilities.swift in Sources */,
|
||||
FD37E9DB28A244E9003AE748 /* ThemePreviewView.swift in Sources */,
|
||||
FD37EA0728AA2CCA003AE748 /* SettingsTableViewController.swift in Sources */,
|
||||
B85357C323A1BD1200AAF6CD /* SeedVC.swift in Sources */,
|
||||
45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */,
|
||||
B8D84ECF25E3108A005A043E /* ExpandingAttachmentsButton.swift in Sources */,
|
||||
|
@ -5490,6 +5500,7 @@
|
|||
B8269D3D25C7B34D00488AB4 /* InputTextView.swift in Sources */,
|
||||
340FC8B6204DAC8D007AEB0F /* OWSQRCodeScanningViewController.m in Sources */,
|
||||
7B0EFDF0275084AA00FFAAE7 /* CallMessageCell.swift in Sources */,
|
||||
FD37EA0B28AB12E2003AE748 /* SettingsCell.swift in Sources */,
|
||||
7B93D06A27CF173D00811CB6 /* MessageRequestsViewController.swift in Sources */,
|
||||
C33100082558FF6D00070591 /* NewConversationButtonSet.swift in Sources */,
|
||||
C3AAFFF225AE99710089E6DD /* AppDelegate.swift in Sources */,
|
||||
|
@ -5506,7 +5517,6 @@
|
|||
FD716E6C28505E1C00C96BF4 /* MessageRequestsViewModel.swift in Sources */,
|
||||
C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */,
|
||||
B835249B25C3AB650089A44F /* VisibleMessageCell.swift in Sources */,
|
||||
340FC8AE204DAC8D007AEB0F /* OWSSoundSettingsViewController.m in Sources */,
|
||||
B8D0A25025E3678700C1835E /* LinkDeviceVC.swift in Sources */,
|
||||
B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */,
|
||||
7B93D07727CF1A8A00811CB6 /* MockDataGenerator.swift in Sources */,
|
||||
|
|
|
@ -139,7 +139,7 @@ final class LinkPreviewView: UIView {
|
|||
var image: UIImage? = state.image
|
||||
let stateHasImage: Bool = (image != nil)
|
||||
if image == nil && (state is LinkPreview.DraftState || state is LinkPreview.SentState) {
|
||||
image = UIImage(named: "Link")
|
||||
image = UIImage(named: "Link")?.withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
|
||||
// Image view
|
||||
|
@ -164,15 +164,8 @@ final class LinkPreviewView: UIView {
|
|||
if image != nil { loader.stopAnimating() } else { loader.startAnimating() }
|
||||
|
||||
// Title
|
||||
let sentLinkPreviewTextColor: UIColor = {
|
||||
switch (isOutgoing, AppModeManager.shared.currentAppMode) {
|
||||
case (false, .light): return .black
|
||||
case (true, .light): return Colors.grey
|
||||
default: return .white
|
||||
}
|
||||
}()
|
||||
titleLabel.textColor = sentLinkPreviewTextColor
|
||||
titleLabel.text = state.title
|
||||
titleLabel.themeTextColor = .textPrimary
|
||||
|
||||
// Horizontal stack view
|
||||
switch state {
|
||||
|
|
|
@ -138,7 +138,12 @@ final class QuoteView: UIView {
|
|||
.withRenderingMode(.alwaysTemplate)
|
||||
)
|
||||
|
||||
imageView.tintColor = .white
|
||||
imageView.themeTintColor = {
|
||||
switch mode {
|
||||
case .regular: return (direction == .outgoing ? .white : .messageBubble_outgoingText)
|
||||
case .draft: return .messageBubble_outgoingText
|
||||
}
|
||||
}()
|
||||
imageView.contentMode = .center
|
||||
imageView.themeBackgroundColor = lineColor
|
||||
imageView.layer.cornerRadius = VisibleMessageCell.smallCornerRadius
|
||||
|
@ -204,7 +209,9 @@ final class QuoteView: UIView {
|
|||
isOutgoingMessage: isOutgoing,
|
||||
textColor: textColor,
|
||||
primaryColor: primaryColor,
|
||||
attributes: [:]
|
||||
attributes: [
|
||||
.foregroundColor: textColor
|
||||
]
|
||||
)
|
||||
}
|
||||
.defaulting(
|
||||
|
@ -256,14 +263,6 @@ final class QuoteView: UIView {
|
|||
mainStackView.addArrangedSubview(bodyLabel)
|
||||
}
|
||||
|
||||
// Cancel button
|
||||
let cancelButton = UIButton(type: .custom)
|
||||
cancelButton.setImage(UIImage(named: "X")?.withRenderingMode(.alwaysTemplate), for: UIControl.State.normal)
|
||||
cancelButton.tintColor = (isLightMode ? .black : .white)
|
||||
cancelButton.set(.width, to: cancelButtonSize)
|
||||
cancelButton.set(.height, to: cancelButtonSize)
|
||||
cancelButton.addTarget(self, action: #selector(cancel), for: UIControl.Event.touchUpInside)
|
||||
|
||||
// Constraints
|
||||
contentView.addSubview(mainStackView)
|
||||
mainStackView.pin(to: contentView)
|
||||
|
@ -292,6 +291,14 @@ final class QuoteView: UIView {
|
|||
lineView.set(.height, to: contentViewHeight - 8) // Add a small amount of spacing above and below the line
|
||||
|
||||
if mode == .draft {
|
||||
// Cancel button
|
||||
let cancelButton = UIButton(type: .custom)
|
||||
cancelButton.setImage(UIImage(named: "X")?.withRenderingMode(.alwaysTemplate), for: .normal)
|
||||
cancelButton.themeTintColor = .textPrimary
|
||||
cancelButton.set(.width, to: cancelButtonSize)
|
||||
cancelButton.set(.height, to: cancelButtonSize)
|
||||
cancelButton.addTarget(self, action: #selector(cancel), for: UIControl.Event.touchUpInside)
|
||||
|
||||
addSubview(cancelButton)
|
||||
cancelButton.center(.vertical, in: self)
|
||||
cancelButton.pin(.right, to: .right, of: self)
|
||||
|
|
|
@ -73,6 +73,7 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve
|
|||
private lazy var tableView: UITableView = {
|
||||
let result = UITableView()
|
||||
result.separatorStyle = .none
|
||||
result.backgroundColor = .clear
|
||||
result.contentInset = UIEdgeInsets(
|
||||
top: 0,
|
||||
left: 0,
|
||||
|
|
|
@ -17,7 +17,7 @@ public class MessageRequestsViewModel {
|
|||
|
||||
// MARK: - Variables
|
||||
|
||||
public static let pageSize: Int = 20
|
||||
public static let pageSize: Int = 15
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
|
|
|
@ -118,8 +118,8 @@ class MessageRequestsCell: UITableViewCell {
|
|||
unreadCountView.heightAnchor.constraint(equalToConstant: FullConversationCell.unreadCountViewSize),
|
||||
|
||||
unreadCountLabel.topAnchor.constraint(equalTo: unreadCountView.topAnchor),
|
||||
unreadCountLabel.leftAnchor.constraint(equalTo: unreadCountView.leftAnchor),
|
||||
unreadCountLabel.rightAnchor.constraint(equalTo: unreadCountView.rightAnchor),
|
||||
unreadCountLabel.leftAnchor.constraint(equalTo: unreadCountView.leftAnchor, constant: 4),
|
||||
unreadCountLabel.rightAnchor.constraint(equalTo: unreadCountView.rightAnchor, constant: -4),
|
||||
unreadCountLabel.bottomAnchor.constraint(equalTo: unreadCountView.bottomAnchor)
|
||||
])
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
@ -28,7 +27,7 @@
|
|||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" name="session_navigation_bar_background"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="b92-yg-YYQ" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="ec1-lk-fbn"/>
|
||||
<constraint firstItem="b92-yg-YYQ" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="jLr-XH-MKf"/>
|
||||
|
@ -42,8 +41,5 @@
|
|||
</scenes>
|
||||
<resources>
|
||||
<image name="SessionGreen64" width="57.5" height="64"/>
|
||||
<namedColor name="session_navigation_bar_background">
|
||||
<color red="0.9882352941176471" green="0.9882352941176471" blue="0.9882352941176471" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
// Separate iOS Frameworks from other imports.
|
||||
#import "AvatarViewHelper.h"
|
||||
#import "AVAudioSession+OWS.h"
|
||||
#import "NotificationSettingsViewController.h"
|
||||
#import "OWSAudioPlayer.h"
|
||||
#import "OWSBezierPathView.h"
|
||||
#import "OWSConversationSettingsViewController.h"
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -684,6 +684,20 @@
|
|||
"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send.";
|
||||
"INVALID_SESSION_ID_MESSAGE" = "Please check the Session ID and try again.";
|
||||
"INVALID_RECOVERY_PHRASE_MESSAGE" = "Please check the Recovery Phrase and try again.";
|
||||
"NOTIFICATIONS_TITLE" = "Notifications";
|
||||
"NOTIFICATIONS_SECTION_STRATEGY" = "Notification Strategy";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE" = "Use Fast Mode";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION" = "You'll be notified of new message reliably and immediately using Apple's notification servers.";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1" = "Go to ";
|
||||
"NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2" = "device notification settings";
|
||||
"NOTIFICATIONS_SECTION_STYLE" = "Notification Style";
|
||||
"NOTIFICATIONS_STYLE_SOUND_TITLE" = "Sound";
|
||||
"NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE" = "Sound When App is Open";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_TITLE" = "Notification Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION" = "The information shown in notifications.";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_AND_CONTENT" = "Name and Content";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NAME_ONLY" = "Name Only";
|
||||
"NOTIFICATIONS_STYLE_CONTENT_OPTION_NO_NAME_OR_CONTENT" = "No Name or Content";
|
||||
"APPEARANCE_TITLE" = "Appearance";
|
||||
"APPEARANCE_THEMES_TITLE" = "Themes";
|
||||
"APPEARANCE_PRIMARY_COLOR_TITLE" = "Primary colour";
|
||||
|
@ -693,3 +707,10 @@
|
|||
"APPEARANCE_NIGHT_MODE_TITLE" = "Auto night-mode";
|
||||
"APPEARANCE_NIGHT_MODE_TOGGLE" = "Match system settings";
|
||||
"HELP_TITLE" = "Help";
|
||||
"HELP_REPORT_BUG_TITLE" = "Report a Bug";
|
||||
"HELP_REPORT_BUG_DESCRIPTION" = "Export your logs, then upload the file though Session's Help Desk.";
|
||||
"HELP_REPORT_BUG_ACTION_TITLE" = "Export Logs";
|
||||
"HELP_TRANSLATE_TITLE" = "Translate Session";
|
||||
"HELP_FEEDBACK_TITLE" = "We'd love your Feedback";
|
||||
"HELP_FAQ_TITLE" = "FAQ";
|
||||
"HELP_SUPPORT_TITLE" = "Support";
|
||||
|
|
|
@ -164,12 +164,3 @@ extension SyncPushTokensJob {
|
|||
.retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Objective C Support
|
||||
|
||||
@objc(OWSSyncPushTokensJob)
|
||||
class OWSSyncPushTokensJob: NSObject {
|
||||
@objc static func run() {
|
||||
SyncPushTokensJob.run(uploadOnlyIfStale: false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import SessionUIKit
|
|||
import SignalUtilitiesKit
|
||||
|
||||
// FIXME: Refactor to be MVVM and use database observation
|
||||
class ChatSettingsViewController: OWSTableViewController {
|
||||
class ConversationSettingsViewController: OWSTableViewController {
|
||||
// MARK: - Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
|
@ -0,0 +1,122 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import DifferenceKit
|
||||
import SessionUIKit
|
||||
import SessionMessagingKit
|
||||
import SessionUtilitiesKit
|
||||
|
||||
class HelpViewModel: SettingsTableViewModel<HelpViewModel.Section, HelpViewModel.Section> {
|
||||
// MARK: - Section
|
||||
|
||||
public enum Section: SettingSection {
|
||||
case report
|
||||
case translate
|
||||
case feedback
|
||||
case faq
|
||||
case support
|
||||
|
||||
var title: String { "" } // No titles
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
override var title: String { "HELP_TITLE".localized() }
|
||||
|
||||
private var _settingsData: [SectionModel] = []
|
||||
public override var settingsData: [SectionModel] { _settingsData }
|
||||
|
||||
public override var observableSettingsData: ObservableData { _observableSettingsData }
|
||||
|
||||
/// This is all the data the screen needs to populate itself, please see the following link for tips to help optimise
|
||||
/// performance https://github.com/groue/GRDB.swift#valueobservation-performance
|
||||
///
|
||||
/// **Note:** This observation will be triggered twice immediately (and be de-duped by the `removeDuplicates`)
|
||||
/// this is due to the behaviour of `ValueConcurrentObserver.asyncStartObservation` which triggers it's own
|
||||
/// fetch (after the ones in `ValueConcurrentObserver.asyncStart`/`ValueConcurrentObserver.syncStart`)
|
||||
/// just in case the database has changed between the two reads - unfortunately it doesn't look like there is a way to prevent this
|
||||
private lazy var _observableSettingsData: ObservableData = ValueObservation
|
||||
.trackingConstantRegion { db -> [SectionModel] in
|
||||
return [
|
||||
SectionModel(
|
||||
model: .report,
|
||||
elements: [
|
||||
SettingInfo(
|
||||
id: .report,
|
||||
title: "HELP_REPORT_BUG_TITLE".localized(),
|
||||
subtitle: "HELP_REPORT_BUG_DESCRIPTION".localized(),
|
||||
action: .rightButtonModal(
|
||||
title: "HELP_REPORT_BUG_ACTION_TITLE".localized(),
|
||||
createModal: {
|
||||
let shareLogsModal: ShareLogsModal = ShareLogsModal()
|
||||
shareLogsModal.modalPresentationStyle = .overFullScreen
|
||||
shareLogsModal.modalTransitionStyle = .crossDissolve
|
||||
|
||||
return shareLogsModal
|
||||
}
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
SectionModel(
|
||||
model: .translate,
|
||||
elements: [
|
||||
SettingInfo(
|
||||
id: .translate,
|
||||
title: "HELP_TRANSLATE_TITLE".localized(),
|
||||
action: .trigger(action: {
|
||||
guard let url: URL = URL(string: "https://crowdin.com/project/session-ios") else {
|
||||
return
|
||||
}
|
||||
|
||||
UIApplication.shared.open(url)
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
SectionModel(
|
||||
model: .feedback,
|
||||
elements: [
|
||||
SettingInfo(
|
||||
id: .feedback,
|
||||
title: "HELP_FEEDBACK_TITLE".localized(),
|
||||
action: .trigger(action: {
|
||||
guard let url: URL = URL(string: "https://getsession.org/survey") else {
|
||||
return
|
||||
}
|
||||
|
||||
UIApplication.shared.open(url)
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
SectionModel(
|
||||
model: .faq,
|
||||
elements: [
|
||||
SettingInfo(
|
||||
id: .faq,
|
||||
title: "HELP_FAQ_TITLE".localized(),
|
||||
action: .trigger(action: {
|
||||
guard let url: URL = URL(string: "https://getsession.org/faq") else {
|
||||
return
|
||||
}
|
||||
|
||||
UIApplication.shared.open(url)
|
||||
})
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
}
|
||||
.removeDuplicates()
|
||||
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
public override func updateSettings(_ updatedSettings: [SectionModel]) {
|
||||
self._settingsData = updatedSettings
|
||||
}
|
||||
|
||||
public override func saveChanges() {}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import DifferenceKit
|
||||
import SessionUIKit
|
||||
import SessionMessagingKit
|
||||
import SessionUtilitiesKit
|
||||
|
||||
class NotificationContentViewModel: SettingsTableViewModel<NotificationSettingsViewModel.Section, Preferences.NotificationPreviewType> {
|
||||
// MARK: - Section
|
||||
|
||||
public enum Section: SettingSection {
|
||||
case content
|
||||
|
||||
var title: String { return "" } // No title
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
override var title: String { "NOTIFICATIONS_STYLE_CONTENT_TITLE".localized() }
|
||||
|
||||
private var _settingsData: [SectionModel] = []
|
||||
public override var settingsData: [SectionModel] { _settingsData }
|
||||
|
||||
public override var observableSettingsData: ObservableData { _observableSettingsData }
|
||||
|
||||
/// This is all the data the screen needs to populate itself, please see the following link for tips to help optimise
|
||||
/// performance https://github.com/groue/GRDB.swift#valueobservation-performance
|
||||
///
|
||||
/// **Note:** This observation will be triggered twice immediately (and be de-duped by the `removeDuplicates`)
|
||||
/// this is due to the behaviour of `ValueConcurrentObserver.asyncStartObservation` which triggers it's own
|
||||
/// fetch (after the ones in `ValueConcurrentObserver.asyncStart`/`ValueConcurrentObserver.syncStart`)
|
||||
/// just in case the database has changed between the two reads - unfortunately it doesn't look like there is a way to prevent this
|
||||
private lazy var _observableSettingsData: ObservableData = ValueObservation
|
||||
.trackingConstantRegion { [weak self] db -> [SectionModel] in
|
||||
let currentSelection: Preferences.NotificationPreviewType? = db[.preferencesNotificationPreviewType]
|
||||
|
||||
return [
|
||||
SectionModel(
|
||||
model: .content,
|
||||
elements: Preferences.NotificationPreviewType.allCases
|
||||
.map { previewType in
|
||||
SettingInfo(
|
||||
id: previewType,
|
||||
title: previewType.name,
|
||||
action: .listSelection(
|
||||
isSelected: { (currentSelection == previewType) },
|
||||
storedSelection: (currentSelection == previewType),
|
||||
shouldAutoSave: true,
|
||||
selectValue: {
|
||||
Storage.shared.write { db in
|
||||
db[.preferencesNotificationPreviewType] = previewType
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
.removeDuplicates()
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
public override func updateSettings(_ updatedSettings: [SectionModel]) {
|
||||
self._settingsData = updatedSettings
|
||||
}
|
||||
|
||||
public override func saveChanges() {}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
||||
|
||||
@interface NotificationSettingsOptionsViewController : OWSTableViewController
|
||||
|
||||
@end
|
|
@ -1,56 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NotificationSettingsOptionsViewController.h"
|
||||
#import "Session-Swift.h"
|
||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||
|
||||
@implementation NotificationSettingsOptionsViewController
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self updateTableContents];
|
||||
|
||||
[LKViewControllerUtilities setUpDefaultSessionStyleForVC:self withTitle:NSLocalizedString(@"Content", @"") customBackButton:NO];
|
||||
self.tableView.backgroundColor = UIColor.clearColor;
|
||||
}
|
||||
|
||||
#pragma mark - Table Contents
|
||||
|
||||
- (void)updateTableContents
|
||||
{
|
||||
OWSTableContents *contents = [OWSTableContents new];
|
||||
|
||||
__weak NotificationSettingsOptionsViewController *weakSelf = self;
|
||||
|
||||
OWSTableSection *section = [OWSTableSection new];
|
||||
// section.footerTitle = NSLocalizedString(@"NOTIFICATIONS_FOOTER_WARNING", nil);
|
||||
|
||||
NSInteger selectedNotifType = [SMKPreferences notificationPreviewType];
|
||||
|
||||
for (NSNumber *option in [SMKPreferences notificationTypes]) {
|
||||
[section addItem:[OWSTableItem
|
||||
itemWithCustomCellBlock:^{
|
||||
UITableViewCell *cell = [OWSTableItem newCell];
|
||||
cell.tintColor = LKColors.accent;
|
||||
[[cell textLabel] setText:[SMKPreferences nameForNotificationPreviewType:option.intValue]];
|
||||
if (selectedNotifType == option.intValue) {
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
}
|
||||
cell.accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER_WITH_NAME(NotificationSettingsOptionsViewController, [SMKPreferences accessibilityIdentifierForNotificationPreviewType:option.intValue]);
|
||||
return cell;
|
||||
}
|
||||
actionBlock:^{
|
||||
[SMKPreferences setNotificationPreviewType: option.intValue];
|
||||
[weakSelf.navigationController popViewControllerAnimated:YES];
|
||||
}]];
|
||||
}
|
||||
[contents addSection:section];
|
||||
|
||||
self.contents = contents;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,9 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
||||
|
||||
@interface NotificationSettingsViewController : OWSTableViewController
|
||||
|
||||
@end
|
|
@ -1,119 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
@import PromiseKit;
|
||||
|
||||
#import "NotificationSettingsViewController.h"
|
||||
#import "NotificationSettingsOptionsViewController.h"
|
||||
#import "OWSSoundSettingsViewController.h"
|
||||
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||
#import <SignalUtilitiesKit/UIUtil.h>
|
||||
#import "Session-Swift.h"
|
||||
|
||||
@implementation NotificationSettingsViewController
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self updateTableContents];
|
||||
|
||||
[LKViewControllerUtilities setUpDefaultSessionStyleForVC:self withTitle:NSLocalizedString(@"vc_notification_settings_title", @"") customBackButton:YES];
|
||||
self.tableView.backgroundColor = UIColor.clearColor;
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
||||
#pragma mark - Table Contents
|
||||
|
||||
- (void)updateTableContents
|
||||
{
|
||||
OWSTableContents *contents = [OWSTableContents new];
|
||||
|
||||
__weak NotificationSettingsViewController *weakSelf = self;
|
||||
|
||||
OWSTableSection *strategySection = [OWSTableSection new];
|
||||
strategySection.headerTitle = NSLocalizedString(@"preferences_notifications_strategy_category_title", @"");
|
||||
[strategySection addItem:[OWSTableItem switchItemWithText:NSLocalizedString(@"vc_notification_settings_notification_mode_title", @"")
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"push_notification_strategy")
|
||||
isOnBlock:^{
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:@"isUsingFullAPNs"];
|
||||
}
|
||||
isEnabledBlock:^{
|
||||
return YES;
|
||||
}
|
||||
target:weakSelf
|
||||
selector:@selector(didToggleAPNsSwitch:)]];
|
||||
strategySection.footerTitle = @"You’ll be notified of new messages reliably and immediately using Apple’s notification servers.";
|
||||
[contents addSection:strategySection];
|
||||
|
||||
// Sounds section.
|
||||
|
||||
OWSTableSection *soundsSection = [OWSTableSection new];
|
||||
soundsSection.headerTitle
|
||||
= NSLocalizedString(@"SETTINGS_SECTION_SOUNDS", @"Header Label for the sounds section of settings views.");
|
||||
[soundsSection
|
||||
addItem:[OWSTableItem disclosureItemWithText:
|
||||
NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND",
|
||||
@"Label for settings view that allows user to change the notification sound.")
|
||||
detailText:[SMKSound displayNameFor:[SMKSound defaultNotificationSound]]
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"message_sound")
|
||||
actionBlock:^{
|
||||
OWSSoundSettingsViewController *vc = [OWSSoundSettingsViewController new];
|
||||
[weakSelf.navigationController pushViewController:vc animated:YES];
|
||||
}]];
|
||||
|
||||
NSString *inAppSoundsLabelText = NSLocalizedString(@"NOTIFICATIONS_SECTION_INAPP",
|
||||
@"Table cell switch label. When disabled, Signal will not play notification sounds while the app is in the "
|
||||
@"foreground.");
|
||||
[soundsSection addItem:[OWSTableItem switchItemWithText:inAppSoundsLabelText
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"in_app_sounds")
|
||||
isOnBlock:^{
|
||||
return [SMKPreferences playNotificationSoundInForeground];
|
||||
}
|
||||
isEnabledBlock:^{
|
||||
return YES;
|
||||
}
|
||||
target:weakSelf
|
||||
selector:@selector(didToggleSoundNotificationsSwitch:)]];
|
||||
[contents addSection:soundsSection];
|
||||
|
||||
OWSTableSection *backgroundSection = [OWSTableSection new];
|
||||
backgroundSection.headerTitle = NSLocalizedString(@"SETTINGS_NOTIFICATION_CONTENT_TITLE", @"table section header");
|
||||
[backgroundSection
|
||||
addItem:[OWSTableItem
|
||||
disclosureItemWithText:NSLocalizedString(@"NOTIFICATIONS_SHOW", nil)
|
||||
detailText:[SMKPreferences nameForNotificationPreviewType:[SMKPreferences notificationPreviewType]]
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"options")
|
||||
actionBlock:^{
|
||||
NotificationSettingsOptionsViewController *vc =
|
||||
[NotificationSettingsOptionsViewController new];
|
||||
[weakSelf.navigationController pushViewController:vc animated:YES];
|
||||
}]];
|
||||
backgroundSection.footerTitle
|
||||
= NSLocalizedString(@"The information shown in notifications when your phone is locked.", @"");
|
||||
[contents addSection:backgroundSection];
|
||||
|
||||
self.contents = contents;
|
||||
}
|
||||
|
||||
#pragma mark - Events
|
||||
|
||||
- (void)didToggleSoundNotificationsSwitch:(UISwitch *)sender
|
||||
{
|
||||
[SMKPreferences setPlayNotificationSoundInForeground:sender.on];
|
||||
}
|
||||
|
||||
- (void)didToggleAPNsSwitch:(UISwitch *)sender
|
||||
{
|
||||
[NSUserDefaults.standardUserDefaults setBool:sender.on forKey:@"isUsingFullAPNs"];
|
||||
[OWSSyncPushTokensJob run]; // FIXME: Only usage of 'OWSSyncPushTokensJob' - remove when gone
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import DifferenceKit
|
||||
import SessionUIKit
|
||||
import SessionMessagingKit
|
||||
import SessionUtilitiesKit
|
||||
|
||||
class NotificationSettingsViewModel: SettingsTableViewModel<NotificationSettingsViewModel.Section, NotificationSettingsViewModel.Setting> {
|
||||
// MARK: - Section
|
||||
|
||||
public enum Section: SettingSection {
|
||||
case strategy
|
||||
case style
|
||||
case content
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .strategy: return "NOTIFICATIONS_SECTION_STRATEGY".localized()
|
||||
case .style: return "NOTIFICATIONS_SECTION_STYLE".localized()
|
||||
case .content: return "" // No title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Setting: Differentiable {
|
||||
case strategyUseFastMode
|
||||
case styleSound
|
||||
case styleSoundWhenAppIsOpen
|
||||
case content
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
override var title: String { "NOTIFICATIONS_TITLE".localized() }
|
||||
|
||||
private var _settingsData: [SectionModel] = []
|
||||
public override var settingsData: [SectionModel] { _settingsData }
|
||||
|
||||
public override var observableSettingsData: ObservableData { _observableSettingsData }
|
||||
|
||||
/// This is all the data the screen needs to populate itself, please see the following link for tips to help optimise
|
||||
/// performance https://github.com/groue/GRDB.swift#valueobservation-performance
|
||||
///
|
||||
/// **Note:** This observation will be triggered twice immediately (and be de-duped by the `removeDuplicates`)
|
||||
/// this is due to the behaviour of `ValueConcurrentObserver.asyncStartObservation` which triggers it's own
|
||||
/// fetch (after the ones in `ValueConcurrentObserver.asyncStart`/`ValueConcurrentObserver.syncStart`)
|
||||
/// just in case the database has changed between the two reads - unfortunately it doesn't look like there is a way to prevent this
|
||||
private lazy var _observableSettingsData: ObservableData = ValueObservation
|
||||
.trackingConstantRegion { db -> [SectionModel] in
|
||||
return [
|
||||
SectionModel(
|
||||
model: .strategy,
|
||||
elements: [
|
||||
SettingInfo(
|
||||
id: .strategyUseFastMode,
|
||||
title: "NOTIFICATIONS_STRATEGY_FAST_MODE_TITLE".localized(),
|
||||
subtitle: "NOTIFICATIONS_STRATEGY_FAST_MODE_DESCRIPTION".localized(),
|
||||
action: .userDefaultsBool(
|
||||
defaults: UserDefaults.standard,
|
||||
key: "isUsingFullAPNs",
|
||||
onChange: {
|
||||
// Force sync the push tokens on change
|
||||
SyncPushTokensJob.run(uploadOnlyIfStale: false)
|
||||
}
|
||||
),
|
||||
extraActionTitle: { _, primaryColor in
|
||||
NSMutableAttributedString()
|
||||
.appending(
|
||||
NSAttributedString(
|
||||
string: "NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_1".localized(),
|
||||
attributes: [
|
||||
.foregroundColor: primaryColor.color
|
||||
]
|
||||
)
|
||||
)
|
||||
.appending(
|
||||
NSAttributedString(
|
||||
string: "NOTIFICATIONS_STRATEGY_FAST_MODE_ACTION_2".localized()
|
||||
)
|
||||
)
|
||||
},
|
||||
onExtraAction: { UIApplication.shared.openSystemSettings() }
|
||||
)
|
||||
]
|
||||
),
|
||||
SectionModel(
|
||||
model: .style,
|
||||
elements: [
|
||||
SettingInfo(
|
||||
id: .styleSound,
|
||||
title: "NOTIFICATIONS_STYLE_SOUND_TITLE".localized(),
|
||||
action: .settingEnum(
|
||||
db,
|
||||
type: Preferences.Sound.self,
|
||||
key: .defaultNotificationSound,
|
||||
titleGenerator: { $0?.displayName },
|
||||
createUpdateScreen: {
|
||||
SettingsTableViewController(viewModel: NotificationSoundViewModel())
|
||||
}
|
||||
)
|
||||
),
|
||||
SettingInfo(
|
||||
id: .styleSoundWhenAppIsOpen,
|
||||
title: "NOTIFICATIONS_STYLE_SOUND_WHEN_OPEN_TITLE".localized(),
|
||||
action: .settingBool(key: .playNotificationSoundInForeground)
|
||||
)
|
||||
]
|
||||
),
|
||||
SectionModel(
|
||||
model: .content,
|
||||
elements: [
|
||||
SettingInfo(
|
||||
id: .content,
|
||||
title: "NOTIFICATIONS_STYLE_CONTENT_TITLE".localized(),
|
||||
subtitle: "NOTIFICATIONS_STYLE_CONTENT_DESCRIPTION".localized(),
|
||||
action: .settingEnum(
|
||||
db,
|
||||
type: Preferences.NotificationPreviewType.self,
|
||||
key: .preferencesNotificationPreviewType,
|
||||
titleGenerator: { $0?.name },
|
||||
createUpdateScreen: {
|
||||
SettingsTableViewController(viewModel: NotificationContentViewModel())
|
||||
}
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
}
|
||||
.removeDuplicates()
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
public override func updateSettings(_ updatedSettings: [SectionModel]) {
|
||||
self._settingsData = updatedSettings
|
||||
}
|
||||
|
||||
public override func saveChanges() {}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import DifferenceKit
|
||||
import SessionUIKit
|
||||
import SessionMessagingKit
|
||||
import SessionUtilitiesKit
|
||||
|
||||
class NotificationSoundViewModel: SettingsTableViewModel<NotificationSettingsViewModel.Section, Preferences.Sound> {
|
||||
private var audioPlayer: OWSAudioPlayer?
|
||||
private var currentSelection: Preferences.Sound?
|
||||
|
||||
deinit {
|
||||
self.audioPlayer?.stop()
|
||||
self.audioPlayer = nil
|
||||
}
|
||||
|
||||
// MARK: - Section
|
||||
|
||||
public enum Section: SettingSection {
|
||||
case content
|
||||
|
||||
var title: String { return "" } // No title
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
override var title: String { "NOTIFICATIONS_STYLE_SOUND_TITLE".localized() }
|
||||
|
||||
private var _settingsData: [SectionModel] = []
|
||||
public override var settingsData: [SectionModel] { _settingsData }
|
||||
|
||||
public override var observableSettingsData: ObservableData { _observableSettingsData }
|
||||
|
||||
/// This is all the data the screen needs to populate itself, please see the following link for tips to help optimise
|
||||
/// performance https://github.com/groue/GRDB.swift#valueobservation-performance
|
||||
///
|
||||
/// **Note:** This observation will be triggered twice immediately (and be de-duped by the `removeDuplicates`)
|
||||
/// this is due to the behaviour of `ValueConcurrentObserver.asyncStartObservation` which triggers it's own
|
||||
/// fetch (after the ones in `ValueConcurrentObserver.asyncStart`/`ValueConcurrentObserver.syncStart`)
|
||||
/// just in case the database has changed between the two reads - unfortunately it doesn't look like there is a way to prevent this
|
||||
private lazy var _observableSettingsData: ObservableData = ValueObservation
|
||||
.trackingConstantRegion { [weak self] db -> [SectionModel] in
|
||||
self?.currentSelection = (self?.currentSelection ?? db[.defaultNotificationSound])
|
||||
|
||||
return [
|
||||
SectionModel(
|
||||
model: .content,
|
||||
elements: Preferences.Sound.notificationSounds
|
||||
.map { sound in
|
||||
SettingInfo(
|
||||
id: sound,
|
||||
title: {
|
||||
guard sound != .note else {
|
||||
return String(
|
||||
format: "SETTINGS_AUDIO_DEFAULT_TONE_LABEL_FORMAT".localized(),
|
||||
sound.displayName
|
||||
)
|
||||
}
|
||||
|
||||
return sound.displayName
|
||||
}(),
|
||||
action: .listSelection(
|
||||
isSelected: { (self?.currentSelection == sound) },
|
||||
storedSelection: (db[.defaultNotificationSound] == sound),
|
||||
shouldAutoSave: false,
|
||||
selectValue: {
|
||||
self?.currentSelection = sound
|
||||
|
||||
// Play the sound (to prevent UI lag we dispatch this to the next
|
||||
// run loop
|
||||
DispatchQueue.main.async {
|
||||
self?.audioPlayer?.stop()
|
||||
self?.audioPlayer = SMKSound.audioPlayer(
|
||||
for: sound.rawValue,
|
||||
audioBehavior: .playback
|
||||
)
|
||||
self?.audioPlayer?.isLooping = false
|
||||
self?.audioPlayer?.play()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
.removeDuplicates()
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
public override func updateSettings(_ updatedSettings: [SectionModel]) {
|
||||
self._settingsData = updatedSettings
|
||||
}
|
||||
|
||||
public override func saveChanges() {
|
||||
guard let currentSelection: Preferences.Sound = self.currentSelection else { return }
|
||||
|
||||
Storage.shared.write { db in
|
||||
db[.defaultNotificationSound] = currentSelection
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSTableViewController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSThread;
|
||||
|
||||
@interface OWSSoundSettingsViewController : OWSTableViewController
|
||||
|
||||
// This property is optional. If it is not set, we are
|
||||
// editing the global notification sound.
|
||||
@property (nonatomic, nullable) NSString *threadId;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,169 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSSoundSettingsViewController.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <SessionMessagingKit/OWSAudioPlayer.h>
|
||||
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||
#import <SignalUtilitiesKit/UIUtil.h>
|
||||
#import "Session-Swift.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSSoundSettingsViewController ()
|
||||
|
||||
@property (nonatomic) BOOL isDirty;
|
||||
|
||||
@property (nonatomic) NSInteger currentSound;
|
||||
|
||||
@property (nonatomic, nullable) OWSAudioPlayer *audioPlayer;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSSoundSettingsViewController
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self setTitle:NSLocalizedString(@"SETTINGS_ITEM_NOTIFICATION_SOUND",
|
||||
@"Label for settings view that allows user to change the notification sound.")];
|
||||
self.currentSound = [SMKSound notificationSoundFor:self.threadId];
|
||||
|
||||
[self updateTableContents];
|
||||
[self updateNavigationItems];
|
||||
|
||||
[LKViewControllerUtilities setUpDefaultSessionStyleForVC:self withTitle:NSLocalizedString(@"Sound", @"") customBackButton:NO];
|
||||
self.tableView.backgroundColor = UIColor.clearColor;
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
||||
- (void)updateNavigationItems
|
||||
{
|
||||
UIBarButtonItem *cancelItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
|
||||
target:self
|
||||
action:@selector(cancelWasPressed:)
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"cancel")];
|
||||
|
||||
cancelItem.tintColor = LKColors.text;
|
||||
|
||||
self.navigationItem.leftBarButtonItem = cancelItem;
|
||||
|
||||
if (self.isDirty) {
|
||||
UIBarButtonItem *saveItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
|
||||
target:self
|
||||
action:@selector(saveWasPressed:)
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"save")];
|
||||
self.navigationItem.rightBarButtonItem = saveItem;
|
||||
} else {
|
||||
self.navigationItem.rightBarButtonItem = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Table Contents
|
||||
|
||||
- (void)updateTableContents
|
||||
{
|
||||
OWSTableContents *contents = [OWSTableContents new];
|
||||
|
||||
__weak OWSSoundSettingsViewController *weakSelf = self;
|
||||
|
||||
OWSTableSection *soundsSection = [OWSTableSection new];
|
||||
soundsSection.headerTitle = NSLocalizedString(
|
||||
@"NOTIFICATIONS_SECTION_SOUNDS", @"Label for settings UI that allows user to change the notification sound.");
|
||||
|
||||
NSArray<NSNumber *> *allSounds = [SMKSound notificationSounds];
|
||||
for (NSNumber *nsValue in allSounds) {
|
||||
NSInteger sound = nsValue.integerValue;
|
||||
OWSTableItem *item;
|
||||
|
||||
NSString *soundLabelText = ^{
|
||||
NSString *baseName = [SMKSound displayNameFor:sound];
|
||||
if ([SMKSound isNote:sound]) {
|
||||
NSString *noteStringFormat = NSLocalizedString(@"SETTINGS_AUDIO_DEFAULT_TONE_LABEL_FORMAT",
|
||||
@"Format string for the default 'Note' sound. Embeds the system {{sound name}}.");
|
||||
return [NSString stringWithFormat:noteStringFormat, baseName];
|
||||
}
|
||||
else {
|
||||
return [SMKSound displayNameFor:sound];
|
||||
}
|
||||
}();
|
||||
|
||||
if (sound == self.currentSound) {
|
||||
item = [OWSTableItem
|
||||
checkmarkItemWithText:soundLabelText
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, [SMKSound displayNameFor:sound])
|
||||
actionBlock:^{
|
||||
[weakSelf soundWasSelected:sound];
|
||||
}];
|
||||
} else {
|
||||
item = [OWSTableItem
|
||||
actionItemWithText:soundLabelText
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, [SMKSound displayNameFor:sound])
|
||||
actionBlock:^{
|
||||
[weakSelf soundWasSelected:sound];
|
||||
}];
|
||||
}
|
||||
[soundsSection addItem:item];
|
||||
}
|
||||
|
||||
[contents addSection:soundsSection];
|
||||
|
||||
self.contents = contents;
|
||||
}
|
||||
|
||||
#pragma mark - Events
|
||||
|
||||
- (void)soundWasSelected:(NSInteger)sound
|
||||
{
|
||||
[self.audioPlayer stop];
|
||||
self.audioPlayer = [SMKSound audioPlayerFor:sound audioBehavior:OWSAudioBehavior_Playback];
|
||||
// Suppress looping in this view.
|
||||
self.audioPlayer.isLooping = NO;
|
||||
[self.audioPlayer play];
|
||||
|
||||
if (self.currentSound == sound) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.currentSound = sound;
|
||||
self.isDirty = YES;
|
||||
[self updateTableContents];
|
||||
[self updateNavigationItems];
|
||||
}
|
||||
|
||||
- (void)cancelWasPressed:(id)sender
|
||||
{
|
||||
// TODO: Add "discard changes?" alert.
|
||||
[self.audioPlayer stop];
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)saveWasPressed:(id)sender
|
||||
{
|
||||
if (self.threadId) {
|
||||
[SMKSound setNotificationSound:self.currentSound forThreadId:self.threadId];
|
||||
}
|
||||
else {
|
||||
[SMKSound setGlobalNotificationSound:self.currentSound];
|
||||
}
|
||||
|
||||
[self.audioPlayer stop];
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,391 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import GRDB
|
||||
import DifferenceKit
|
||||
import SessionUIKit
|
||||
import SessionUtilitiesKit
|
||||
import SignalUtilitiesKit
|
||||
|
||||
class SettingsTableViewController<Section: SettingSection, SettingItem: Hashable & Differentiable>: BaseVC, UITableViewDataSource, UITableViewDelegate {
|
||||
typealias SectionModel = SettingsTableViewModel<Section, SettingItem>.SectionModel
|
||||
|
||||
private let viewModel: SettingsTableViewModel<Section, SettingItem>
|
||||
private var dataChangeObservable: DatabaseCancellable?
|
||||
private var hasLoadedInitialSettingsData: Bool = false
|
||||
|
||||
// MARK: - Components
|
||||
|
||||
private lazy var tableView: UITableView = {
|
||||
let result: UITableView = UITableView()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.separatorStyle = .none
|
||||
result.backgroundColor = .clear
|
||||
result.showsVerticalScrollIndicator = false
|
||||
result.showsHorizontalScrollIndicator = false
|
||||
result.register(view: SettingsCell.self)
|
||||
result.registerHeaderFooterView(view: SettingHeaderView.self)
|
||||
result.dataSource = self
|
||||
result.delegate = self
|
||||
|
||||
if #available(iOS 15.0, *) {
|
||||
result.sectionHeaderTopPadding = 0
|
||||
}
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(viewModel: SettingsTableViewModel<Section, SettingItem>) {
|
||||
self.viewModel = viewModel
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
ViewControllerUtilities.setUpDefaultSessionStyle(
|
||||
for: self,
|
||||
title: viewModel.title,
|
||||
hasCustomBackButton: false
|
||||
)
|
||||
|
||||
view.themeBackgroundColor = .backgroundPrimary
|
||||
view.addSubview(tableView)
|
||||
|
||||
setupLayout()
|
||||
|
||||
// Notifications
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(applicationDidBecomeActive(_:)),
|
||||
name: UIApplication.didBecomeActiveNotification,
|
||||
object: nil
|
||||
)
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(applicationDidResignActive(_:)),
|
||||
name: UIApplication.didEnterBackgroundNotification, object: nil
|
||||
)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
startObservingChanges()
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
stopObservingChanges()
|
||||
}
|
||||
|
||||
@objc func applicationDidBecomeActive(_ notification: Notification) {
|
||||
startObservingChanges()
|
||||
}
|
||||
|
||||
@objc func applicationDidResignActive(_ notification: Notification) {
|
||||
stopObservingChanges()
|
||||
}
|
||||
|
||||
private func setupLayout() {
|
||||
tableView.pin(to: view)
|
||||
}
|
||||
|
||||
// MARK: - Updating
|
||||
|
||||
private func startObservingChanges() {
|
||||
// Start observing for data changes
|
||||
dataChangeObservable = Storage.shared.start(
|
||||
viewModel.observableSettingsData,
|
||||
// If we haven't done the initial load the trigger it immediately (blocking the main
|
||||
// thread so we remain on the launch screen until it completes to be consistent with
|
||||
// the old behaviour)
|
||||
scheduling: (hasLoadedInitialSettingsData ?
|
||||
.async(onQueue: .main) :
|
||||
.immediate
|
||||
),
|
||||
onError: { _ in },
|
||||
onChange: { [weak self] settingsData in
|
||||
// The default scheduler emits changes on the main thread
|
||||
self?.handleSettingsUpdates(settingsData)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private func stopObservingChanges() {
|
||||
// Stop observing database changes
|
||||
dataChangeObservable?.cancel()
|
||||
}
|
||||
|
||||
private func handleSettingsUpdates(_ updatedData: [SectionModel], initialLoad: Bool = false) {
|
||||
// Ensure the first load runs without animations (if we don't do this the cells will animate
|
||||
// in from a frame of CGRect.zero)
|
||||
guard hasLoadedInitialSettingsData else {
|
||||
hasLoadedInitialSettingsData = true
|
||||
UIView.performWithoutAnimation { handleSettingsUpdates(updatedData, initialLoad: true) }
|
||||
return
|
||||
}
|
||||
|
||||
// Navigation bar
|
||||
updateNavigation(updatedData)
|
||||
|
||||
// Reload the table content (animate changes after the first load)
|
||||
tableView.reload(
|
||||
using: StagedChangeset(source: viewModel.settingsData, target: updatedData),
|
||||
deleteSectionsAnimation: .none,
|
||||
insertSectionsAnimation: .none,
|
||||
reloadSectionsAnimation: .none,
|
||||
deleteRowsAnimation: .bottom,
|
||||
insertRowsAnimation: .none,
|
||||
reloadRowsAnimation: .none,
|
||||
interrupt: { $0.changeCount > 100 } // Prevent too many changes from causing performance issues
|
||||
) { [weak self] updatedData in
|
||||
self?.viewModel.updateSettings(updatedData)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateNavigation(_ data: [SectionModel]) {
|
||||
guard
|
||||
case .listSelection(_, _, let shouldAutoSave, _) = data.first?.elements.first?.action,
|
||||
!shouldAutoSave
|
||||
else {
|
||||
navigationItem.leftBarButtonItem = nil
|
||||
navigationItem.rightBarButtonItem = nil
|
||||
return
|
||||
}
|
||||
|
||||
let isStoredSelected: Bool = (data.first?.elements ?? []).contains { info in
|
||||
switch info.action {
|
||||
case .listSelection(let isSelected, let storedSelection, _, _):
|
||||
return (isSelected() && storedSelection)
|
||||
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
let cancelButton: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonPressed))
|
||||
cancelButton.themeTintColor = .textPrimary
|
||||
navigationItem.leftBarButtonItem = cancelButton
|
||||
|
||||
let saveButton: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveButtonPressed))
|
||||
saveButton.themeTintColor = .textPrimary
|
||||
navigationItem.rightBarButtonItem = (isStoredSelected ? nil : saveButton)
|
||||
}
|
||||
|
||||
// MARK: - UITableViewDataSource
|
||||
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return self.viewModel.settingsData.count
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return self.viewModel.settingsData[section].elements.count
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let section: SectionModel = viewModel.settingsData[indexPath.section]
|
||||
let settingInfo: SettingInfo<SettingItem> = section.elements[indexPath.row]
|
||||
|
||||
let cell: SettingsCell = tableView.dequeue(type: SettingsCell.self, for: indexPath)
|
||||
cell.update(
|
||||
title: settingInfo.title,
|
||||
subtitle: settingInfo.subtitle,
|
||||
action: settingInfo.action,
|
||||
extraActionTitle: settingInfo.extraActionTitle,
|
||||
onExtraAction: settingInfo.onExtraAction,
|
||||
isFirstInSection: (indexPath.row == 0),
|
||||
isLastInSection: (indexPath.row == (section.elements.count - 1))
|
||||
)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
let section: SectionModel = viewModel.settingsData[section]
|
||||
let view: SettingHeaderView = tableView.dequeueHeaderFooterView(type: SettingHeaderView.self)
|
||||
view.update(with: section.model.title)
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
// MARK: - UITableViewDelegate
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
|
||||
let section: SectionModel = self.viewModel.settingsData[indexPath.section]
|
||||
let settingInfo: SettingInfo<SettingItem> = section.elements[indexPath.row]
|
||||
|
||||
switch settingInfo.action {
|
||||
case .trigger(let action):
|
||||
action()
|
||||
|
||||
case .rightButtonModal(_, let createModal):
|
||||
let viewController: UIViewController = createModal()
|
||||
present(viewController, animated: true, completion: nil)
|
||||
|
||||
case .userDefaultsBool(let defaults, let key, let onChange):
|
||||
defaults.set(!defaults.bool(forKey: key), forKey: key)
|
||||
manuallyReload(indexPath: indexPath, section: section, settingInfo: settingInfo)
|
||||
onChange?()
|
||||
|
||||
case .settingBool(let key):
|
||||
Storage.shared.write { db in db[key] = !db[key] }
|
||||
manuallyReload(indexPath: indexPath, section: section, settingInfo: settingInfo)
|
||||
|
||||
case .push(let createDestination), .dangerPush(let createDestination),
|
||||
.settingEnum(_, _, let createDestination):
|
||||
let viewController: UIViewController = createDestination()
|
||||
navigationController?.pushViewController(viewController, animated: true)
|
||||
|
||||
case .listSelection(_, _, let shouldAutoSave, let selectValue):
|
||||
let maybeOldSelection: (Int, SettingInfo<SettingItem>)? = section.elements
|
||||
.enumerated()
|
||||
.first(where: { index, info in
|
||||
switch info.action {
|
||||
case .listSelection(let isSelected, _, _, _): return isSelected()
|
||||
default: return false
|
||||
}
|
||||
})
|
||||
|
||||
selectValue()
|
||||
updateNavigation(viewModel.settingsData)
|
||||
manuallyReload(indexPath: indexPath, section: section, settingInfo: settingInfo)
|
||||
|
||||
// Update the old selection as well
|
||||
if let oldSelection: (index: Int, info: SettingInfo<SettingItem>) = maybeOldSelection {
|
||||
manuallyReload(
|
||||
indexPath: IndexPath(
|
||||
row: oldSelection.index,
|
||||
section: indexPath.section
|
||||
),
|
||||
section: section,
|
||||
settingInfo: oldSelection.info
|
||||
)
|
||||
}
|
||||
|
||||
guard shouldAutoSave else { return }
|
||||
|
||||
navigationController?.popViewController(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func manuallyReload(
|
||||
indexPath: IndexPath,
|
||||
section: SectionModel,
|
||||
settingInfo: SettingInfo<SettingItem>
|
||||
) {
|
||||
// Try update the existing cell to have a nice animation instead of reloading the cell
|
||||
if let existingCell: SettingsCell = tableView.cellForRow(at: indexPath) as? SettingsCell {
|
||||
existingCell.update(
|
||||
title: settingInfo.title,
|
||||
subtitle: settingInfo.subtitle,
|
||||
action: settingInfo.action,
|
||||
extraActionTitle: settingInfo.extraActionTitle,
|
||||
onExtraAction: settingInfo.onExtraAction,
|
||||
isFirstInSection: (indexPath.row == 0),
|
||||
isLastInSection: (indexPath.row == (section.elements.count - 1))
|
||||
)
|
||||
}
|
||||
else {
|
||||
tableView.reloadRows(at: [indexPath], with: .none)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - NavigationActions
|
||||
|
||||
@objc private func cancelButtonPressed() {
|
||||
navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
||||
@objc private func saveButtonPressed() {
|
||||
viewModel.saveChanges()
|
||||
|
||||
navigationController?.popViewController(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SettingHeaderView
|
||||
|
||||
class SettingHeaderView: UITableViewHeaderFooterView {
|
||||
// MARK: - UI
|
||||
|
||||
private let stackView: UIStackView = {
|
||||
let result: UIStackView = UIStackView()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.axis = .vertical
|
||||
result.distribution = .fill
|
||||
result.alignment = .fill
|
||||
result.isLayoutMarginsRelativeArrangement = true
|
||||
result.layoutMargins = UIEdgeInsets(
|
||||
top: Values.mediumSpacing,
|
||||
left: Values.largeSpacing,
|
||||
bottom: Values.smallSpacing,
|
||||
right: Values.largeSpacing
|
||||
)
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let titleLabel: UILabel = {
|
||||
let result: UILabel = UILabel()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.font = .systemFont(ofSize: Values.mediumFontSize)
|
||||
result.themeTextColor = .textSecondary
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let separator: UIView = UIView.separator()
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init(reuseIdentifier: String?) {
|
||||
super.init(reuseIdentifier: reuseIdentifier)
|
||||
|
||||
self.backgroundView = UIView()
|
||||
self.backgroundView?.themeBackgroundColor = .backgroundPrimary
|
||||
|
||||
addSubview(stackView)
|
||||
addSubview(separator)
|
||||
|
||||
stackView.addArrangedSubview(titleLabel)
|
||||
|
||||
setupLayout()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func setupLayout() {
|
||||
self.heightAnchor.constraint(greaterThanOrEqualToConstant: Values.mediumSpacing).isActive = true
|
||||
|
||||
stackView.pin(to: self)
|
||||
|
||||
separator.pin(.left, to: .left, of: self)
|
||||
separator.pin(.right, to: .right, of: self)
|
||||
separator.pin(.bottom, to: .bottom, of: self)
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
fileprivate func update(with title: String) {
|
||||
titleLabel.text = title
|
||||
titleLabel.isHidden = title.isEmpty
|
||||
}
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import DifferenceKit
|
||||
import SessionUIKit
|
||||
import SessionUtilitiesKit
|
||||
|
||||
class SettingsTableViewModel<Section: SettingSection, SettingItem: Hashable & Differentiable> {
|
||||
typealias SectionModel = ArraySection<Section, SettingInfo<SettingItem>>
|
||||
typealias ObservableData = ValueObservation<ValueReducers.RemoveDuplicates<ValueReducers.Fetch<[SectionModel]>>>
|
||||
|
||||
open var title: String { preconditionFailure("abstract class - override in subclass") }
|
||||
open var settingsData: [SectionModel] { preconditionFailure("abstract class - override in subclass") }
|
||||
open var observableSettingsData: ObservableData {
|
||||
preconditionFailure("abstract class - override in subclass")
|
||||
}
|
||||
|
||||
func updateSettings(_ updatedSettings: [SectionModel]) {
|
||||
preconditionFailure("abstract class - override in subclass")
|
||||
}
|
||||
|
||||
func saveChanges() {
|
||||
preconditionFailure("abstract class - override in subclass")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SettingSection
|
||||
|
||||
protocol SettingSection: Differentiable {
|
||||
var title: String { get }
|
||||
}
|
||||
|
||||
// MARK: - SettingInfo
|
||||
|
||||
struct SettingInfo<ID: Hashable & Differentiable>: Equatable, Hashable, Differentiable {
|
||||
let id: ID
|
||||
let title: String
|
||||
let subtitle: String?
|
||||
let action: SettingsAction
|
||||
let extraActionTitle: ((Theme, Theme.PrimaryColor) -> NSAttributedString)?
|
||||
let onExtraAction: (() -> Void)?
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(
|
||||
id: ID,
|
||||
title: String,
|
||||
subtitle: String? = nil,
|
||||
action: SettingsAction,
|
||||
extraActionTitle: ((Theme, Theme.PrimaryColor) -> NSAttributedString)? = nil,
|
||||
onExtraAction: (() -> Void)? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.action = action
|
||||
self.extraActionTitle = extraActionTitle
|
||||
self.onExtraAction = onExtraAction
|
||||
}
|
||||
|
||||
// MARK: - Conformance
|
||||
|
||||
var differenceIdentifier: ID { id }
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
id.hash(into: &hasher)
|
||||
title.hash(into: &hasher)
|
||||
subtitle.hash(into: &hasher)
|
||||
action.hash(into: &hasher)
|
||||
}
|
||||
|
||||
static func == (lhs: SettingInfo<ID>, rhs: SettingInfo<ID>) -> Bool {
|
||||
return (
|
||||
lhs.id == rhs.id &&
|
||||
lhs.title == rhs.title &&
|
||||
lhs.subtitle == rhs.subtitle &&
|
||||
lhs.action == rhs.action
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SettingsAction
|
||||
|
||||
public enum SettingsAction: Hashable, Equatable {
|
||||
case userDefaultsBool(
|
||||
defaults: UserDefaults,
|
||||
key: String,
|
||||
onChange: (() -> Void)?
|
||||
)
|
||||
case settingBool(key: Setting.BoolKey)
|
||||
case settingEnum(
|
||||
key: String,
|
||||
title: String?,
|
||||
createUpdateScreen: () -> UIViewController
|
||||
)
|
||||
|
||||
case trigger(action: () -> Void)
|
||||
case push(createDestination: () -> UIViewController)
|
||||
case dangerPush(createDestination: () -> UIViewController)
|
||||
case listSelection(
|
||||
isSelected: () -> Bool,
|
||||
storedSelection: Bool,
|
||||
shouldAutoSave: Bool,
|
||||
selectValue: () -> Void
|
||||
)
|
||||
case rightButtonModal(
|
||||
title: String,
|
||||
createModal: () -> UIViewController
|
||||
)
|
||||
|
||||
private var actionName: String {
|
||||
switch self {
|
||||
case .userDefaultsBool: return "userDefaultsBool"
|
||||
case .settingBool: return "settingBool"
|
||||
case .settingEnum: return "settingEnum"
|
||||
|
||||
case .trigger: return "trigger"
|
||||
case .push: return "push"
|
||||
case .dangerPush: return "dangerPush"
|
||||
case .listSelection: return "listSelection"
|
||||
case .rightButtonModal: return "rightButtonModal"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Convenience
|
||||
|
||||
public static func settingEnum<ET: EnumIntSetting>(
|
||||
_ db: Database,
|
||||
type: ET.Type,
|
||||
key: Setting.EnumKey,
|
||||
titleGenerator: @escaping ((ET?) -> String?),
|
||||
createUpdateScreen: @escaping () -> UIViewController
|
||||
) -> SettingsAction {
|
||||
return SettingsAction.settingEnum(
|
||||
key: key.rawValue,
|
||||
title: titleGenerator(db[key]),
|
||||
createUpdateScreen: createUpdateScreen
|
||||
)
|
||||
}
|
||||
|
||||
public static func settingEnum<ET: EnumStringSetting>(
|
||||
_ db: Database,
|
||||
type: ET.Type,
|
||||
key: Setting.EnumKey,
|
||||
titleGenerator: @escaping ((ET?) -> String?),
|
||||
createUpdateScreen: @escaping () -> UIViewController
|
||||
) -> SettingsAction {
|
||||
return SettingsAction.settingEnum(
|
||||
key: key.rawValue,
|
||||
title: titleGenerator(db[key]),
|
||||
createUpdateScreen: createUpdateScreen
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Conformance
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
actionName.hash(into: &hasher)
|
||||
|
||||
switch self {
|
||||
case .userDefaultsBool(_, let key, _): key.hash(into: &hasher)
|
||||
case .settingBool(let key): key.hash(into: &hasher)
|
||||
case .settingEnum(let key, let title, _):
|
||||
key.hash(into: &hasher)
|
||||
title.hash(into: &hasher)
|
||||
|
||||
case .listSelection(let isSelected, let storedSelection, let shouldAutoSave, _):
|
||||
isSelected().hash(into: &hasher)
|
||||
storedSelection.hash(into: &hasher)
|
||||
shouldAutoSave.hash(into: &hasher)
|
||||
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
public static func == (lhs: SettingsAction, rhs: SettingsAction) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case (.userDefaultsBool(_, let lhsKey, _), .userDefaultsBool(_, let rhsKey, _)):
|
||||
return (lhsKey == rhsKey)
|
||||
|
||||
case (.settingBool(let lhsKey), .settingBool(let rhsKey)): return (lhsKey == rhsKey)
|
||||
|
||||
case (.settingEnum(let lhsKey, let lhsTitle, _), .settingEnum(let rhsKey, let rhsTitle, _)):
|
||||
return (
|
||||
lhsKey == rhsKey &&
|
||||
lhsTitle == rhsTitle
|
||||
)
|
||||
|
||||
case (.listSelection(let lhsIsSelected, let lhsStoredSelection, let lhsShouldAutoSave, _), .listSelection(let rhsIsSelected, let rhsStoredSelection, let rhsShouldAutoSave, _)):
|
||||
return (
|
||||
lhsIsSelected() == rhsIsSelected() &&
|
||||
lhsStoredSelection == rhsStoredSelection &&
|
||||
lhsShouldAutoSave == rhsShouldAutoSave
|
||||
)
|
||||
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -254,7 +254,7 @@ final class SettingsVC: BaseVC, AvatarViewHelperDelegate {
|
|||
UIView.separator(),
|
||||
getSettingButton(title: "vc_settings_notifications_button_title".localized(), action: #selector(showNotificationSettings)),
|
||||
UIView.separator(),
|
||||
getSettingButton(title: "CONVERSATIONS_TITLE".localized(), action: #selector(showChatSettings)),
|
||||
getSettingButton(title: "CONVERSATIONS_TITLE".localized(), action: #selector(showConversationSettings)),
|
||||
UIView.separator(),
|
||||
getSettingButton(title: "MESSAGE_REQUESTS_TITLE".localized(), action: #selector(showMessageRequests)),
|
||||
UIView.separator(),
|
||||
|
@ -544,8 +544,10 @@ final class SettingsVC: BaseVC, AvatarViewHelperDelegate {
|
|||
}
|
||||
|
||||
@objc private func showNotificationSettings() {
|
||||
let notificationSettingsVC = NotificationSettingsViewController()
|
||||
self.navigationController?.pushViewController(notificationSettingsVC, animated: true)
|
||||
let settingsViewController: SettingsTableViewController = SettingsTableViewController(
|
||||
viewModel: NotificationSettingsViewModel()
|
||||
)
|
||||
self.navigationController?.pushViewController(settingsViewController, animated: true)
|
||||
}
|
||||
|
||||
@objc private func showMessageRequests() {
|
||||
|
@ -553,9 +555,9 @@ final class SettingsVC: BaseVC, AvatarViewHelperDelegate {
|
|||
self.navigationController?.pushViewController(viewController, animated: true)
|
||||
}
|
||||
|
||||
@objc private func showChatSettings() {
|
||||
let chatSettingsVC = ChatSettingsViewController()
|
||||
self.navigationController?.pushViewController(chatSettingsVC, animated: true)
|
||||
@objc private func showConversationSettings() {
|
||||
let conversationSettingsVC = ConversationSettingsViewController()
|
||||
self.navigationController?.pushViewController(conversationSettingsVC, animated: true)
|
||||
}
|
||||
|
||||
@objc private func showAppearanceSettings() {
|
||||
|
@ -571,7 +573,10 @@ final class SettingsVC: BaseVC, AvatarViewHelperDelegate {
|
|||
}
|
||||
|
||||
@objc private func showHelp() {
|
||||
|
||||
let settingsViewController: SettingsTableViewController = SettingsTableViewController(
|
||||
viewModel: HelpViewModel()
|
||||
)
|
||||
self.navigationController?.pushViewController(settingsViewController, animated: true)
|
||||
}
|
||||
|
||||
@objc private func clearAllData() {
|
||||
|
|
|
@ -0,0 +1,402 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import GRDB
|
||||
import SessionUIKit
|
||||
|
||||
class SettingsCell: UITableViewCell {
|
||||
/// This value is here to allow the theming update callback to be released when preparing for reuse
|
||||
private var instanceView: UIView = UIView()
|
||||
private var onExtraAction: (() -> Void)?
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
private let topSeparator: UIView = {
|
||||
let result: UIView = UIView.separator()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let contentStackView: UIStackView = {
|
||||
let result: UIStackView = UIStackView()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.axis = .horizontal
|
||||
result.distribution = .equalSpacing
|
||||
result.alignment = .fill
|
||||
result.spacing = Values.mediumSpacing
|
||||
result.isLayoutMarginsRelativeArrangement = true
|
||||
result.layoutMargins = UIEdgeInsets(
|
||||
top: Values.mediumSpacing,
|
||||
leading: Values.largeSpacing,
|
||||
bottom: Values.mediumSpacing,
|
||||
trailing: Values.largeSpacing
|
||||
)
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let titleStackView: UIStackView = {
|
||||
let result: UIStackView = UIStackView()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.axis = .vertical
|
||||
result.distribution = .equalSpacing
|
||||
result.alignment = .fill
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let titleLabel: UILabel = {
|
||||
let result: UILabel = UILabel()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.font = .boldSystemFont(ofSize: Values.mediumFontSize)
|
||||
result.themeTextColor = .textPrimary
|
||||
result.numberOfLines = 0
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let subtitleLabel: UILabel = {
|
||||
let result: UILabel = UILabel()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.font = .systemFont(ofSize: Values.smallFontSize)
|
||||
result.themeTextColor = .textPrimary
|
||||
result.numberOfLines = 0
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var extraActionButton: UIButton = {
|
||||
let result: UIButton = UIButton()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.titleLabel?.font = .boldSystemFont(ofSize: Values.smallFontSize)
|
||||
result.contentHorizontalAlignment = .left
|
||||
result.contentEdgeInsets = UIEdgeInsets(
|
||||
top: 8,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0
|
||||
)
|
||||
result.addTarget(self, action: #selector(extraActionTapped), for: .touchUpInside)
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let actionContainerView: UIView = {
|
||||
let result: UIView = UIView()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let pushChevronImageView: UIImageView = {
|
||||
let result: UIImageView = UIImageView(image: UIImage(systemName: "chevron.right"))
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.themeTintColor = .textPrimary
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let toggleSwitch: UISwitch = {
|
||||
let result: UISwitch = UISwitch()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.isUserInteractionEnabled = false // Triggered by didSelectCell instead
|
||||
result.themeOnTintColor = .primary
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let dropDownImageView: UIImageView = {
|
||||
let result: UIImageView = UIImageView(image: UIImage(systemName: "arrowtriangle.down.fill"))
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.themeTintColor = .textPrimary
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let dropDownLabel: UILabel = {
|
||||
let result: UILabel = UILabel()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.font = .systemFont(ofSize: Values.smallFontSize, weight: .medium)
|
||||
result.themeTextColor = .textPrimary
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let tickImageView: UIImageView = {
|
||||
let result: UIImageView = UIImageView(image: UIImage(systemName: "checkmark"))
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.themeTintColor = .primary
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var rightActionButtonContainerView: UIView = {
|
||||
let result: UIView = UIView()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.themeBackgroundColor = .solidButton_background
|
||||
result.layer.cornerRadius = 5
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var rightActionButtonLabel: UILabel = {
|
||||
let result: UILabel = UILabel()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.font = .boldSystemFont(ofSize: Values.smallFontSize)
|
||||
result.themeTextColor = .textPrimary
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
private let botSeparator: UIView = {
|
||||
let result: UIView = UIView.separator()
|
||||
result.translatesAutoresizingMaskIntoConstraints = false
|
||||
result.isHidden = true
|
||||
|
||||
return result
|
||||
}()
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
setupViewHierarchy()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
|
||||
setupViewHierarchy()
|
||||
}
|
||||
|
||||
private func setupViewHierarchy() {
|
||||
themeBackgroundColor = .settings_tabBackground
|
||||
|
||||
// Highlight color
|
||||
let selectedBackgroundView = UIView()
|
||||
selectedBackgroundView.themeBackgroundColor = .settings_tabHighlight
|
||||
self.selectedBackgroundView = selectedBackgroundView
|
||||
|
||||
contentView.addSubview(topSeparator)
|
||||
contentView.addSubview(contentStackView)
|
||||
contentView.addSubview(botSeparator)
|
||||
|
||||
contentStackView.addArrangedSubview(titleStackView)
|
||||
contentStackView.addArrangedSubview(actionContainerView)
|
||||
|
||||
titleStackView.addArrangedSubview(titleLabel)
|
||||
titleStackView.addArrangedSubview(subtitleLabel)
|
||||
titleStackView.addArrangedSubview(extraActionButton)
|
||||
|
||||
actionContainerView.addSubview(pushChevronImageView)
|
||||
actionContainerView.addSubview(toggleSwitch)
|
||||
actionContainerView.addSubview(dropDownImageView)
|
||||
actionContainerView.addSubview(dropDownLabel)
|
||||
actionContainerView.addSubview(tickImageView)
|
||||
actionContainerView.addSubview(rightActionButtonContainerView)
|
||||
|
||||
rightActionButtonContainerView.addSubview(rightActionButtonLabel)
|
||||
|
||||
setupLayout()
|
||||
}
|
||||
|
||||
private func setupLayout() {
|
||||
topSeparator.pin(.top, to: .top, of: contentView)
|
||||
topSeparator.pin(.left, to: .left, of: contentView)
|
||||
topSeparator.pin(.right, to: .right, of: contentView)
|
||||
|
||||
contentStackView.pin(to: contentView)
|
||||
|
||||
pushChevronImageView.center(.vertical, in: actionContainerView)
|
||||
pushChevronImageView.pin(.right, to: .right, of: actionContainerView)
|
||||
|
||||
actionContainerView.widthAnchor
|
||||
.constraint(greaterThanOrEqualTo: toggleSwitch.widthAnchor)
|
||||
.isActive = true
|
||||
toggleSwitch.setCompressionResistanceHigh()
|
||||
toggleSwitch.center(.vertical, in: actionContainerView)
|
||||
toggleSwitch.pin(.right, to: .right, of: actionContainerView)
|
||||
|
||||
dropDownLabel.setCompressionResistanceHigh()
|
||||
dropDownLabel.center(.vertical, in: actionContainerView)
|
||||
dropDownLabel.pin(.right, to: .right, of: actionContainerView)
|
||||
|
||||
dropDownImageView.center(.vertical, in: actionContainerView)
|
||||
dropDownImageView.pin(.left, to: .left, of: actionContainerView)
|
||||
dropDownImageView.pin(.right, to: .left, of: dropDownLabel, withInset: -Values.verySmallSpacing)
|
||||
dropDownImageView.set(.width, to: 10)
|
||||
dropDownImageView.set(.height, to: 10)
|
||||
|
||||
tickImageView.center(.vertical, in: actionContainerView)
|
||||
tickImageView.pin(.right, to: .right, of: actionContainerView)
|
||||
|
||||
rightActionButtonContainerView.center(.vertical, in: actionContainerView)
|
||||
rightActionButtonContainerView.pin(.left, to: .left, of: actionContainerView)
|
||||
rightActionButtonContainerView.pin(.right, to: .right, of: actionContainerView)
|
||||
|
||||
rightActionButtonLabel.setCompressionResistanceHigh()
|
||||
rightActionButtonLabel.pin(to: rightActionButtonContainerView, withInset: Values.smallSpacing)
|
||||
|
||||
botSeparator.pin(.left, to: .left, of: contentView)
|
||||
botSeparator.pin(.right, to: .right, of: contentView)
|
||||
botSeparator.pin(.bottom, to: .bottom, of: contentView)
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
|
||||
self.instanceView = UIView()
|
||||
self.onExtraAction = nil
|
||||
|
||||
titleLabel.text = ""
|
||||
titleLabel.themeTextColor = .textPrimary
|
||||
subtitleLabel.text = ""
|
||||
dropDownLabel.text = ""
|
||||
|
||||
topSeparator.isHidden = true
|
||||
subtitleLabel.isHidden = true
|
||||
extraActionButton.isHidden = true
|
||||
actionContainerView.isHidden = true
|
||||
pushChevronImageView.isHidden = true
|
||||
toggleSwitch.isHidden = true
|
||||
dropDownImageView.isHidden = true
|
||||
dropDownLabel.isHidden = true
|
||||
tickImageView.isHidden = true
|
||||
tickImageView.alpha = 1
|
||||
rightActionButtonContainerView.isHidden = true
|
||||
botSeparator.isHidden = true
|
||||
}
|
||||
|
||||
public func update(
|
||||
title: String,
|
||||
subtitle: String?,
|
||||
action: SettingsAction,
|
||||
extraActionTitle: ((Theme, Theme.PrimaryColor) -> NSAttributedString)?,
|
||||
onExtraAction: (() -> Void)?,
|
||||
isFirstInSection: Bool,
|
||||
isLastInSection: Bool
|
||||
) {
|
||||
self.instanceView = UIView()
|
||||
self.onExtraAction = onExtraAction
|
||||
|
||||
// Left content
|
||||
titleLabel.text = title
|
||||
subtitleLabel.text = subtitle
|
||||
subtitleLabel.isHidden = (subtitle == nil)
|
||||
extraActionButton.isHidden = (extraActionTitle == nil)
|
||||
|
||||
// Separator Visibility
|
||||
switch action {
|
||||
case .dangerPush:
|
||||
topSeparator.isHidden = true
|
||||
botSeparator.isHidden = true
|
||||
|
||||
default:
|
||||
topSeparator.isHidden = isFirstInSection
|
||||
botSeparator.isHidden = !isLastInSection
|
||||
}
|
||||
|
||||
// Action Behaviours
|
||||
switch action {
|
||||
case .userDefaultsBool(let defaults, let key, _):
|
||||
actionContainerView.isHidden = false
|
||||
toggleSwitch.isHidden = false
|
||||
|
||||
let newValue: Bool = defaults.bool(forKey: key)
|
||||
|
||||
if newValue != toggleSwitch.isOn {
|
||||
toggleSwitch.setOn(newValue, animated: true)
|
||||
}
|
||||
|
||||
case .settingBool(let key):
|
||||
actionContainerView.isHidden = false
|
||||
toggleSwitch.isHidden = false
|
||||
|
||||
let newValue: Bool = Storage.shared[key]
|
||||
|
||||
if newValue != toggleSwitch.isOn {
|
||||
toggleSwitch.setOn(newValue, animated: true)
|
||||
}
|
||||
|
||||
case .settingEnum(_, let value, _):
|
||||
actionContainerView.isHidden = false
|
||||
dropDownImageView.isHidden = false
|
||||
dropDownLabel.isHidden = false
|
||||
dropDownLabel.text = value
|
||||
|
||||
case .listSelection(let isSelected, let storedSelection, _, _):
|
||||
actionContainerView.isHidden = false
|
||||
tickImageView.isHidden = (!isSelected() && !storedSelection)
|
||||
tickImageView.alpha = (!isSelected() && storedSelection ? 0.3 : 1)
|
||||
|
||||
case .trigger, .push:
|
||||
actionContainerView.isHidden = false
|
||||
pushChevronImageView.isHidden = false
|
||||
|
||||
case .dangerPush:
|
||||
titleLabel.themeTextColor = .danger
|
||||
actionContainerView.isHidden = false
|
||||
|
||||
case .rightButtonModal(let title, _):
|
||||
actionContainerView.isHidden = false
|
||||
rightActionButtonContainerView.isHidden = false
|
||||
rightActionButtonLabel.text = title
|
||||
}
|
||||
|
||||
// Extra action
|
||||
if let extraActionTitle: ((Theme, Theme.PrimaryColor) -> NSAttributedString) = extraActionTitle {
|
||||
ThemeManager.onThemeChange(observer: instanceView) { [weak extraActionButton] theme, primaryColor in
|
||||
extraActionButton?.setAttributedTitle(
|
||||
extraActionTitle(theme, primaryColor),
|
||||
for: .normal
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Interaction
|
||||
|
||||
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
|
||||
super.setHighlighted(highlighted, animated: animated)
|
||||
|
||||
// Note: Only setting the highlighted state is done here, the unhighlight is done
|
||||
// in 'setSelected'
|
||||
guard highlighted else { return }
|
||||
|
||||
rightActionButtonContainerView.themeBackgroundColor = .solidButton_highlight
|
||||
}
|
||||
|
||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||
super.setSelected(selected, animated: animated)
|
||||
|
||||
// Note: Only un-setting the unhighlighted state is done here, the highlighted state is done
|
||||
// in 'setHighlighted'
|
||||
guard !selected else { return }
|
||||
guard animated else {
|
||||
rightActionButtonContainerView.themeBackgroundColor = .solidButton_background
|
||||
return
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: 0.4) { [weak self] in
|
||||
self?.rightActionButtonContainerView.themeBackgroundColor = .solidButton_background
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func extraActionTapped() {
|
||||
onExtraAction?()
|
||||
}
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import SessionUtilitiesKit
|
||||
import AudioToolbox
|
||||
import GRDB
|
||||
import DifferenceKit
|
||||
import SessionUtilitiesKit
|
||||
|
||||
public extension Setting.EnumKey {
|
||||
/// Controls how notifications should appear for the user (See `NotificationPreviewType` for the options)
|
||||
|
@ -77,7 +78,7 @@ public extension Setting.DoubleKey {
|
|||
}
|
||||
|
||||
public enum Preferences {
|
||||
public enum NotificationPreviewType: Int, CaseIterable, EnumIntSetting {
|
||||
public enum NotificationPreviewType: Int, CaseIterable, EnumIntSetting, Differentiable {
|
||||
/// Notifications should include both the sender name and a preview of the message content
|
||||
case nameAndPreview
|
||||
|
||||
|
@ -87,7 +88,7 @@ public enum Preferences {
|
|||
/// Notifications should be a generic message
|
||||
case noNameNoPreview
|
||||
|
||||
var name: String {
|
||||
public var name: String {
|
||||
switch self {
|
||||
case .nameAndPreview: return "NOTIFICATIONS_SENDER_AND_MESSAGE".localized()
|
||||
case .nameNoPreview: return "NOTIFICATIONS_SENDER_ONLY".localized()
|
||||
|
@ -96,7 +97,7 @@ public enum Preferences {
|
|||
}
|
||||
}
|
||||
|
||||
public enum Sound: Int, Codable, DatabaseValueConvertible, EnumIntSetting {
|
||||
public enum Sound: Int, Codable, DatabaseValueConvertible, EnumIntSetting, Differentiable {
|
||||
public static var defaultiOSIncomingRingtone: Sound = .opening
|
||||
public static var defaultNotificationSound: Sound = .note
|
||||
|
||||
|
@ -157,7 +158,7 @@ public enum Preferences {
|
|||
]
|
||||
}
|
||||
|
||||
var displayName: String {
|
||||
public var displayName: String {
|
||||
// TODO: Should we localize these sound names?
|
||||
switch self {
|
||||
case .`default`: return ""
|
||||
|
@ -234,7 +235,7 @@ public enum Preferences {
|
|||
let url: URL = URL(fileURLWithPath: filename)
|
||||
|
||||
return Bundle.main.url(
|
||||
forResource: url.deletingPathExtension().absoluteString,
|
||||
forResource: url.deletingPathExtension().path,
|
||||
withExtension: url.pathExtension
|
||||
)
|
||||
}
|
||||
|
@ -306,50 +307,6 @@ public enum Preferences {
|
|||
|
||||
@objc(SMKPreferences)
|
||||
public class SMKPreferences: NSObject {
|
||||
@objc public static let notificationTypes: [Int] = Preferences.NotificationPreviewType
|
||||
.allCases
|
||||
.map { $0.rawValue }
|
||||
|
||||
@objc public static func nameForNotificationPreviewType(_ previewType: Int) -> String {
|
||||
return Preferences.NotificationPreviewType(rawValue: previewType)
|
||||
.defaulting(to: .nameAndPreview)
|
||||
.name
|
||||
}
|
||||
|
||||
@objc public static func notificationPreviewType() -> Int {
|
||||
return Storage.shared[.preferencesNotificationPreviewType]
|
||||
.defaulting(to: Preferences.NotificationPreviewType.nameAndPreview)
|
||||
.rawValue
|
||||
}
|
||||
|
||||
@objc public static func setNotificationPreviewType(_ previewType: Int) {
|
||||
Storage.shared.write { db in
|
||||
db[.preferencesNotificationPreviewType] = Preferences.NotificationPreviewType(rawValue: previewType)
|
||||
.defaulting(to: .nameAndPreview)
|
||||
}
|
||||
}
|
||||
|
||||
@objc public static func accessibilityIdentifierForNotificationPreviewType(_ previewType: Int) -> String {
|
||||
let notificationPreviewType: Preferences.NotificationPreviewType = Preferences.NotificationPreviewType(rawValue: previewType)
|
||||
.defaulting(to: .nameAndPreview)
|
||||
|
||||
switch notificationPreviewType {
|
||||
case .nameAndPreview: return "NotificationNamePreview"
|
||||
case .nameNoPreview: return "NotificationNameNoPreview"
|
||||
case .noNameNoPreview: return "NotificationNoNameNoPreview"
|
||||
}
|
||||
}
|
||||
|
||||
@objc(setPlayNotificationSoundInForeground:)
|
||||
static func objc_setPlayNotificationSoundInForeground(_ enabled: Bool) {
|
||||
Storage.shared.write { db in db[.playNotificationSoundInForeground] = enabled }
|
||||
}
|
||||
|
||||
@objc(playNotificationSoundInForeground)
|
||||
static func objc_playNotificationSoundInForeground() -> Bool {
|
||||
return Storage.shared[.playNotificationSoundInForeground]
|
||||
}
|
||||
|
||||
@objc(setScreenSecurity:)
|
||||
static func objc_setScreenSecurity(_ enabled: Bool) {
|
||||
Storage.shared.write { db in db[.appSwitcherPreviewEnabled] = enabled }
|
||||
|
|
|
@ -8,6 +8,7 @@ internal enum Theme_ClassicDark: ThemeColors {
|
|||
.primary: .primary,
|
||||
.defaultPrimary: Theme.PrimaryColor.green.color,
|
||||
.danger: #colorLiteral(red: 1, green: 0.2274509804, blue: 0.2274509804, alpha: 1),
|
||||
.white: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
|
||||
.clear: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0),
|
||||
.backgroundPrimary: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
|
||||
.backgroundSecondary: #colorLiteral(red: 0.1058823529, green: 0.1058823529, blue: 0.1058823529, alpha: 1),
|
||||
|
@ -51,6 +52,10 @@ internal enum Theme_ClassicDark: ThemeColors {
|
|||
.outlineButton_destructiveHighlight: #colorLiteral(red: 1, green: 0.2274509804, blue: 0.2274509804, alpha: 0.3),
|
||||
.outlineButton_destructiveBorder: #colorLiteral(red: 1, green: 0.2274509804, blue: 0.2274509804, alpha: 1),
|
||||
|
||||
// SolidButton
|
||||
.solidButton_background: #colorLiteral(red: 0.1764705882, green: 0.1764705882, blue: 0.1764705882, alpha: 1),
|
||||
.solidButton_highlight: #colorLiteral(red: 0.3254901961, green: 0.3254901961, blue: 0.3254901961, alpha: 1),
|
||||
|
||||
// Settings
|
||||
.settings_tabBackground: #colorLiteral(red: 0.1058823529, green: 0.1058823529, blue: 0.1058823529, alpha: 1),
|
||||
.settings_tabHighlight: #colorLiteral(red: 0.2549019608, green: 0.2549019608, blue: 0.2549019608, alpha: 1),
|
||||
|
|
|
@ -8,6 +8,7 @@ internal enum Theme_ClassicLight: ThemeColors {
|
|||
.primary: .primary,
|
||||
.defaultPrimary: Theme.PrimaryColor.green.color,
|
||||
.danger: #colorLiteral(red: 0.8823529412, green: 0.1764705882, blue: 0.09803921569, alpha: 1),
|
||||
.white: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
|
||||
.clear: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0),
|
||||
.backgroundPrimary: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
|
||||
.backgroundSecondary: #colorLiteral(red: 0.9764705882, green: 0.9764705882, blue: 0.9764705882, alpha: 1),
|
||||
|
@ -51,6 +52,10 @@ internal enum Theme_ClassicLight: ThemeColors {
|
|||
.outlineButton_destructiveHighlight: #colorLiteral(red: 0.8823529412, green: 0.1764705882, blue: 0.09803921569, alpha: 0.3),
|
||||
.outlineButton_destructiveBorder: #colorLiteral(red: 0.8823529412, green: 0.1764705882, blue: 0.09803921569, alpha: 1),
|
||||
|
||||
// SolidButton
|
||||
.solidButton_background: #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9411764706, alpha: 1),
|
||||
.solidButton_highlight: #colorLiteral(red: 0.8156862745, green: 0.8156862745, blue: 0.8156862745, alpha: 1),
|
||||
|
||||
// Settings
|
||||
.settings_tabBackground: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
|
||||
.settings_tabHighlight: #colorLiteral(red: 0.8745098039, green: 0.8745098039, blue: 0.8745098039, alpha: 1),
|
||||
|
|
|
@ -8,6 +8,7 @@ internal enum Theme_OceanDark: ThemeColors {
|
|||
.primary: .primary,
|
||||
.defaultPrimary: Theme.PrimaryColor.blue.color,
|
||||
.danger: #colorLiteral(red: 1, green: 0.2274509804, blue: 0.2274509804, alpha: 1),
|
||||
.white: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
|
||||
.clear: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0),
|
||||
.backgroundPrimary: #colorLiteral(red: 0.1450980392, green: 0.1529411765, blue: 0.2078431373, alpha: 1),
|
||||
.backgroundSecondary: #colorLiteral(red: 0.1019607843, green: 0.1098039216, blue: 0.1568627451, alpha: 1),
|
||||
|
@ -51,6 +52,10 @@ internal enum Theme_OceanDark: ThemeColors {
|
|||
.outlineButton_destructiveHighlight: #colorLiteral(red: 1, green: 0.2274509804, blue: 0.2274509804, alpha: 0.3),
|
||||
.outlineButton_destructiveBorder: #colorLiteral(red: 1, green: 0.2274509804, blue: 0.2274509804, alpha: 1),
|
||||
|
||||
// SolidButton
|
||||
.solidButton_background: #colorLiteral(red: 0.1450980392, green: 0.1529411765, blue: 0.2078431373, alpha: 1),
|
||||
.solidButton_highlight: #colorLiteral(red: 0.2117647059, green: 0.2196078431, blue: 0.3019607844, alpha: 1),
|
||||
|
||||
// Settings
|
||||
.settings_tabBackground: #colorLiteral(red: 0.1019607843, green: 0.1098039216, blue: 0.1568627451, alpha: 1),
|
||||
.settings_tabHighlight: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1),
|
||||
|
@ -66,8 +71,8 @@ internal enum Theme_OceanDark: ThemeColors {
|
|||
.conversationButton_unreadBackground: #colorLiteral(red: 0.1450980392, green: 0.1529411765, blue: 0.2078431373, alpha: 1),
|
||||
.conversationButton_unreadHighlight: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1),
|
||||
.conversationButton_unreadStripBackground: .primary,
|
||||
.conversationButton_unreadBubbleBackground: Theme.PrimaryColor.blue.color,
|
||||
.conversationButton_unreadBubbleText: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
|
||||
.conversationButton_unreadBubbleBackground: .primary,
|
||||
.conversationButton_unreadBubbleText: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
|
||||
.conversationButton_pinBackground: Theme.PrimaryColor.yellow.color
|
||||
]
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ internal enum Theme_OceanLight: ThemeColors {
|
|||
.primary: .primary,
|
||||
.defaultPrimary: Theme.PrimaryColor.blue.color,
|
||||
.danger: #colorLiteral(red: 0.8823529412, green: 0.1764705882, blue: 0.09803921569, alpha: 1),
|
||||
.white: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
|
||||
.clear: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0),
|
||||
.backgroundPrimary: #colorLiteral(red: 0.9882352941, green: 1, blue: 1, alpha: 1),
|
||||
.backgroundSecondary: #colorLiteral(red: 0.9254901961, green: 0.9803921569, blue: 0.9843137255, alpha: 1),
|
||||
|
@ -51,6 +52,10 @@ internal enum Theme_OceanLight: ThemeColors {
|
|||
.outlineButton_destructiveHighlight: #colorLiteral(red: 0.8823529412, green: 0.1764705882, blue: 0.09803921569, alpha: 0.3),
|
||||
.outlineButton_destructiveBorder: #colorLiteral(red: 0.8823529412, green: 0.1764705882, blue: 0.09803921569, alpha: 1),
|
||||
|
||||
// SolidButton
|
||||
.solidButton_background: #colorLiteral(red: 0.9254901961, green: 0.9803921569, blue: 0.9843137255, alpha: 1),
|
||||
.solidButton_highlight: #colorLiteral(red: 0.8431372549, green: 0.9333333334, blue: 0.9411764706, alpha: 1),
|
||||
|
||||
// Settings
|
||||
.settings_tabBackground: #colorLiteral(red: 0.9882352941, green: 1, blue: 1, alpha: 1),
|
||||
.settings_tabHighlight: #colorLiteral(red: 0.9058823529, green: 0.9529411765, blue: 0.9568627451, alpha: 1),
|
||||
|
|
|
@ -4,7 +4,7 @@ import UIKit.UIColor
|
|||
import SessionUtilitiesKit
|
||||
|
||||
public extension Theme {
|
||||
public enum PrimaryColor: String, Codable, CaseIterable, EnumStringSetting {
|
||||
enum PrimaryColor: String, Codable, CaseIterable, EnumStringSetting {
|
||||
case green
|
||||
case blue
|
||||
case purple
|
||||
|
@ -24,7 +24,7 @@ public extension Theme {
|
|||
|
||||
public var color: UIColor {
|
||||
switch self {
|
||||
case .green: return #colorLiteral(red: 0.1882352941, green: 0.9411764706, blue: 0.6549019608, alpha: 1)
|
||||
case .green: return #colorLiteral(red: 0.1921568627, green: 0.9450980392, blue: 0.5882352941, alpha: 1)
|
||||
case .blue: return #colorLiteral(red: 0.3411764706, green: 0.7882352941, blue: 0.9803921569, alpha: 1)
|
||||
case .purple: return #colorLiteral(red: 0.7882352941, green: 0.5764705882, blue: 1, alpha: 1)
|
||||
case .pink: return #colorLiteral(red: 1, green: 0.5843137255, blue: 0.937254902, alpha: 1)
|
||||
|
|
|
@ -59,6 +59,7 @@ public enum ThemeValue {
|
|||
case primary
|
||||
case defaultPrimary
|
||||
case danger
|
||||
case white
|
||||
case clear
|
||||
case backgroundPrimary
|
||||
case backgroundSecondary
|
||||
|
@ -102,6 +103,10 @@ public enum ThemeValue {
|
|||
case outlineButton_destructiveHighlight
|
||||
case outlineButton_destructiveBorder
|
||||
|
||||
// SolidButton
|
||||
case solidButton_background
|
||||
case solidButton_highlight
|
||||
|
||||
// Settings
|
||||
case settings_tabBackground
|
||||
case settings_tabHighlight
|
||||
|
|
|
@ -83,7 +83,7 @@ extension Setting {
|
|||
// MARK: - Keys
|
||||
|
||||
public extension Setting {
|
||||
struct BoolKey: RawRepresentable, ExpressibleByStringLiteral {
|
||||
struct BoolKey: RawRepresentable, ExpressibleByStringLiteral, Hashable {
|
||||
public let rawValue: String
|
||||
|
||||
public init(_ rawValue: String) { self.rawValue = rawValue }
|
||||
|
@ -93,7 +93,7 @@ public extension Setting {
|
|||
public init(extendedGraphemeClusterLiteral value: String) { self.init(value) }
|
||||
}
|
||||
|
||||
struct DateKey: RawRepresentable, ExpressibleByStringLiteral {
|
||||
struct DateKey: RawRepresentable, ExpressibleByStringLiteral, Hashable {
|
||||
public let rawValue: String
|
||||
|
||||
public init(_ rawValue: String) { self.rawValue = rawValue }
|
||||
|
@ -103,7 +103,7 @@ public extension Setting {
|
|||
public init(extendedGraphemeClusterLiteral value: String) { self.init(value) }
|
||||
}
|
||||
|
||||
struct DoubleKey: RawRepresentable, ExpressibleByStringLiteral {
|
||||
struct DoubleKey: RawRepresentable, ExpressibleByStringLiteral, Hashable {
|
||||
public let rawValue: String
|
||||
|
||||
public init(_ rawValue: String) { self.rawValue = rawValue }
|
||||
|
@ -113,7 +113,7 @@ public extension Setting {
|
|||
public init(extendedGraphemeClusterLiteral value: String) { self.init(value) }
|
||||
}
|
||||
|
||||
struct IntKey: RawRepresentable, ExpressibleByStringLiteral {
|
||||
struct IntKey: RawRepresentable, ExpressibleByStringLiteral, Hashable {
|
||||
public let rawValue: String
|
||||
|
||||
public init(_ rawValue: String) { self.rawValue = rawValue }
|
||||
|
@ -123,7 +123,7 @@ public extension Setting {
|
|||
public init(extendedGraphemeClusterLiteral value: String) { self.init(value) }
|
||||
}
|
||||
|
||||
struct StringKey: RawRepresentable, ExpressibleByStringLiteral {
|
||||
struct StringKey: RawRepresentable, ExpressibleByStringLiteral, Hashable {
|
||||
public let rawValue: String
|
||||
|
||||
public init(_ rawValue: String) { self.rawValue = rawValue }
|
||||
|
@ -133,7 +133,7 @@ public extension Setting {
|
|||
public init(extendedGraphemeClusterLiteral value: String) { self.init(value) }
|
||||
}
|
||||
|
||||
struct EnumKey: RawRepresentable, ExpressibleByStringLiteral {
|
||||
struct EnumKey: RawRepresentable, ExpressibleByStringLiteral, Hashable {
|
||||
public let rawValue: String
|
||||
|
||||
public init(_ rawValue: String) { self.rawValue = rawValue }
|
||||
|
|
Loading…
Reference in New Issue