From ea32e407a91cbe892aba4e7ddbe4d2a986b5a758 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Fri, 12 Aug 2022 17:28:00 +1000 Subject: [PATCH] Applied theming to a number of screens, some minor cleanup and bug fixes Updated the HomeVC, SettingsVC and GlobalSearch UI to use theming Removed the "fade view" gradients from the various screens Added a simple log to the PagedDatabaseObserver to make debugging easier Updated the FullConversationCell to also show the "read" state for messages Updated the read receipt icons to use SFSymbols directly Updated the PlaceholderIcon to use the PrimaryColour's as it's colour options --- Session.xcodeproj/project.pbxproj | 86 ++++-- Session/Closed Groups/EditClosedGroupVC.swift | 2 - Session/Closed Groups/NewClosedGroupVC.swift | 3 - Session/Conversations/ConversationVC.swift | 5 - .../Content Views/QuoteView.swift | 52 ++-- .../Message Cells/VisibleMessageCell.swift | 38 +-- .../Settings/ProfilePictureVC.swift | 4 +- Session/DMs/NewDMVC.swift | 5 +- .../GlobalSearch/EmptySearchResultCell.swift | 12 +- .../GlobalSearchViewController.swift | 23 +- Session/Home/HomeVC.swift | 58 ++-- .../MessageRequestsViewController.swift | 25 +- .../Views/MessageRequestsCell.swift | 19 +- Session/Home/NewConversationButtonSet.swift | 181 ++++++++++--- Session/Meta/AppDelegate.swift | 3 - .../CircleDotDotDot.pdf | Bin 171587 -> 0 bytes .../CircleDotDotDot.imageset/Contents.json | 12 - .../Contents.json | 12 - .../FilledCircleCheckDarkMode.pdf | Bin 6359 -> 0 bytes .../Contents.json | 12 - .../FilledCircleCheckLightMode.pdf | Bin 6861 -> 0 bytes .../Contents.json | 23 -- .../error-12@1x.png | Bin 220 -> 0 bytes .../error-12@2x.png | Bin 423 -> 0 bytes .../error-12@3x.png | Bin 701 -> 0 bytes .../Translations/en.lproj/Localizable.strings | 2 +- .../Translations/es.lproj/Localizable.strings | 2 +- .../Translations/fa.lproj/Localizable.strings | 2 +- .../Translations/hi.lproj/Localizable.strings | 2 +- .../Translations/hr.lproj/Localizable.strings | 2 +- .../id-ID.lproj/Localizable.strings | 2 +- .../Translations/nl.lproj/Localizable.strings | 2 +- .../pt_BR.lproj/Localizable.strings | 2 +- .../Translations/si.lproj/Localizable.strings | 2 +- .../Translations/sv.lproj/Localizable.strings | 2 +- .../Translations/th.lproj/Localizable.strings | 2 +- .../vi-VN.lproj/Localizable.strings | 2 +- .../zh-Hant.lproj/Localizable.strings | 2 +- Session/Notifications/AppNotifications.swift | 2 +- Session/Onboarding/DisplayNameVC.swift | 2 - Session/Onboarding/FakeChatView.swift | 43 ++- Session/Onboarding/LandingVC.swift | 6 +- Session/Onboarding/LinkDeviceVC.swift | 5 +- Session/Onboarding/PNModeVC.swift | 2 - Session/Onboarding/RegisterVC.swift | 2 - Session/Onboarding/RestoreVC.swift | 2 - Session/Onboarding/SeedReminderView.swift | 15 +- Session/Onboarding/SeedVC.swift | 2 - Session/Open Groups/JoinOpenGroupVC.swift | 2 - Session/Path/PathVC.swift | 2 - Session/Settings/QRCodeVC.swift | 2 - Session/Settings/SettingsVC.swift | 2 - Session/Shared/BaseVC.swift | 62 ----- Session/Shared/FullConversationCell.swift | 250 ++++++++++-------- Session/Shared/LoadingViewController.swift | 12 +- Session/Shared/ScanQRCodeWrapperVC.swift | 2 +- Session/Shared/UserSelectionVC.swift | 4 +- Session/Utilities/MentionUtilities.swift | 30 ++- .../Database/Models/RecipientState.swift | 14 + .../SessionThreadViewModel.swift | 14 +- SessionShareExtension/ShareVC.swift | 13 +- SessionShareExtension/ThreadPickerVC.swift | 35 +-- .../Migrations/_001_ThemePreferences.swift | 14 +- SessionUIKit/Style Guide/ThemeManager.swift | 231 ++++------------ .../Themes/Theme+ClassicDark.swift | 12 +- .../Themes/Theme+ClassicLight.swift | 12 +- .../Style Guide/Themes/Theme+OceanDark.swift | 16 +- .../Style Guide/Themes/Theme+OceanLight.swift | 12 +- SessionUIKit/Style Guide/Themes/Theme.swift | 10 +- .../Style Guide/Themes/UIKit+Theme.swift | 155 +++++++++++ .../Types/PagedDatabaseObserver.swift | 10 +- .../Profile Pictures/Identicon+ObjC.swift | 1 + .../Profile Pictures/PlaceholderIcon.swift | 12 +- .../Profile Pictures/ProfilePictureView.swift | 11 +- 74 files changed, 839 insertions(+), 783 deletions(-) delete mode 100644 Session/Meta/Images.xcassets/Session/CircleDotDotDot.imageset/CircleDotDotDot.pdf delete mode 100644 Session/Meta/Images.xcassets/Session/CircleDotDotDot.imageset/Contents.json delete mode 100644 Session/Meta/Images.xcassets/Session/FilledCircleCheckDarkMode.imageset/Contents.json delete mode 100644 Session/Meta/Images.xcassets/Session/FilledCircleCheckDarkMode.imageset/FilledCircleCheckDarkMode.pdf delete mode 100644 Session/Meta/Images.xcassets/Session/FilledCircleCheckLightMode.imageset/Contents.json delete mode 100644 Session/Meta/Images.xcassets/Session/FilledCircleCheckLightMode.imageset/FilledCircleCheckLightMode.pdf delete mode 100644 Session/Meta/Images.xcassets/message_status_failed.imageset/Contents.json delete mode 100644 Session/Meta/Images.xcassets/message_status_failed.imageset/error-12@1x.png delete mode 100644 Session/Meta/Images.xcassets/message_status_failed.imageset/error-12@2x.png delete mode 100644 Session/Meta/Images.xcassets/message_status_failed.imageset/error-12@3x.png create mode 100644 SessionUIKit/Style Guide/Themes/UIKit+Theme.swift diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 717fa452f..400a30928 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -107,7 +107,6 @@ 4CA485BB2232339F004B9E7D /* PhotoCaptureViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */; }; 4CC613362227A00400E21A3A /* ConversationSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC613352227A00400E21A3A /* ConversationSearch.swift */; }; 5163CBC4F53274C88D1F88F8 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 782B65234A707D762FEAFD3B /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit.framework */; }; - 63A15A5E6605581543B4A5B4 /* Pods_SessionUIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DEB8C073F5E3C418BFB96C3 /* Pods_SessionUIKit.framework */; }; 70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70377AAA1918450100CAF501 /* MobileCoreServices.framework */; }; 71B1D8AF3ADE2BD191256496 /* Pods_GlobalDependencies_Session.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48AD214D67ABED845101E795 /* Pods_GlobalDependencies_Session.framework */; }; 768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; }; @@ -158,6 +157,7 @@ 7BFD1A8C2747150E00FB91B9 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFD1A8B2747150E00FB91B9 /* TurnServerInfo.swift */; }; 7BFD1A972747689000FB91B9 /* Session-Turn-Server in Resources */ = {isa = PBXBuildFile; fileRef = 7BFD1A962747689000FB91B9 /* Session-Turn-Server */; }; 7BFFB33C27D02F5800BEA04E /* CallPermissionRequestModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFFB33B27D02F5800BEA04E /* CallPermissionRequestModal.swift */; }; + 821EFD1644285AC2D3733D27 /* Pods_GlobalDependencies_SessionUIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9C58C3ADF46C718488458C2 /* Pods_GlobalDependencies_SessionUIKit.framework */; }; 92EB2776D36B22D2E0552A05 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionMessagingKit_SessionMessagingKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2691123A7F231EDD8226C4B5 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionMessagingKit_SessionMessagingKitTests.framework */; }; 98547545DAF8E7916DF9F0BF /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionNotificationServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F84A214B9A1C0CCF6DB09C8 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionNotificationServiceExtension.framework */; }; A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; }; @@ -521,7 +521,6 @@ C3D0972B2510499C00F6E3E4 /* BackgroundPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D0972A2510499C00F6E3E4 /* BackgroundPoller.swift */; }; C3D90A1125773888002C9DF5 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; }; C3D90A5C25773A25002C9DF5 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; }; - C3D90A7A25773A93002C9DF5 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A5EB255C970D007BE2A3 /* Configuration.swift */; }; C3D9E35525675EE10040E4F3 /* MIMETypeUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB41255A580C00E217F9 /* MIMETypeUtil.m */; }; C3D9E35E25675F640040E4F3 /* OWSFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA8E255A57FD00E217F9 /* OWSFileSystem.m */; }; C3D9E379256760340040E4F3 /* MIMETypeUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAFC255A580600E217F9 /* MIMETypeUtil.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -530,7 +529,6 @@ C3D9E3A4256763DE0040E4F3 /* AppContext.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB8A255A581200E217F9 /* AppContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; C3D9E3BE25676AD70040E4F3 /* (null) in Sources */ = {isa = PBXBuildFile; }; C3D9E3BF25676AD70040E4F3 /* (null) in Sources */ = {isa = PBXBuildFile; }; - C3D9E43125676D3D0040E4F3 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D9E43025676D3D0040E4F3 /* Configuration.swift */; }; C3D9E4C02567767F0040E4F3 /* DataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBB6255A581600E217F9 /* DataSource.m */; }; C3D9E4D12567777D0040E4F3 /* OWSMediaUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB22255A580900E217F9 /* OWSMediaUtils.swift */; }; C3D9E4DA256778410040E4F3 /* UIImage+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB81255A581100E217F9 /* UIImage+OWS.m */; }; @@ -656,6 +654,12 @@ FD37E9D928A230F2003AE748 /* TraitObservingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37E9D828A230F2003AE748 /* TraitObservingWindow.swift */; }; FD37E9DB28A244E9003AE748 /* ThemePreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37E9DA28A244E9003AE748 /* ThemePreviewView.swift */; }; FD37E9DD28A384EB003AE748 /* PrimaryColorSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37E9DC28A384EB003AE748 /* PrimaryColorSelectionView.swift */; }; + FD37E9EF28A5ED70003AE748 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; platformFilter = ios; }; + FD37E9F628A5F106003AE748 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37E9F528A5F106003AE748 /* Configuration.swift */; }; + FD37E9F928A5F14A003AE748 /* _001_ThemePreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD37E9F828A5F14A003AE748 /* _001_ThemePreferences.swift */; }; + 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 */; }; 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 */; }; @@ -942,6 +946,13 @@ remoteGlobalIDString = C33FD9AA255A548A00E217F9; remoteInfo = SignalUtilitiesKit; }; + FD37E9F128A5ED70003AE748 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D221A080169C9E5E00537ABF /* Project object */; + proxyType = 1; + remoteGlobalIDString = C3C2A678255388CC00C340D1; + remoteInfo = SessionUtilitiesKit; + }; FD83B9B427CF200A005E1583 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D221A080169C9E5E00537ABF /* Project object */; @@ -1005,6 +1016,7 @@ /* Begin PBXFileReference section */ 0BF4561630A52BE96F164CF6 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SignalUtilitiesKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SignalUtilitiesKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0E836037CC97CE5A47735596 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionSnodeKit.app store release.xcconfig"; sourceTree = ""; }; + 18EAE958B8C12503F2C294DF /* Pods-GlobalDependencies-SessionUIKit.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-SessionUIKit.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-SessionUIKit/Pods-GlobalDependencies-SessionUIKit.app store release.xcconfig"; sourceTree = ""; }; 1A0882BF820F5B44969F91F1 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.debug.xcconfig"; sourceTree = ""; }; 245BF74EF6348E2D4125033F /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-SessionNotificationServiceExtension.app store release.xcconfig"; sourceTree = ""; }; 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 = ""; }; @@ -1128,11 +1140,11 @@ 4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoCaptureViewController.swift; sourceTree = ""; }; 4CC613352227A00400E21A3A /* ConversationSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearch.swift; sourceTree = ""; }; 506FA2159653FF9F446D97D1 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit.debug.xcconfig"; sourceTree = ""; }; + 510955DC99A0FD84F2D1C159 /* Pods-GlobalDependencies-SessionUIKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-SessionUIKit.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-SessionUIKit/Pods-GlobalDependencies-SessionUIKit.debug.xcconfig"; sourceTree = ""; }; 5442DF945D862CEDF7F8AC49 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit_SessionUtilitiesKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_ExtendedDependencies_SessionUtilitiesKit_SessionUtilitiesKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5626DC0D5F62C1C2C64E4AFC /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionShareExtension.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionShareExtension.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionShareExtension/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionShareExtension.app store release.xcconfig"; sourceTree = ""; }; 56F41C56FC7B2F381E440FB0 /* Pods-GlobalDependencies-Session.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-Session.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-Session/Pods-GlobalDependencies-Session.debug.xcconfig"; sourceTree = ""; }; 58A6BA91F634756FA0BEC9E5 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit-SessionUtilitiesKitTests.app store release.xcconfig"; sourceTree = ""; }; - 5DEB8C073F5E3C418BFB96C3 /* Pods_SessionUIKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SessionUIKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6737124ECBC2DFEE2DD716D3 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionSnodeKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionSnodeKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6BE8FBF62464A7177034A0AB /* Pods-GlobalDependencies-Session.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-Session.app store release.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-Session/Pods-GlobalDependencies-Session.app store release.xcconfig"; sourceTree = ""; }; 6F84A214B9A1C0CCF6DB09C8 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionNotificationServiceExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionNotificationServiceExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1198,6 +1210,7 @@ A1C32D4D17A0652C000A904E /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; A1C32D4F17A06537000A904E /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; A1FDCBEE16DAA6C300868894 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + A9C58C3ADF46C718488458C2 /* Pods_GlobalDependencies_SessionUIKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GlobalDependencies_SessionUIKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B60EDE031A05A01700D73516 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; B646D10E1AA5461A004133BA /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; B657DDC91911A40500F45B0C /* Signal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Signal.entitlements; sourceTree = ""; }; @@ -1608,7 +1621,6 @@ C3ECBF7A257056B700EA7FCE /* Threading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Threading.swift; sourceTree = ""; }; C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoopNotificationsManager.swift; sourceTree = ""; }; C3F0A5B2255C915C007BE2A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - C3F0A5EB255C970D007BE2A3 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; D0CE0424239A1574F683D2D7 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests.debug.xcconfig"; path = "Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionMessagingKit-SessionMessagingKitTests.debug.xcconfig"; sourceTree = ""; }; D2179CFB16BB0B3A0006F3AB /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; D2179CFD16BB0B480006F3AB /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; @@ -1707,6 +1719,10 @@ FD37E9D828A230F2003AE748 /* TraitObservingWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraitObservingWindow.swift; sourceTree = ""; }; FD37E9DA28A244E9003AE748 /* ThemePreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemePreviewView.swift; sourceTree = ""; }; FD37E9DC28A384EB003AE748 /* PrimaryColorSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryColorSelectionView.swift; sourceTree = ""; }; + FD37E9F528A5F106003AE748 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; + FD37E9F828A5F14A003AE748 /* _001_ThemePreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _001_ThemePreferences.swift; sourceTree = ""; }; + FD37E9FE28A5F2CD003AE748 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; + FD37EA0028A60473003AE748 /* UIKit+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+Theme.swift"; sourceTree = ""; }; FD3AABE828306BBD00E5099A /* ThreadPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadPickerViewModel.swift; sourceTree = ""; }; FD3C905B27E3FBEF00CD579F /* BatchRequestInfoSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchRequestInfoSpec.swift; sourceTree = ""; }; FD3C905F27E410F700CD579F /* FileUploadResponseSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUploadResponseSpec.swift; sourceTree = ""; }; @@ -1902,7 +1918,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 63A15A5E6605581543B4A5B4 /* Pods_SessionUIKit.framework in Frameworks */, + FD37E9EF28A5ED70003AE748 /* SessionUtilitiesKit.framework in Frameworks */, + 821EFD1644285AC2D3733D27 /* Pods_GlobalDependencies_SessionUIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2028,6 +2045,8 @@ 6BE8FBF62464A7177034A0AB /* Pods-GlobalDependencies-Session.app store release.xcconfig */, EC5C23F9D234F558BE5E41DE /* Pods-SessionUIKit.debug.xcconfig */, 29CF8C79F41BF00B1C2E59A0 /* Pods-SessionUIKit.app store release.xcconfig */, + 510955DC99A0FD84F2D1C159 /* Pods-GlobalDependencies-SessionUIKit.debug.xcconfig */, + 18EAE958B8C12503F2C294DF /* Pods-GlobalDependencies-SessionUIKit.app store release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -2677,9 +2696,11 @@ isa = PBXGroup; children = ( C331FF422558F9E400070591 /* Meta */, + FD37E9F428A5F0FB003AE748 /* Database */, C331FFCC2558FAF300070591 /* Components */, C331FF5E2558FA0F00070591 /* Style Guide */, C331FFAE2558FA7700070591 /* Utilities */, + FD37E9F528A5F106003AE748 /* Configuration.swift */, ); path = SessionUIKit; sourceTree = ""; @@ -2738,7 +2759,6 @@ isa = PBXGroup; children = ( C33FD9B7255A54A300E217F9 /* Meta */, - C3F0A5EB255C970D007BE2A3 /* Configuration.swift */, C36096ED25AD20FD008B62B2 /* Media Viewing & Editing */, C38BBA0D255E321C0041B9A3 /* Messaging */, C36096EF25AD2268008B62B2 /* Profile Pictures */, @@ -2746,6 +2766,7 @@ C3851CD225624B060061EEB0 /* Shared Views */, C360970125AD22D3008B62B2 /* Shared View Controllers */, C3CA3B11255CF17200F4C6D4 /* Utilities */, + C3D9E43025676D3D0040E4F3 /* Configuration.swift */, ); path = SignalUtilitiesKit; sourceTree = ""; @@ -3147,8 +3168,7 @@ B8A582AE258C65D000AFD84C /* Networking */, B8A582AD258C655E00AFD84C /* PromiseKit */, FD09796527F6B0A800936362 /* Utilities */, - FDCDB8EF2817ABCE00352A0C /* Utilities */, - C3D9E43025676D3D0040E4F3 /* Configuration.swift */, + FD37E9FE28A5F2CD003AE748 /* Configuration.swift */, ); path = SessionUtilitiesKit; sourceTree = ""; @@ -3411,7 +3431,7 @@ 6F84A214B9A1C0CCF6DB09C8 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionNotificationServiceExtension.framework */, 6737124ECBC2DFEE2DD716D3 /* Pods_GlobalDependencies_FrameworkAndExtensionDependencies_SessionSnodeKit.framework */, 48AD214D67ABED845101E795 /* Pods_GlobalDependencies_Session.framework */, - 5DEB8C073F5E3C418BFB96C3 /* Pods_SessionUIKit.framework */, + A9C58C3ADF46C718488458C2 /* Pods_GlobalDependencies_SessionUIKit.framework */, ); name = Frameworks; sourceTree = ""; @@ -3447,6 +3467,7 @@ FD09797127FAA2F500936362 /* Optional+Utilities.swift */, FD09797C27FBDB2000936362 /* Notification+Utilities.swift */, FDF222082818D2B0000A4995 /* NSAttributedString+Utilities.swift */, + FDCDB8F02817ABE600352A0C /* Optional+Utilities.swift */, ); path = Utilities; sourceTree = ""; @@ -3605,6 +3626,7 @@ FD37E9C928A1E4BD003AE748 /* Theme+ClassicLight.swift */, FD37E9D228A1FCDB003AE748 /* Theme+OceanDark.swift */, FD37E9D428A1FCE8003AE748 /* Theme+OceanLight.swift */, + FD37EA0028A60473003AE748 /* UIKit+Theme.swift */, ); path = Themes; sourceTree = ""; @@ -3619,6 +3641,22 @@ path = Views; sourceTree = ""; }; + FD37E9F428A5F0FB003AE748 /* Database */ = { + isa = PBXGroup; + children = ( + FD37E9F728A5F143003AE748 /* Migrations */, + ); + path = Database; + sourceTree = ""; + }; + FD37E9F728A5F143003AE748 /* Migrations */ = { + isa = PBXGroup; + children = ( + FD37E9F828A5F14A003AE748 /* _001_ThemePreferences.swift */, + ); + path = Migrations; + sourceTree = ""; + }; FD3C905D27E410DB00CD579F /* Common Networking */ = { isa = PBXGroup; children = ( @@ -3908,14 +3946,6 @@ path = Models; sourceTree = ""; }; - FDCDB8EF2817ABCE00352A0C /* Utilities */ = { - isa = PBXGroup; - children = ( - FDCDB8F02817ABE600352A0C /* Optional+Utilities.swift */, - ); - path = Utilities; - sourceTree = ""; - }; FDE7214E287E50D50093DF33 /* Scripts */ = { isa = PBXGroup; children = ( @@ -4107,6 +4137,7 @@ buildRules = ( ); dependencies = ( + FD37E9F228A5ED70003AE748 /* PBXTargetDependency */, ); name = SessionUIKit; productName = SessionUIKit; @@ -4633,7 +4664,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-SessionUIKit-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-GlobalDependencies-SessionUIKit-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -4880,13 +4911,16 @@ C331FFE32558FB0000070591 /* TabBar.swift in Sources */, FD37E9D528A1FCE8003AE748 /* Theme+OceanLight.swift in Sources */, FD37E9C828A1D73F003AE748 /* Theme+PrimaryColors.swift in Sources */, + FD37EA0128A60473003AE748 /* UIKit+Theme.swift in Sources */, FD37E9CF28A1EB1B003AE748 /* Theme.swift in Sources */, C331FFB92558FA8D00070591 /* UIView+Constraints.swift in Sources */, C331FF962558FA6B00070591 /* Colors.swift in Sources */, + FD37E9F628A5F106003AE748 /* Configuration.swift in Sources */, C331FFE02558FB0000070591 /* SearchBar.swift in Sources */, C331FF982558FA6B00070591 /* AppMode.swift in Sources */, C331FFE82558FB0000070591 /* TextView.swift in Sources */, FD37E9D728A20B5D003AE748 /* UIColor+Utilities.swift in Sources */, + FD37E9F928A5F14A003AE748 /* _001_ThemePreferences.swift in Sources */, FD37E9C328A1C6F3003AE748 /* ThemeManager.swift in Sources */, C331FF9A2558FA6B00070591 /* Values.swift in Sources */, FD37E9C628A1D4EC003AE748 /* Theme+ClassicDark.swift in Sources */, @@ -4909,6 +4943,7 @@ C33FDC7D255A582000E217F9 /* OWSDispatch.m in Sources */, C38EF247255B6D67007E1867 /* NSAttributedString+OWS.m in Sources */, C33FDD49255A582000E217F9 /* ParamParser.swift in Sources */, + FD37E9FD28A5F216003AE748 /* Configuration.swift in Sources */, C38EF3C5255B6DE7007E1867 /* OWSViewController+ImageEditor.swift in Sources */, C38EF2A5255B6D93007E1867 /* Identicon+ObjC.swift in Sources */, C38EF385255B6DD2007E1867 /* AttachmentTextToolbar.swift in Sources */, @@ -4929,7 +4964,6 @@ C38EF3C1255B6DE7007E1867 /* ImageEditorBrushViewController.swift in Sources */, C33FDD32255A582000E217F9 /* OWSOperation.m in Sources */, C3F0A530255C80BC007BE2A3 /* NoopNotificationsManager.swift in Sources */, - C3D90A7A25773A93002C9DF5 /* Configuration.swift in Sources */, C33FDD8D255A582000E217F9 /* OWSSignalAddress.swift in Sources */, C38EF388255B6DD2007E1867 /* AttachmentApprovalViewController.swift in Sources */, C38EF2A7255B6D93007E1867 /* ProfilePictureView.swift in Sources */, @@ -5067,7 +5101,6 @@ FDCDB8E42817819600352A0C /* (null) in Sources */, C32C5DC9256DD935003C73A2 /* ProxiedContentDownloader.swift in Sources */, C3D9E4C02567767F0040E4F3 /* DataSource.m in Sources */, - C3D9E43125676D3D0040E4F3 /* Configuration.swift in Sources */, C32C5DD2256DD9E5003C73A2 /* LRUCache.swift in Sources */, FD9004152818B46300ABAAF6 /* JobRunner.swift in Sources */, C3A7211A2558BCA10043A11F /* DiffieHellman.swift in Sources */, @@ -5077,6 +5110,7 @@ C3BBE0AA2554D4DE0050F1E3 /* Dictionary+Utilities.swift in Sources */, C3D9E4DA256778410040E4F3 /* UIImage+OWS.m in Sources */, C32C600F256E07F5003C73A2 /* NSUserDefaults+OWS.m in Sources */, + FD37E9FF28A5F2CD003AE748 /* Configuration.swift in Sources */, C3D9E35E25675F640040E4F3 /* OWSFileSystem.m in Sources */, FD09797D27FBDB2000936362 /* Notification+Utilities.swift in Sources */, FDC6D7602862B3F600B04575 /* Dependencies.swift in Sources */, @@ -5645,6 +5679,12 @@ target = C33FD9AA255A548A00E217F9 /* SignalUtilitiesKit */; targetProxy = C3D90A7025773A44002C9DF5 /* PBXContainerItemProxy */; }; + FD37E9F228A5ED70003AE748 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + platformFilter = ios; + target = C3C2A678255388CC00C340D1 /* SessionUtilitiesKit */; + targetProxy = FD37E9F128A5ED70003AE748 /* PBXContainerItemProxy */; + }; FD83B9B527CF200A005E1583 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = C3C2A678255388CC00C340D1 /* SessionUtilitiesKit */; @@ -5989,7 +6029,7 @@ }; C331FF242558F9D400070591 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EC5C23F9D234F558BE5E41DE /* Pods-SessionUIKit.debug.xcconfig */; + baseConfigurationReference = 510955DC99A0FD84F2D1C159 /* Pods-GlobalDependencies-SessionUIKit.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -6046,7 +6086,7 @@ }; C331FF252558F9D400070591 /* App Store Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 29CF8C79F41BF00B1C2E59A0 /* Pods-SessionUIKit.app store release.xcconfig */; + baseConfigurationReference = 18EAE958B8C12503F2C294DF /* Pods-GlobalDependencies-SessionUIKit.app store release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; diff --git a/Session/Closed Groups/EditClosedGroupVC.swift b/Session/Closed Groups/EditClosedGroupVC.swift index c00ac18b7..1abf63ce7 100644 --- a/Session/Closed Groups/EditClosedGroupVC.swift +++ b/Session/Closed Groups/EditClosedGroupVC.swift @@ -82,8 +82,6 @@ final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegat override func viewDidLoad() { super.viewDidLoad() - setUpGradientBackground() - setUpNavBarStyle() setNavBarTitle("Edit Group") let backButton = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil) diff --git a/Session/Closed Groups/NewClosedGroupVC.swift b/Session/Closed Groups/NewClosedGroupVC.swift index 7e2c382a0..5dee4878a 100644 --- a/Session/Closed Groups/NewClosedGroupVC.swift +++ b/Session/Closed Groups/NewClosedGroupVC.swift @@ -45,9 +45,6 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate override func viewDidLoad() { super.viewDidLoad() - setUpGradientBackground() - setUpNavBarStyle() - let customTitleFontSize = Values.largeFontSize setNavBarTitle("vc_create_closed_group_title".localized(), customFontSize: customTitleFontSize) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index b06c8d0b2..ec3be96f4 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -317,11 +317,6 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers override func viewDidLoad() { super.viewDidLoad() - // Gradient - setUpGradientBackground() - - // Nav bar - setUpNavBarStyle() navigationItem.titleView = titleView // Note: We need to update the nav bar buttons here (with invalid data) because if we don't the diff --git a/Session/Conversations/Message Cells/Content Views/QuoteView.swift b/Session/Conversations/Message Cells/Content Views/QuoteView.swift index e8ca3da3a..f7d843bb1 100644 --- a/Session/Conversations/Message Cells/Content Views/QuoteView.swift +++ b/Session/Conversations/Message Cells/Content Views/QuoteView.swift @@ -185,32 +185,40 @@ final class QuoteView: UIView { let isOutgoing = (direction == .outgoing) bodyLabel.font = .systemFont(ofSize: Values.smallFontSize) - bodyLabel.attributedText = body - .map { - MentionUtilities.highlightMentions( - in: $0, - threadVariant: threadVariant, - currentUserPublicKey: currentUserPublicKey, - currentUserBlindedPublicKey: currentUserBlindedPublicKey, - isOutgoingMessage: isOutgoing, - attributes: [:] - ) - } - .defaulting( - to: attachment.map { - NSAttributedString(string: MIMETypeUtil.isAudio($0.contentType) ? "Audio" : "Document") - } - ) - .defaulting(to: NSAttributedString(string: "Document")) - bodyLabel.themeTextColor = (direction == .outgoing ? - .messageBubble_outgoingText : - .messageBubble_incomingText - ) - let bodyLabelSize = bodyLabel.systemLayoutSizeFitting(availableSpace) + ThemeManager.onThemeChange(observer: bodyLabel) { [weak bodyLabel] theme, primaryColor in + let targetThemeColor: ThemeValue = (direction == .outgoing ? + .messageBubble_outgoingText : + .messageBubble_incomingText + ) + + guard let textColor: UIColor = theme.colors[targetThemeColor] else { return } + + bodyLabel?.attributedText = body + .map { + MentionUtilities.highlightMentions( + in: $0, + threadVariant: threadVariant, + currentUserPublicKey: currentUserPublicKey, + currentUserBlindedPublicKey: currentUserBlindedPublicKey, + isOutgoingMessage: isOutgoing, + textColor: textColor, + primaryColor: primaryColor, + attributes: [:] + ) + } + .defaulting( + to: attachment.map { + NSAttributedString(string: MIMETypeUtil.isAudio($0.contentType) ? "Audio" : "Document") + } + ) + .defaulting(to: NSAttributedString(string: "Document")) + } // Label stack view + let bodyLabelSize = bodyLabel.systemLayoutSizeFitting(availableSpace) var authorLabelHeight: CGFloat? + if threadVariant == .openGroup || threadVariant == .closedGroup { let isCurrentUser: Bool = [ currentUserPublicKey, diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index 9062e3ecf..37d8a7f88 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -300,10 +300,12 @@ final class VisibleMessageCell: MessageCell, UITextViewDelegate, BodyTextViewDel authorLabelHeightConstraint.constant = (cellViewModel.senderName != nil ? authorLabelSize.height : 0) // Message status image view - let (image, tintColor, backgroundColor) = getMessageStatusImage(for: cellViewModel) + let (image, tintColor) = cellViewModel.state.statusIconInfo( + variant: cellViewModel.variant, + hasAtLeastOneReadReceipt: cellViewModel.hasAtLeastOneReadReceipt + ) messageStatusImageView.image = image messageStatusImageView.themeTintColor = tintColor - messageStatusImageView.themeBackgroundColor = backgroundColor messageStatusImageView.isHidden = ( cellViewModel.variant != .standardOutgoing || cellViewModel.variant == .infoCall || @@ -838,34 +840,6 @@ final class VisibleMessageCell: MessageCell, UITextViewDelegate, BodyTextViewDel } } - private func getMessageStatusImage(for cellViewModel: MessageViewModel) -> (image: UIImage?, tintColor: ThemeValue?, backgroundColor: ThemeValue?) { - guard cellViewModel.variant == .standardOutgoing else { return (nil, nil, nil) } - - let image: UIImage - var tintColor: ThemeValue? = nil - var backgroundColor: ThemeValue? = nil - - switch (cellViewModel.state, cellViewModel.hasAtLeastOneReadReceipt) { - case (.sending, _): - image = #imageLiteral(resourceName: "CircleDotDotDot").withRenderingMode(.alwaysTemplate) - tintColor = .textPrimary - - case (.sent, false), (.skipped, _): - image = #imageLiteral(resourceName: "CircleCheck").withRenderingMode(.alwaysTemplate) - tintColor = .textPrimary - - case (.sent, true): - image = isLightMode ? #imageLiteral(resourceName: "FilledCircleCheckLightMode") : #imageLiteral(resourceName: "FilledCircleCheckDarkMode") - backgroundColor = isLightMode ? .black : .white - - case (.failed, _): - image = #imageLiteral(resourceName: "message_status_failed").withRenderingMode(.alwaysTemplate) - tintColor = .danger - } - - return (image, tintColor, backgroundColor) - } - private func getSize(for cellViewModel: MessageViewModel) -> CGSize { guard let mediaAttachments: [Attachment] = cellViewModel.attachments?.filter({ $0.isVisualMedia }) else { preconditionFailure() @@ -959,7 +933,7 @@ final class VisibleMessageCell: MessageCell, UITextViewDelegate, BodyTextViewDel result.isUserInteractionEnabled = true result.delegate = delegate - ThemeManager.onThemeChange(observer: result) { [weak result] theme, _ in + ThemeManager.onThemeChange(observer: result) { [weak result] theme, primaryColor in guard let actualTextColor: UIColor = theme.colors[textColor], let backgroundPrimaryColor: UIColor = theme.colors[.backgroundPrimary], @@ -975,6 +949,8 @@ final class VisibleMessageCell: MessageCell, UITextViewDelegate, BodyTextViewDel currentUserPublicKey: cellViewModel.currentUserPublicKey, currentUserBlindedPublicKey: cellViewModel.currentUserBlindedPublicKey, isOutgoingMessage: isOutgoing, + textColor: actualTextColor, + primaryColor: primaryColor, attributes: [ .foregroundColor: actualTextColor, .font: UIFont.systemFont(ofSize: getFontSize(for: cellViewModel)) diff --git a/Session/Conversations/Settings/ProfilePictureVC.swift b/Session/Conversations/Settings/ProfilePictureVC.swift index 44d693394..41524e640 100644 --- a/Session/Conversations/Settings/ProfilePictureVC.swift +++ b/Session/Conversations/Settings/ProfilePictureVC.swift @@ -25,9 +25,9 @@ final class ProfilePictureVC: BaseVC { override func viewDidLoad() { view.backgroundColor = .clear - setUpGradientBackground() - setUpNavBarStyle() + setNavBarTitle(snTitle) + // Close button let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) closeButton.tintColor = Colors.text diff --git a/Session/DMs/NewDMVC.swift b/Session/DMs/NewDMVC.swift index 97b932904..b34f2ff55 100644 --- a/Session/DMs/NewDMVC.swift +++ b/Session/DMs/NewDMVC.swift @@ -62,9 +62,8 @@ final class NewDMVC : BaseVC, UIPageViewControllerDataSource, UIPageViewControll // MARK: Lifecycle override func viewDidLoad() { super.viewDidLoad() - setUpGradientBackground() - setUpNavBarStyle() - setNavBarTitle(NSLocalizedString("vc_create_private_chat_title", comment: "")) + + setNavBarTitle("vc_create_private_chat_title".localized()) let navigationBar = navigationController!.navigationBar // Set up navigation bar buttons let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) diff --git a/Session/Home/GlobalSearch/EmptySearchResultCell.swift b/Session/Home/GlobalSearch/EmptySearchResultCell.swift index 10009dbd4..4afac6994 100644 --- a/Session/Home/GlobalSearch/EmptySearchResultCell.swift +++ b/Session/Home/GlobalSearch/EmptySearchResultCell.swift @@ -9,10 +9,11 @@ import NVActivityIndicatorView class EmptySearchResultCell: UITableViewCell { private lazy var messageLabel: UILabel = { let result = UILabel() + result.text = "CONVERSATION_SEARCH_NO_RESULTS".localized() + result.themeTextColor = .textPrimary result.textAlignment = .center result.numberOfLines = 3 - result.textColor = Colors.text - result.text = NSLocalizedString("CONVERSATION_SEARCH_NO_RESULTS", comment: "") + return result }() @@ -20,12 +21,14 @@ class EmptySearchResultCell: UITableViewCell { let result = NVActivityIndicatorView(frame: CGRect.zero, type: .circleStrokeSpin, color: Colors.text, padding: nil) result.set(.width, to: 40) result.set(.height, to: 40) + return result }() + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - backgroundColor = .clear + themeBackgroundColor = .clear selectionStyle = .none contentView.addSubview(messageLabel) @@ -54,7 +57,8 @@ class EmptySearchResultCell: UITableViewCell { spinner.stopAnimating() spinner.startAnimating() messageLabel.isHidden = true - } else { + } + else { spinner.stopAnimating() messageLabel.isHidden = false } diff --git a/Session/Home/GlobalSearch/GlobalSearchViewController.swift b/Session/Home/GlobalSearch/GlobalSearchViewController.swift index c88b527be..992aca2ce 100644 --- a/Session/Home/GlobalSearch/GlobalSearchViewController.swift +++ b/Session/Home/GlobalSearch/GlobalSearchViewController.swift @@ -50,9 +50,10 @@ class GlobalSearchViewController: BaseVC, UITableViewDelegate, UITableViewDataSo internal lazy var searchBar: SearchBar = { let result: SearchBar = SearchBar() - result.tintColor = Colors.text + result.themeTintColor = .textPrimary result.delegate = self result.showsCancelButton = true + return result }() @@ -74,8 +75,6 @@ class GlobalSearchViewController: BaseVC, UITableViewDelegate, UITableViewDataSo public override func viewDidLoad() { super.viewDidLoad() - setUpGradientBackground() - tableView.dataSource = self tableView.delegate = self view.addSubview(tableView) @@ -116,9 +115,10 @@ class GlobalSearchViewController: BaseVC, UITableViewDelegate, UITableViewDataSo if UIDevice.current.isIPad { let ipadCancelButton = UIButton() ipadCancelButton.setTitle("Cancel", for: .normal) + ipadCancelButton.setThemeTitleColor(.textPrimary, for: .normal) ipadCancelButton.addTarget(self, action: #selector(cancel), for: .touchUpInside) - ipadCancelButton.setTitleColor(Colors.text, for: .normal) searchBarContainer.addSubview(ipadCancelButton) + ipadCancelButton.pin(.trailing, to: .trailing, of: searchBarContainer) ipadCancelButton.autoVCenterInSuperview() searchBar.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets.zero, excludingEdge: .trailing) @@ -312,16 +312,19 @@ extension GlobalSearchViewController { } let titleLabel = UILabel() + titleLabel.font = .boldSystemFont(ofSize: Values.largeFontSize) titleLabel.text = title - titleLabel.textColor = Colors.text - titleLabel.font = .boldSystemFont(ofSize: Values.mediumFontSize) + titleLabel.themeTextColor = .textPrimary let container = UIView() - container.backgroundColor = Colors.cellBackground - container.layoutMargins = UIEdgeInsets(top: Values.smallSpacing, left: Values.mediumSpacing, bottom: Values.smallSpacing, right: Values.mediumSpacing) + container.themeBackgroundColor = .backgroundPrimary container.addSubview(titleLabel) - titleLabel.autoPinEdgesToSuperviewMargins() - + + titleLabel.pin(.top, to: .top, of: container, withInset: Values.mediumSpacing) + titleLabel.pin(.bottom, to: .bottom, of: container, withInset: -Values.mediumSpacing) + titleLabel.pin(.left, to: .left, of: container, withInset: Values.largeSpacing) + titleLabel.pin(.right, to: .right, of: container, withInset: -Values.largeSpacing) + return container } diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index a31e246c1..995f6464c 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -41,14 +41,21 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve private lazy var seedReminderView: SeedReminderView = { let result = SeedReminderView(hasContinueButton: true) let title = "You're almost finished! 80%" - let attributedTitle = NSMutableAttributedString(string: title) - attributedTitle.addAttribute(.foregroundColor, value: Colors.accent, range: (title as NSString).range(of: "80%")) - result.title = attributedTitle - result.subtitle = NSLocalizedString("view_seed_reminder_subtitle_1", comment: "") + result.subtitle = "view_seed_reminder_subtitle_1".localized() result.setProgress(0.8, animated: false) result.delegate = self result.isHidden = !self.viewModel.state.showViewedSeedBanner + ThemeManager.onThemeChange(observer: result) { [weak result] _, primaryColor in + let attributedTitle = NSMutableAttributedString(string: title) + attributedTitle.addAttribute( + .foregroundColor, + value: primaryColor.color, + range: (title as NSString).range(of: "80%") + ) + result?.title = attributedTitle + } + return result }() @@ -56,7 +63,7 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve let result: UILabel = UILabel() result.font = UIFont.systemFont(ofSize: Values.smallFontSize) result.text = "LOADING_CONVERSATIONS".localized() - result.textColor = Colors.text + result.themeTextColor = .textPrimary result.textAlignment = .center result.numberOfLines = 0 @@ -65,7 +72,6 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve private lazy var tableView: UITableView = { let result = UITableView() - result.backgroundColor = .clear result.separatorStyle = .none result.contentInset = UIEdgeInsets( top: 0, @@ -94,23 +100,15 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve private lazy var newConversationButtonSet: NewConversationButtonSet = { let result = NewConversationButtonSet() result.delegate = self - return result - }() - - private lazy var fadeView: UIView = { - let result = UIView() - let gradient = Gradients.homeVCFade - result.setGradient(gradient) - result.isUserInteractionEnabled = false return result }() - + private lazy var emptyStateView: UIView = { let explanationLabel = UILabel() explanationLabel.font = .systemFont(ofSize: Values.smallFontSize) explanationLabel.text = "vc_home_empty_state_message".localized() - explanationLabel.textColor = Colors.text + explanationLabel.themeTextColor = .textPrimary explanationLabel.textAlignment = .center explanationLabel.lineBreakMode = .byWordWrapping explanationLabel.numberOfLines = 0 @@ -142,11 +140,6 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve // Preparation SessionApp.homeViewController.mutate { $0 = self } - // Gradient & nav bar - setUpGradientBackground() - if navigationController?.navigationBar != nil { - setUpNavBarStyle() - } updateNavBarButtons() setUpNavBarSessionHeading() @@ -174,12 +167,6 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve } tableView.pin(.trailing, to: .trailing, of: view) tableView.pin(.bottom, to: .bottom, of: view) - view.addSubview(fadeView) - fadeView.pin(.leading, to: .leading, of: view) - let topInset = 0.15 * view.height() - fadeView.pin(.top, to: .top, of: view, withInset: topInset) - fadeView.pin(.trailing, to: .trailing, of: view) - fadeView.pin(.bottom, to: .bottom, of: view) // Empty state view view.addSubview(emptyStateView) @@ -431,14 +418,6 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve rightBarButtonItem.isAccessibilityElement = true navigationItem.rightBarButtonItem = rightBarButtonItem } - - @objc override internal func handleAppModeChangedNotification(_ notification: Notification) { - super.handleAppModeChangedNotification(notification) - - let gradient = Gradients.homeVCFade - fadeView.setGradient(gradient) // Re-do the gradient - tableView.reloadData() - } // MARK: - UITableViewDataSource @@ -478,7 +457,7 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve switch section.model { case .loadMore: let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(style: .medium) - loadingIndicator.tintColor = Colors.text + loadingIndicator.themeTintColor = .textPrimary loadingIndicator.alpha = 0.5 loadingIndicator.startAnimating() @@ -557,7 +536,7 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve let hide = UITableViewRowAction(style: .destructive, title: "TXT_HIDE_TITLE".localized()) { _, _ in Storage.shared.write { db in db[.hasHiddenMessageRequests] = true } } - hide.backgroundColor = Colors.destructive + hide.themeBackgroundColor = .danger return [hide] @@ -606,7 +585,7 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve self?.present(alert, animated: true, completion: nil) } - delete.backgroundColor = Colors.destructive + delete.themeBackgroundColor = .danger let pin: UITableViewRowAction = UITableViewRowAction( style: .normal, @@ -621,6 +600,7 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve .updateAll(db, SessionThread.Columns.isPinned.set(to: !threadViewModel.threadIsPinned)) } } + pin.themeBackgroundColor = .conversationButton_pinBackground guard threadViewModel.threadVariant == .contact && !threadViewModel.threadIsNoteToSelf else { return [ delete, pin ] @@ -650,7 +630,7 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, NewConve .retainUntilComplete() } } - block.backgroundColor = Colors.unimportant + block.themeBackgroundColor = .backgroundTertiary return [ delete, block, pin ] diff --git a/Session/Home/Message Requests/MessageRequestsViewController.swift b/Session/Home/Message Requests/MessageRequestsViewController.swift index 87ce44b07..83af902dd 100644 --- a/Session/Home/Message Requests/MessageRequestsViewController.swift +++ b/Session/Home/Message Requests/MessageRequestsViewController.swift @@ -69,15 +69,6 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat return result }() - private lazy var fadeView: UIView = { - let result: UIView = UIView() - result.translatesAutoresizingMaskIntoConstraints = false - result.isUserInteractionEnabled = false - result.setGradient(Gradients.homeVCFade) - - return result - }() - private lazy var clearAllButton: OutlineButton = { let result: OutlineButton = OutlineButton(style: .destructive, size: .medium) result.translatesAutoresizingMaskIntoConstraints = false @@ -102,7 +93,6 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat // the dataSource has the correct data) view.addSubview(tableView) view.addSubview(emptyStateLabel) - view.addSubview(fadeView) view.addSubview(clearAllButton) setupLayout() @@ -162,12 +152,7 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat emptyStateLabel.leftAnchor.constraint(equalTo: view.leftAnchor, constant: Values.mediumSpacing), emptyStateLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -Values.mediumSpacing), emptyStateLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), - - fadeView.topAnchor.constraint(equalTo: view.topAnchor, constant: (0.15 * view.bounds.height)), - fadeView.leftAnchor.constraint(equalTo: view.leftAnchor), - fadeView.rightAnchor.constraint(equalTo: view.rightAnchor), - fadeView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - + clearAllButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), clearAllButton.bottomAnchor.constraint( equalTo: view.safeAreaLayoutGuide.bottomAnchor, @@ -259,14 +244,6 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat } } } - - @objc override internal func handleAppModeChangedNotification(_ notification: Notification) { - super.handleAppModeChangedNotification(notification) - - let gradient = Gradients.homeVCFade - fadeView.setGradient(gradient) // Re-do the gradient - tableView.reloadData() - } // MARK: - UITableViewDataSource diff --git a/Session/Home/Message Requests/Views/MessageRequestsCell.swift b/Session/Home/Message Requests/Views/MessageRequestsCell.swift index b2b72f799..7956b1fbb 100644 --- a/Session/Home/Message Requests/Views/MessageRequestsCell.swift +++ b/Session/Home/Message Requests/Views/MessageRequestsCell.swift @@ -28,7 +28,7 @@ class MessageRequestsCell: UITableViewCell { let result: UIView = UIView() result.translatesAutoresizingMaskIntoConstraints = false result.clipsToBounds = true - result.backgroundColor = Colors.sessionMessageRequestsBubble + result.themeBackgroundColor = .conversationButton_unreadBubbleBackground result.layer.cornerRadius = (Values.mediumProfilePictureSize / 2) return result @@ -37,7 +37,7 @@ class MessageRequestsCell: UITableViewCell { private let iconImageView: UIImageView = { let result: UIImageView = UIImageView(image: #imageLiteral(resourceName: "message_requests").withRenderingMode(.alwaysTemplate)) result.translatesAutoresizingMaskIntoConstraints = false - result.tintColor = Colors.sessionMessageRequestsIcon + result.themeTintColor = .conversationButton_unreadBubbleText return result }() @@ -48,8 +48,8 @@ class MessageRequestsCell: UITableViewCell { result.setContentHuggingPriority(.defaultHigh, for: .horizontal) result.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) result.font = .boldSystemFont(ofSize: Values.mediumFontSize) - result.text = NSLocalizedString("MESSAGE_REQUESTS_TITLE", comment: "") - result.textColor = Colors.sessionMessageRequestsTitle + result.text = "MESSAGE_REQUESTS_TITLE".localized() + result.themeTextColor = .textPrimary result.lineBreakMode = .byTruncatingTail return result @@ -59,7 +59,7 @@ class MessageRequestsCell: UITableViewCell { let result: UIView = UIView() result.translatesAutoresizingMaskIntoConstraints = false result.clipsToBounds = true - result.backgroundColor = Colors.text.withAlphaComponent(Values.veryLowOpacity) + result.themeBackgroundColor = .conversationButton_unreadBubbleBackground result.layer.cornerRadius = (FullConversationCell.unreadCountViewSize / 2) return result @@ -69,17 +69,16 @@ class MessageRequestsCell: UITableViewCell { let result = UILabel() result.translatesAutoresizingMaskIntoConstraints = false result.font = .boldSystemFont(ofSize: Values.verySmallFontSize) - result.textColor = Colors.text + result.themeTextColor = .conversationButton_unreadBubbleText result.textAlignment = .center return result }() private func setUpViewHierarchy() { - backgroundColor = Colors.cellPinned + themeBackgroundColor = .conversationButton_unreadBackground selectedBackgroundView = UIView() - selectedBackgroundView?.backgroundColor = Colors.cellSelected - + selectedBackgroundView?.themeBackgroundColor = .conversationButton_unreadHighlight contentView.addSubview(iconContainerView) contentView.addSubview(titleLabel) @@ -115,7 +114,7 @@ class MessageRequestsCell: UITableViewCell { unreadCountView.leftAnchor.constraint(equalTo: titleLabel.rightAnchor, constant: (Values.smallSpacing / 2)), unreadCountView.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor), - unreadCountView.widthAnchor.constraint(equalToConstant: FullConversationCell.unreadCountViewSize), + unreadCountView.widthAnchor.constraint(greaterThanOrEqualToConstant: FullConversationCell.unreadCountViewSize), unreadCountView.heightAnchor.constraint(equalToConstant: FullConversationCell.unreadCountViewSize), unreadCountLabel.topAnchor.constraint(equalTo: unreadCountView.topAnchor), diff --git a/Session/Home/NewConversationButtonSet.swift b/Session/Home/NewConversationButtonSet.swift index b1f933479..eeae96f56 100644 --- a/Session/Home/NewConversationButtonSet.swift +++ b/Session/Home/NewConversationButtonSet.swift @@ -8,7 +8,8 @@ final class NewConversationButtonSet : UIView { private var expandedButton: NewConversationButton? var delegate: NewConversationButtonSetDelegate? - // MARK: Settings + // MARK: - Settings + private let spacing = Values.veryLargeSpacing private let iconSize = CGFloat(24) private let maxDragDistance = CGFloat(56) @@ -16,53 +17,81 @@ final class NewConversationButtonSet : UIView { static let collapsedButtonSize = CGFloat(60) static let expandedButtonSize = CGFloat(72) - // MARK: Components + // MARK: - Components + private lazy var mainButton = NewConversationButton(isMainButton: true, icon: #imageLiteral(resourceName: "Plus").scaled(to: CGSize(width: iconSize, height: iconSize))) private lazy var newDMButton = NewConversationButton(isMainButton: false, icon: #imageLiteral(resourceName: "Message").scaled(to: CGSize(width: iconSize, height: iconSize))) private lazy var createClosedGroupButton = NewConversationButton(isMainButton: false, icon: #imageLiteral(resourceName: "Group").scaled(to: CGSize(width: iconSize, height: iconSize))) private lazy var joinOpenGroupButton = NewConversationButton(isMainButton: false, icon: #imageLiteral(resourceName: "Globe").scaled(to: CGSize(width: iconSize, height: iconSize))) - private lazy var newDMLabel: UILabel = { - let result: UILabel = UILabel() + private lazy var newDMLabel: UIView = { + let result: UIView = UIView() result.translatesAutoresizingMaskIntoConstraints = false - result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize, weight: .bold) - result.text = NSLocalizedString("NEW_CONVERSATION_MENU_DIRECT_MESSAGE", comment: "").uppercased() - result.textColor = Colors.grey - result.textAlignment = .center + result.themeBackgroundColor = .backgroundPrimary + result.layer.cornerRadius = 4 + + let label: UILabel = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .boldSystemFont(ofSize: Values.verySmallFontSize) + label.text = "NEW_CONVERSATION_MENU_DIRECT_MESSAGE".localized().uppercased() + label.themeTextColor = .textPrimary + label.textAlignment = .center + result.addSubview(label) + + label.pin(to: result, withInset: 4) return result }() - private lazy var createClosedGroupLabel: UILabel = { - let result: UILabel = UILabel() + private lazy var createClosedGroupLabel: UIView = { + let result: UIView = UIView() result.translatesAutoresizingMaskIntoConstraints = false - result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize, weight: .bold) - result.text = NSLocalizedString("NEW_CONVERSATION_MENU_CLOSED_GROUP", comment: "").uppercased() - result.textColor = Colors.grey - result.textAlignment = .center + result.themeBackgroundColor = .backgroundPrimary + result.layer.cornerRadius = 4 + + let label: UILabel = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .boldSystemFont(ofSize: Values.verySmallFontSize) + label.text = "NEW_CONVERSATION_MENU_CLOSED_GROUP".localized().uppercased() + label.themeTextColor = .textPrimary + label.textAlignment = .center + result.addSubview(label) + + label.pin(to: result, withInset: 4) return result }() - private lazy var joinOpenGroupLabel: UILabel = { - let result: UILabel = UILabel() + private lazy var joinOpenGroupLabel: UIView = { + let result: UIView = UIView() result.translatesAutoresizingMaskIntoConstraints = false - result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize, weight: .bold) - result.text = NSLocalizedString("NEW_CONVERSATION_MENU_OPEN_GROUP", comment: "").uppercased() - result.textColor = Colors.grey - result.textAlignment = .center + result.themeBackgroundColor = .backgroundPrimary + result.layer.cornerRadius = 4 + + let label: UILabel = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = .boldSystemFont(ofSize: Values.verySmallFontSize) + label.text = "NEW_CONVERSATION_MENU_OPEN_GROUP".localized().uppercased() + label.themeTextColor = .textPrimary + label.textAlignment = .center + result.addSubview(label) + + label.pin(to: result, withInset: 4) return result }() - // MARK: Initialization + // MARK: - Initialization + override init(frame: CGRect) { super.init(frame: frame) + setUpViewHierarchy() } required init?(coder: NSCoder) { super.init(coder: coder) + setUpViewHierarchy() } @@ -75,49 +104,61 @@ final class NewConversationButtonSet : UIView { createClosedGroupButton.isAccessibilityElement = true joinOpenGroupButton.accessibilityLabel = "Join open group button" joinOpenGroupButton.isAccessibilityElement = true + let inset = (NewConversationButtonSet.expandedButtonSize - NewConversationButtonSet.collapsedButtonSize) / 2 addSubview(joinOpenGroupLabel) addSubview(joinOpenGroupButton) + horizontalButtonConstraints[joinOpenGroupButton] = joinOpenGroupButton.pin(.left, to: .left, of: self, withInset: inset) verticalButtonConstraints[joinOpenGroupButton] = joinOpenGroupButton.pin(.bottom, to: .bottom, of: self, withInset: -inset) joinOpenGroupLabel.center(.horizontal, in: joinOpenGroupButton) joinOpenGroupLabel.pin(.top, to: .bottom, of: joinOpenGroupButton, withInset: 8) addSubview(newDMLabel) addSubview(newDMButton) + newDMButton.center(.horizontal, in: self) verticalButtonConstraints[newDMButton] = newDMButton.pin(.top, to: .top, of: self, withInset: inset) newDMLabel.center(.horizontal, in: newDMButton) newDMLabel.pin(.top, to: .bottom, of: newDMButton, withInset: 8) addSubview(createClosedGroupLabel) addSubview(createClosedGroupButton) + horizontalButtonConstraints[createClosedGroupButton] = createClosedGroupButton.pin(.right, to: .right, of: self, withInset: -inset) verticalButtonConstraints[createClosedGroupButton] = createClosedGroupButton.pin(.bottom, to: .bottom, of: self, withInset: -inset) createClosedGroupLabel.center(.horizontal, in: createClosedGroupButton) createClosedGroupLabel.pin(.top, to: .bottom, of: createClosedGroupButton, withInset: 8) addSubview(mainButton) + mainButton.center(.horizontal, in: self) mainButton.pin(.bottom, to: .bottom, of: self, withInset: -inset) + let width = 2 * NewConversationButtonSet.expandedButtonSize + 2 * spacing + NewConversationButtonSet.collapsedButtonSize set(.width, to: width) + let height = NewConversationButtonSet.expandedButtonSize + spacing + NewConversationButtonSet.collapsedButtonSize set(.height, to: height) collapse(withAnimation: false) isUserInteractionEnabled = true + let joinOpenGroupButtonTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleJoinOpenGroupButtonTapped)) joinOpenGroupButton.addGestureRecognizer(joinOpenGroupButtonTapGestureRecognizer) + let createNewPrivateChatButtonTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleCreateNewPrivateChatButtonTapped)) newDMButton.addGestureRecognizer(createNewPrivateChatButtonTapGestureRecognizer) + let createNewClosedGroupButtonTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleCreateNewClosedGroupButtonTapped)) createClosedGroupButton.addGestureRecognizer(createNewClosedGroupButtonTapGestureRecognizer) } - // MARK: Interaction + // MARK: - Interaction + @objc private func handleJoinOpenGroupButtonTapped() { delegate?.joinOpenGroup() } @objc private func handleCreateNewPrivateChatButtonTapped() { delegate?.createNewDM() } @objc private func handleCreateNewClosedGroupButtonTapped() { delegate?.createClosedGroup() } private func expand(isUserDragging: Bool) { let views = [ joinOpenGroupButton, joinOpenGroupLabel, newDMButton, newDMLabel, createClosedGroupButton, createClosedGroupLabel ] + UIView.animate(withDuration: 0.25, animations: { views.forEach { $0.alpha = 1 } let inset = (NewConversationButtonSet.expandedButtonSize - NewConversationButtonSet.collapsedButtonSize) / 2 @@ -137,6 +178,7 @@ final class NewConversationButtonSet : UIView { isUserDragging = false let buttons = [ joinOpenGroupButton, newDMButton, createClosedGroupButton ] let labels = [ joinOpenGroupLabel, newDMLabel, createClosedGroupLabel ] + UIView.animate(withDuration: isAnimated ? 0.25 : 0) { labels.forEach { label in label.alpha = 0 @@ -264,27 +306,67 @@ final class NewConversationButtonSet : UIView { } } -// MARK: Delegate +// MARK: - Delegate + protocol NewConversationButtonSetDelegate { - func joinOpenGroup() func createNewDM() func createClosedGroup() } -// MARK: Button -private final class NewConversationButton : UIImageView { +// MARK: - Button + +private final class NewConversationButton: UIImageView { private let isMainButton: Bool private let icon: UIImage var widthConstraint: NSLayoutConstraint! var heightConstraint: NSLayoutConstraint! + + // MARK: - UI + + private let innerShadowLayer: CALayer = { + let result: CALayer = CALayer() + result.masksToBounds = true + result.themeShadowColor = .menuButton_innerShadow + result.position = CGPoint( + x: (NewConversationButtonSet.collapsedButtonSize / 2), + y: (NewConversationButtonSet.collapsedButtonSize / 2) + ) + result.bounds = CGRect( + x: 0, + y: 0, + width: NewConversationButtonSet.collapsedButtonSize, + height: NewConversationButtonSet.collapsedButtonSize + ) + result.cornerRadius = (NewConversationButtonSet.collapsedButtonSize / 2) + result.shadowOffset = .zero + result.shadowOpacity = 0.4 + result.shadowRadius = 2 + + let cutout: UIBezierPath = UIBezierPath( + roundedRect: result.bounds + .insetBy(dx: result.shadowRadius, dy: result.shadowRadius), + cornerRadius: (NewConversationButtonSet.collapsedButtonSize / 2) + ).reversing() + let path: UIBezierPath = UIBezierPath( + roundedRect: result.bounds, + cornerRadius: (NewConversationButtonSet.collapsedButtonSize / 2) + ) + path.append(cutout) + result.shadowPath = path.cgPath + + return result + }() + + // MARK: - Initialization init(isMainButton: Bool, icon: UIImage) { self.isMainButton = isMainButton self.icon = icon + super.init(frame: CGRect.zero) + setUpViewHierarchy() - NotificationCenter.default.addObserver(self, selector: #selector(handleAppModeChangedNotification(_:)), name: .appModeChanged, object: nil) } override init(frame: CGRect) { @@ -294,26 +376,39 @@ private final class NewConversationButton : UIImageView { required init?(coder: NSCoder) { preconditionFailure("Use init(isMainButton:) instead.") } - - deinit { - NotificationCenter.default.removeObserver(self) - } private func setUpViewHierarchy(isUpdate: Bool = false) { - let newConversationButtonCollapsedBackground = isLightMode ? UIColor(hex: 0xF5F5F5) : UIColor(hex: 0x1F1F1F) - backgroundColor = isMainButton ? Colors.accent : newConversationButtonCollapsedBackground - let size = NewConversationButtonSet.collapsedButtonSize - layer.cornerRadius = size / 2 - let glowColor = isMainButton ? Colors.expandedButtonGlowColor : (isLightMode ? UIColor.black.withAlphaComponent(0.4) : UIColor.black) - let glowConfiguration = UIView.CircularGlowConfiguration(size: size, color: glowColor, isAnimated: false, radius: isLightMode ? 4 : 6) - setCircularGlow(with: glowConfiguration) - layer.masksToBounds = false - let iconColor = (isMainButton && isLightMode) ? UIColor.white : (isLightMode ? UIColor.black : UIColor.white) - image = icon.asTintedImage(color: iconColor)! + clipsToBounds = false + image = icon.withRenderingMode(.alwaysTemplate) contentMode = .center + layer.cornerRadius = (NewConversationButtonSet.collapsedButtonSize / 2) + + themeBackgroundColor = (isMainButton ? .menuButton_background : .backgroundTertiary) + themeTintColor = .menuButton_icon + + if isMainButton { + themeShadowColor = .menuButton_outerShadow + layer.shadowRadius = 15 + layer.shadowOpacity = 0.3 + layer.shadowOffset = .zero + layer.cornerRadius = (NewConversationButtonSet.collapsedButtonSize / 2) + layer.shadowPath = UIBezierPath( + ovalIn: CGRect( + origin: CGPoint.zero, + size: CGSize( + width: NewConversationButtonSet.collapsedButtonSize, + height: NewConversationButtonSet.collapsedButtonSize + ) + ) + ).cgPath + + self.layer.addSublayer(innerShadowLayer) + + } + if !isUpdate { - widthConstraint = set(.width, to: size) - heightConstraint = set(.height, to: size) + widthConstraint = set(.width, to: NewConversationButtonSet.collapsedButtonSize) + heightConstraint = set(.height, to: NewConversationButtonSet.collapsedButtonSize) } } diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index e65899328..c723660e0 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -89,8 +89,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD mainWindow.rootViewController = self.loadingViewController mainWindow.makeKeyAndVisible() - adapt(appMode: AppModeManager.getAppModeOrSystemDefault()) - // This must happen in appDidFinishLaunching or earlier to ensure we don't // miss notifications. // Setting the delegate also seems to prevent us from getting the legacy notification @@ -156,7 +154,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD UserDefaults.sharedLokiProject?[.isMainAppActive] = true ensureRootViewController() - adapt(appMode: AppModeManager.getAppModeOrSystemDefault()) AppReadiness.runNowOrWhenAppDidBecomeReady { [weak self] in self?.handleActivation() diff --git a/Session/Meta/Images.xcassets/Session/CircleDotDotDot.imageset/CircleDotDotDot.pdf b/Session/Meta/Images.xcassets/Session/CircleDotDotDot.imageset/CircleDotDotDot.pdf deleted file mode 100644 index fa02fc4b10a1a82eb8f447c3e7a00186fb271daf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171587 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

1HkJ6^Si;4R!G@jmHDq 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 TC1g?)(1i@1u6{1-oD!M<%K2LL diff --git a/Session/Meta/Images.xcassets/message_status_failed.imageset/error-12@2x.png b/Session/Meta/Images.xcassets/message_status_failed.imageset/error-12@2x.png deleted file mode 100644 index f8c0b4b7c6407a4b30195c73005dd9dae7e1c6f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 423 zcmV;Y0a*TtP)Px$VM#YMu7D`HjB|q&C@DA$g*)T}gbsn= zeP+iZva_>*_esxQyl>vHvp@Ezh~r7!Q}I=N7RMr}#Y$X>KjKEb3K*5*UOYNPgVvI( z8ONKte?^RU;+Oa#PQ=GR+B~BV4O(J|jbg6egGj(qq%0oLpe2S_JbFQP1aQ%-h(9F8 z;yWW5tJBJIi@BvH*2;xvi%+$zEbYUd1{xTHl?%@XEJaoVljYSsB>^6I;fZ%K6A5HR zct}Zr2VQ7r54y04!1wt!$kn_W@3kz+#@hCfIs&}V;$3XR4>pm9)C72;-BO~gAVD26 z{8_hmW;L&x1XVD5NiZEr13j2mMS@jOzk5+v^qW`XoqeP6$8sDM<>iQ(l&psx$+8~T zHX2?QoatA>4GEaAI8TTUlXhPx%cS%G+R9Fekm@!WqK@^0Kgn}XkG)N#pnO~5OhK4j0ahX3smyYJ@G(pPWNTj4l z5g}J7RJ8d6Mj{doC57dX`Hp+m+~I`X_Wq~l1mM>oncR%eu$|i{+34%di^(^tMWu_3rzIdnfOlJ z7hj4mY7*~@yhjeX?fMUTjow*USN3<&o84;uUfdK@K`u4adM|pTkpvQdir(Op<~vE% zvy-U(EP78g9yP^M`pW#){8;P?^rB}NL+hU(--#tt_*U#1^mJ3~shQvk2XG52cxm%R zg=nA^n0nxB8jGyZM9le~QF>8|vAV=LKnqRk@vy-PaZs*`;9R_}qJI9Mg(kqmA%sg?iyn=Hlxyx{i2IqqRRlebuDQLGhI(9#nNlnE>K!Z8STcLFuW-wR zel3Hc#vaDd$Q-`1I5jMl$g)G?T)5^4L#Ni^jm3S1u334R_vo0%_=BS(nhh1idBi<% z4oW3QEpZOeidsBOPy6<%>)+lv0y(*8Oiy^ll?V0^_#&QHQBkaEqva^n|vHD-D41@*2VUNA~)poY; 0 ? + .conversationButton_unreadBackground : + .conversationButton_background + ) + self.selectedBackgroundView?.themeBackgroundColor = (unreadCount > 0 ? + .conversationButton_unreadHighlight : + .conversationButton_highlight + ) if cellViewModel.threadIsBlocked == true { - accentLineView.backgroundColor = Colors.destructive + accentLineView.themeBackgroundColor = .danger accentLineView.alpha = 1 } else { - accentLineView.backgroundColor = Colors.accent + accentLineView.themeBackgroundColor = .conversationButton_unreadStripBackground accentLineView.alpha = (unreadCount > 0 ? 1 : 0.0001) // Setting the alpha to exactly 0 causes an issue on iOS 12 } @@ -357,37 +387,37 @@ public final class FullConversationCell: UITableViewCell { typingIndicatorView.startAnimation() } else { - snippetLabel.attributedText = getSnippet(cellViewModel: cellViewModel) typingIndicatorView.isHidden = true typingIndicatorView.stopAnimation() - } - - statusIndicatorView.backgroundColor = nil - - switch (cellViewModel.interactionVariant, cellViewModel.interactionState) { - case (.standardOutgoing, .sending): - statusIndicatorView.image = #imageLiteral(resourceName: "CircleDotDotDot").withRenderingMode(.alwaysTemplate) - statusIndicatorView.tintColor = Colors.text - statusIndicatorView.isHidden = false - - case (.standardOutgoing, .sent): - statusIndicatorView.image = #imageLiteral(resourceName: "CircleCheck").withRenderingMode(.alwaysTemplate) - statusIndicatorView.tintColor = Colors.text - statusIndicatorView.isHidden = false - - case (.standardOutgoing, .failed): - statusIndicatorView.image = #imageLiteral(resourceName: "message_status_failed").withRenderingMode(.alwaysTemplate) - statusIndicatorView.tintColor = Colors.destructive - statusIndicatorView.isHidden = false - default: - statusIndicatorView.isHidden = true + ThemeManager.onThemeChange(observer: snippetLabel) { [weak self, weak snippetLabel] theme, _ in + guard let textColor: UIColor = theme.colors[.textPrimary] else { return } + + snippetLabel?.attributedText = self?.getSnippet( + cellViewModel: cellViewModel, + textColor: textColor + ) + } } + + let stateInfo = cellViewModel.interactionState?.statusIconInfo( + variant: (cellViewModel.interactionVariant ?? .standardOutgoing), + hasAtLeastOneReadReceipt: (cellViewModel.interactionHasAtLeastOneReadReceipt ?? false) + ) + statusIndicatorView.image = stateInfo?.image + statusIndicatorView.themeTintColor = stateInfo?.tintColor + statusIndicatorView.isHidden = ( + cellViewModel.interactionVariant != .standardOutgoing && + cellViewModel.interactionState != .skipped + ) } // MARK: - Snippet generation - private func getSnippet(cellViewModel: SessionThreadViewModel) -> NSMutableAttributedString { + private func getSnippet( + cellViewModel: SessionThreadViewModel, + textColor: UIColor + ) -> NSMutableAttributedString { // If we don't have an interaction then do nothing guard cellViewModel.interactionId != nil else { return NSMutableAttributedString() } @@ -398,13 +428,13 @@ public final class FullConversationCell: UITableViewCell { string: "\u{e067} ", attributes: [ .font: UIFont.ows_elegantIconsFont(10), - .foregroundColor :Colors.unimportant + .foregroundColor: textColor ] )) } else if cellViewModel.threadOnlyNotifyForMentions == true { let imageAttachment = NSTextAttachment() - imageAttachment.image = UIImage(named: "NotifyMentions.png")?.asTintedImage(color: Colors.unimportant) + imageAttachment.image = UIImage(named: "NotifyMentions.png")?.asTintedImage(color: textColor) imageAttachment.bounds = CGRect(x: 0, y: -2, width: Values.smallFontSize, height: Values.smallFontSize) let imageString = NSAttributedString(attachment: imageAttachment) @@ -413,30 +443,22 @@ public final class FullConversationCell: UITableViewCell { string: " ", attributes: [ .font: UIFont.ows_elegantIconsFont(10), - .foregroundColor: Colors.unimportant + .foregroundColor: textColor ] )) } - let font: UIFont = ((cellViewModel.threadUnreadCount ?? 0) > 0 ? - .boldSystemFont(ofSize: Values.smallFontSize) : - .systemFont(ofSize: Values.smallFontSize) - ) - if cellViewModel.threadVariant == .closedGroup || cellViewModel.threadVariant == .openGroup { let authorName: String = cellViewModel.authorName(for: cellViewModel.threadVariant) result.append(NSAttributedString( string: "\(authorName): ", - attributes: [ - .font: font, - .foregroundColor: Colors.text - ] + attributes: [ .foregroundColor: textColor ] )) } result.append(NSAttributedString( - string: MentionUtilities.highlightMentions( + string: MentionUtilities.highlightMentionsNoAttributes( in: Interaction.previewText( variant: (cellViewModel.interactionVariant ?? .standardIncoming), body: cellViewModel.interactionBody, @@ -450,10 +472,7 @@ public final class FullConversationCell: UITableViewCell { currentUserPublicKey: cellViewModel.currentUserPublicKey, currentUserBlindedPublicKey: cellViewModel.currentUserBlindedPublicKey ), - attributes: [ - .font: font, - .foregroundColor: Colors.text - ] + attributes: [ .foregroundColor: textColor ] )) return result @@ -465,7 +484,8 @@ public final class FullConversationCell: UITableViewCell { currentUserPublicKey: String, currentUserBlindedPublicKey: String?, searchText: String, - fontSize: CGFloat + fontSize: CGFloat, + textColor: UIColor ) -> NSAttributedString { guard !content.isEmpty, content != "NOTE_TO_SELF".localized() else { return NSMutableAttributedString( @@ -473,7 +493,7 @@ public final class FullConversationCell: UITableViewCell { "\(authorName ?? ""): \(content)" : content ), - attributes: [ .foregroundColor: Colors.text ] + attributes: [ .foregroundColor: textColor ] ) } @@ -481,7 +501,7 @@ public final class FullConversationCell: UITableViewCell { // // Note: The 'threadVariant' is used for profile context but in the search results // we don't want to include the truncated id as part of the name so we exclude it - let mentionReplacedContent: String = MentionUtilities.highlightMentions( + let mentionReplacedContent: String = MentionUtilities.highlightMentionsNoAttributes( in: content, threadVariant: .contact, currentUserPublicKey: currentUserPublicKey, @@ -490,7 +510,7 @@ public final class FullConversationCell: UITableViewCell { let result: NSMutableAttributedString = NSMutableAttributedString( string: mentionReplacedContent, attributes: [ - .foregroundColor: Colors.text + .foregroundColor: textColor .withAlphaComponent(Values.lowOpacity) ] ) @@ -523,7 +543,7 @@ public final class FullConversationCell: UITableViewCell { } let legacyRange: NSRange = NSRange(range, in: normalizedSnippet) - result.addAttribute(.foregroundColor, value: Colors.text, range: legacyRange) + result.addAttribute(.foregroundColor, value: textColor, range: legacyRange) result.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: fontSize), range: legacyRange) } } diff --git a/Session/Shared/LoadingViewController.swift b/Session/Shared/LoadingViewController.swift index 8bbe92fba..c366bf011 100644 --- a/Session/Shared/LoadingViewController.swift +++ b/Session/Shared/LoadingViewController.swift @@ -25,7 +25,7 @@ public class LoadingViewController: UIViewController { private var logoView: UIImageView = { let result: UIImageView = UIImageView(image: #imageLiteral(resourceName: "SessionGreen64")) result.contentMode = .scaleAspectFit - result.layer.shadowColor = Colors.accent.cgColor + result.layer.shadowColor = Theme.PrimaryColor.green.color.cgColor result.layer.shadowOffset = .zero result.layer.shadowRadius = 3 result.layer.shadowOpacity = 0 @@ -37,8 +37,8 @@ public class LoadingViewController: UIViewController { let result: UIProgressView = UIProgressView(progressViewStyle: .bar) result.clipsToBounds = true result.progress = 0 - result.tintColor = Colors.accent - result.trackTintColor = Colors.text.withAlphaComponent(0.1) + result.tintColor = Theme.PrimaryColor.green.color + result.progressTintColor = Theme.classicDark.colors[.textPrimary]?.withAlphaComponent(0.1) result.layer.cornerRadius = 6 return result @@ -48,7 +48,7 @@ public class LoadingViewController: UIViewController { let result: UILabel = UILabel() result.font = UIFont.systemFont(ofSize: Values.mediumFontSize) result.text = "DATABASE_VIEW_OVERLAY_TITLE".localized() - result.textColor = Colors.text + result.textColor = Theme.classicDark.colors[.textPrimary] result.textAlignment = .center result.numberOfLines = 0 result.lineBreakMode = .byWordWrapping @@ -60,7 +60,7 @@ public class LoadingViewController: UIViewController { let result: UILabel = UILabel() result.font = UIFont.systemFont(ofSize: Values.verySmallFontSize) result.text = "DATABASE_VIEW_OVERLAY_SUBTITLE".localized() - result.textColor = Colors.text + result.textColor = Theme.classicDark.colors[.textPrimary] result.textAlignment = .center result.numberOfLines = 0 result.lineBreakMode = .byWordWrapping @@ -84,7 +84,7 @@ public class LoadingViewController: UIViewController { override public func loadView() { self.view = UIView() - self.view.backgroundColor = Colors.navigationBarBackground + self.view.backgroundColor = Theme.classicDark.colors[.backgroundPrimary] self.view.addSubview(self.logoView) self.view.addSubview(self.labelStack) diff --git a/Session/Shared/ScanQRCodeWrapperVC.swift b/Session/Shared/ScanQRCodeWrapperVC.swift index 2d8241569..d6a345195 100644 --- a/Session/Shared/ScanQRCodeWrapperVC.swift +++ b/Session/Shared/ScanQRCodeWrapperVC.swift @@ -28,7 +28,7 @@ final class ScanQRCodeWrapperVC : BaseVC { if isPresentedModally { navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(close)) } - setUpGradientBackground() + // Set up scan QR code VC scanQRCodeVC.scanDelegate = delegate let scanQRCodeVCView = scanQRCodeVC.view! diff --git a/Session/Shared/UserSelectionVC.swift b/Session/Shared/UserSelectionVC.swift index a2946f565..632a25b14 100644 --- a/Session/Shared/UserSelectionVC.swift +++ b/Session/Shared/UserSelectionVC.swift @@ -45,9 +45,9 @@ final class UserSelectionVC: BaseVC, UITableViewDataSource, UITableViewDelegate override func viewDidLoad() { super.viewDidLoad() - setUpGradientBackground() - setUpNavBarStyle() + setNavBarTitle(navBarTitle) + navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDoneButtonTapped)) view.addSubview(tableView) tableView.pin(to: view) diff --git a/Session/Utilities/MentionUtilities.swift b/Session/Utilities/MentionUtilities.swift index f5876d5d6..bbf033c5e 100644 --- a/Session/Utilities/MentionUtilities.swift +++ b/Session/Utilities/MentionUtilities.swift @@ -6,20 +6,23 @@ import SessionUIKit import SessionMessagingKit public enum MentionUtilities { - public static func highlightMentions( + public static func highlightMentionsNoAttributes( in string: String, threadVariant: SessionThread.Variant, currentUserPublicKey: String, currentUserBlindedPublicKey: String? ) -> String { + /// **Note:** We are returning the string here so the 'textColor' and 'primaryColor' values are irrelevant return highlightMentions( in: string, threadVariant: threadVariant, currentUserPublicKey: currentUserPublicKey, currentUserBlindedPublicKey: currentUserBlindedPublicKey, isOutgoingMessage: false, + textColor: .black, + primaryColor: Theme.PrimaryColor.green, attributes: [:] - ).string // isOutgoingMessage and attributes are irrelevant + ).string } public static func highlightMentions( @@ -28,6 +31,8 @@ public enum MentionUtilities { currentUserPublicKey: String?, currentUserBlindedPublicKey: String?, isOutgoingMessage: Bool, + textColor: UIColor, + primaryColor: Theme.PrimaryColor, attributes: [NSAttributedString.Key: Any] ) -> NSAttributedString { guard @@ -87,18 +92,19 @@ public enum MentionUtilities { // to maintain a "rounded rect" effect rather than a "pill" effect result.addAttribute(.currentUserMentionBackgroundCornerRadius, value: (8 * sizeDiff), range: mention.range) result.addAttribute(.currentUserMentionBackgroundPadding, value: (3 * sizeDiff), range: mention.range) - result.addAttribute(.currentUserMentionBackgroundColor, value: Colors.accent, range: mention.range) - result.addAttribute(.foregroundColor, value: UIColor.black, range: mention.range) + result.addAttribute(.currentUserMentionBackgroundColor, value: primaryColor.color, range: mention.range) + result.addAttribute( + .foregroundColor, + value: UIColor.black, // Note: This text should always be black + range: mention.range + ) } else { - let color: UIColor = { - switch (isLightMode, isOutgoingMessage) { - case (_, true): return .black - case (true, false): return .black - case (false, false): return Colors.accent - } - }() - result.addAttribute(.foregroundColor, value: color, range: mention.range) + result.addAttribute( + .foregroundColor, + value: (isOutgoingMessage ? primaryColor.color : textColor), + range: mention.range + ) } } diff --git a/SessionMessagingKit/Database/Models/RecipientState.swift b/SessionMessagingKit/Database/Models/RecipientState.swift index 9c29d2002..baad3bea6 100644 --- a/SessionMessagingKit/Database/Models/RecipientState.swift +++ b/SessionMessagingKit/Database/Models/RecipientState.swift @@ -4,6 +4,7 @@ import Foundation import GRDB import SignalCoreKit import SessionUtilitiesKit +import SessionUIKit public struct RecipientState: Codable, Equatable, FetchableRecord, PersistableRecord, TableRecord, ColumnExpressible { public static var databaseTableName: String { "recipientState" } @@ -63,6 +64,19 @@ public struct RecipientState: Codable, Equatable, FetchableRecord, PersistableRe return "MESSAGE_STATUS_SENT".localized() } } + + public func statusIconInfo(variant: Interaction.Variant, hasAtLeastOneReadReceipt: Bool) -> (image: UIImage?, tintColor: ThemeValue) { + guard variant == .standardOutgoing else { return (nil, .textPrimary) } + + switch (self, hasAtLeastOneReadReceipt) { + case (.sending, _): return (UIImage(systemName: "ellipsis.circle"), .textPrimary) + case (.sent, false), (.skipped, _): + return (UIImage(systemName: "checkmark.circle"), .textPrimary) + + case (.sent, true): return (UIImage(systemName: "checkmark.circle.fill"), .textPrimary) + case (.failed, _): return (UIImage(systemName: "exclamationmark.circle"), .danger) + } + } } /// The id for the interaction this state belongs to diff --git a/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift b/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift index bb78b6940..1fb064f9b 100644 --- a/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift +++ b/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift @@ -50,6 +50,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat public static let interactionTimestampMsKey: SQL = SQL(stringLiteral: CodingKeys.interactionTimestampMs.stringValue) public static let interactionBodyKey: SQL = SQL(stringLiteral: CodingKeys.interactionBody.stringValue) public static let interactionStateKey: SQL = SQL(stringLiteral: CodingKeys.interactionState.stringValue) + public static let interactionHasAtLeastOneReadReceiptKey: SQL = SQL(stringLiteral: CodingKeys.interactionHasAtLeastOneReadReceipt.stringValue) public static let interactionIsOpenGroupInvitationKey: SQL = SQL(stringLiteral: CodingKeys.interactionIsOpenGroupInvitation.stringValue) public static let interactionAttachmentDescriptionInfoKey: SQL = SQL(stringLiteral: CodingKeys.interactionAttachmentDescriptionInfo.stringValue) public static let interactionAttachmentCountKey: SQL = SQL(stringLiteral: CodingKeys.interactionAttachmentCount.stringValue) @@ -117,6 +118,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat private let interactionTimestampMs: Int64? public let interactionBody: String? public let interactionState: RecipientState.State? + public let interactionHasAtLeastOneReadReceipt: Bool? public let interactionIsOpenGroupInvitation: Bool? public let interactionAttachmentDescriptionInfo: Attachment.DescriptionInfo? public let interactionAttachmentCount: Int? @@ -269,6 +271,7 @@ public extension SessionThreadViewModel { self.interactionTimestampMs = nil self.interactionBody = nil self.interactionState = nil + self.interactionHasAtLeastOneReadReceipt = nil self.interactionIsOpenGroupInvitation = nil self.interactionAttachmentDescriptionInfo = nil self.interactionAttachmentCount = nil @@ -323,6 +326,7 @@ public extension SessionThreadViewModel { interactionTimestampMs: self.interactionTimestampMs, interactionBody: self.interactionBody, interactionState: self.interactionState, + interactionHasAtLeastOneReadReceipt: self.interactionHasAtLeastOneReadReceipt, interactionIsOpenGroupInvitation: self.interactionIsOpenGroupInvitation, interactionAttachmentDescriptionInfo: self.interactionAttachmentDescriptionInfo, interactionAttachmentCount: self.interactionAttachmentCount, @@ -366,6 +370,9 @@ public extension SessionThreadViewModel { let interactionAttachment: TypedTableAlias = TypedTableAlias() let profile: TypedTableAlias = TypedTableAlias() + let interactionStateInteractionIdColumnLiteral: SQL = SQL(stringLiteral: RecipientState.Columns.interactionId.name) + let readReceiptTableLiteral: SQL = SQL(stringLiteral: "readReceipt") + let readReceiptReadTimestampMsColumnLiteral: SQL = SQL(stringLiteral: RecipientState.Columns.readTimestampMs.name) let profileIdColumnLiteral: SQL = SQL(stringLiteral: Profile.Columns.id.name) let profileNicknameColumnLiteral: SQL = SQL(stringLiteral: Profile.Columns.nickname.name) let profileNameColumnLiteral: SQL = SQL(stringLiteral: Profile.Columns.name.name) @@ -380,7 +387,7 @@ public extension SessionThreadViewModel { /// /// Explicitly set default values for the fields ignored for search results let numColumnsBeforeProfiles: Int = 12 - let numColumnsBetweenProfilesAndAttachmentInfo: Int = 10 // The attachment info columns will be combined + let numColumnsBetweenProfilesAndAttachmentInfo: Int = 11 // The attachment info columns will be combined let request: SQLRequest = """ SELECT @@ -415,6 +422,7 @@ public extension SessionThreadViewModel { -- Default to 'sending' assuming non-processed interaction when null IFNULL(MIN(\(recipientState[.state])), \(SQL("\(RecipientState.State.sending)"))) AS \(ViewModel.interactionStateKey), + (\(readReceiptTableLiteral).\(readReceiptReadTimestampMsColumnLiteral) IS NOT NULL) AS \(ViewModel.interactionHasAtLeastOneReadReceiptKey), (\(linkPreview[.url]) IS NOT NULL) AS \(ViewModel.interactionIsOpenGroupInvitationKey), -- These 4 properties will be combined into 'Attachment.DescriptionInfo' @@ -456,6 +464,10 @@ public extension SessionThreadViewModel { \(SQL("\(recipientState[.state]) != \(RecipientState.State.skipped)")) AND \(recipientState[.interactionId]) = \(Interaction.self).\(ViewModel.interactionIdKey) ) + LEFT JOIN \(RecipientState.self) AS \(readReceiptTableLiteral) ON ( + \(readReceiptTableLiteral).\(readReceiptReadTimestampMsColumnLiteral) IS NOT NULL AND + \(Interaction.self).\(ViewModel.interactionIdKey) = \(readReceiptTableLiteral).\(interactionStateInteractionIdColumnLiteral) + ) LEFT JOIN \(LinkPreview.self) ON ( \(linkPreview[.url]) = \(interaction[.linkPreviewUrl]) AND \(SQL("\(linkPreview[.variant]) = \(LinkPreview.Variant.openGroupInvitation)")) AND diff --git a/SessionShareExtension/ShareVC.swift b/SessionShareExtension/ShareVC.swift index aeef0393b..006c162e7 100644 --- a/SessionShareExtension/ShareVC.swift +++ b/SessionShareExtension/ShareVC.swift @@ -6,7 +6,7 @@ import PromiseKit import SignalUtilitiesKit import SessionUIKit -final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerDelegate { +final class ShareVC: UINavigationController, ShareViewDelegate, AppModeManagerDelegate { private var areVersionMigrationsComplete = false public static var attachmentPrepPromise: Promise<[SignalAttachment]>? @@ -29,6 +29,9 @@ final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerD SetCurrentAppContext(appContext) AppModeManager.configure(delegate: self) + // Need to manually trigger these since we don't have a "mainWindow" here + ThemeManager.applyNavigationStyling() + ThemeManager.applyWindowStyling() Logger.info("") @@ -66,6 +69,14 @@ final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerD object: nil ) } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + // Note: The share extension doesn't have a proper window so we need to manually update + // the ThemeManager from here + ThemeManager.traitCollectionDidChange(previousTraitCollection) + } @objc func versionMigrationsDidComplete(needsConfigSync: Bool) { diff --git a/SessionShareExtension/ThreadPickerVC.swift b/SessionShareExtension/ThreadPickerVC.swift index a2ad09208..e2c59b5c6 100644 --- a/SessionShareExtension/ThreadPickerVC.swift +++ b/SessionShareExtension/ThreadPickerVC.swift @@ -45,32 +45,15 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView return tableView }() - private lazy var fadeView: UIView = { - let view = UIView() - let gradient = Gradients.homeVCFade - view.setGradient(gradient) - view.isUserInteractionEnabled = false - - return view - }() - // MARK: - Lifecycle override func viewDidLoad() { super.viewDidLoad() - setupNavBar() - - // Gradient - view.themeBackgroundColor = .backgroundPrimary - - // Title navigationItem.titleView = titleLabel - // Table view - + view.themeBackgroundColor = .backgroundPrimary view.addSubview(tableView) - view.addSubview(fadeView) setupLayout() @@ -110,22 +93,6 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView dataChangeObservable?.cancel() } - private func setupNavBar() { - guard let navigationBar = navigationController?.navigationBar else { return } - if #available(iOS 15.0, *) { - let appearance = UINavigationBarAppearance() - appearance.configureWithOpaqueBackground() - appearance.backgroundColor = Colors.navigationBarBackground - navigationBar.standardAppearance = appearance; - navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance - } - } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - view.setGradient(Gradients.defaultBackground) - fadeView.setGradient(Gradients.homeVCFade) - } - // MARK: Layout private func setupLayout() { diff --git a/SessionUIKit/Database/Migrations/_001_ThemePreferences.swift b/SessionUIKit/Database/Migrations/_001_ThemePreferences.swift index e3e8b5763..13ebfc567 100644 --- a/SessionUIKit/Database/Migrations/_001_ThemePreferences.swift +++ b/SessionUIKit/Database/Migrations/_001_ThemePreferences.swift @@ -13,18 +13,18 @@ enum _001_ThemePreferences: Migration { static let minExpectedRunDuration: TimeInterval = 0.1 static func migrate(_ db: Database) throws { - // Start by adding the jobs that don't have collections (in the jobs like these - // will be added via migrations) + // Determine if the user was matching the system setting let isMatchingSystemSetting: Bool = UserDefaults.standard.dictionaryRepresentation() .keys .contains("appMode") - // TODO: Test the migration works + + // Set the default theme settings sccordingly db[.themeMatchSystemDayNightCycle] = isMatchingSystemSetting db[.theme] = (isMatchingSystemSetting ? - Theme.classicDark : ( - UserDefaults.standard.integer(forKey: "appMode") == 0 ? - Theme.classicLight : - Theme.classicDark + Theme.classicDark : + (UserDefaults.standard.integer(forKey: "appMode") == 0 ? + Theme.classicLight : + Theme.classicDark ) ) db[.themePrimaryColor] = Theme.PrimaryColor.green diff --git a/SessionUIKit/Style Guide/ThemeManager.swift b/SessionUIKit/Style Guide/ThemeManager.swift index 0def865d7..a710a51ab 100644 --- a/SessionUIKit/Style Guide/ThemeManager.swift +++ b/SessionUIKit/Style Guide/ThemeManager.swift @@ -22,54 +22,6 @@ public extension Setting.BoolKey { // MARK: - ThemeManager public enum ThemeManager { - fileprivate class ThemeApplier { - enum InfoKey: String { - case keyPath - case controlState - } - - private let applyTheme: (Theme) -> () - private let info: [AnyHashable] - private var otherAppliers: [ThemeManager.ThemeApplier]? - - init( - existingApplier: ThemeManager.ThemeApplier?, - info: [AnyHashable], - applyTheme: @escaping (Theme) -> () - ) { - self.applyTheme = applyTheme - self.info = info - - // Store any existing "appliers" (removing their 'otherApplier' references to prevent - // loops and excluding any which match the current "info" as they should be replaced - // by this applier) - self.otherAppliers = [existingApplier] - .appending(contentsOf: existingApplier?.otherAppliers) - .compactMap { $0?.clearingOtherAppliers() } - .filter { $0.info != info } - - // Automatically apply the theme immediately - self.apply(theme: ThemeManager.currentTheme) - } - - // MARK: - Functions - - private func clearingOtherAppliers() -> ThemeManager.ThemeApplier { - self.otherAppliers = nil - - return self - } - - fileprivate func apply(theme: Theme) { - self.applyTheme(theme) - - // If there are otherAppliers stored against this one then trigger those as well - self.otherAppliers?.forEach { applier in - applier.applyTheme(theme) - } - } - } - /// **Note:** Using `weakToStrongObjects` means that the value types will continue to be maintained until the map table resizes /// itself (ie. until a new UI element is registered to the table) /// @@ -126,13 +78,9 @@ public enum ThemeManager { db[.themeMatchSystemDayNightCycle] = matchSystemNightModeSetting } - // If the user enabled the "match system" setting then update the UI if needed - guard - matchSystemNightModeSetting && - UITraitCollection.current.userInterfaceStyle != ThemeManager.currentTheme.interfaceStyle - else { return } - - traitCollectionDidChange(UITraitCollection.current) + // Note: We have to trigger this directly or the 'TraitObservingWindow' won't actually + // trigger the trait change if the app launched with this setting switched off + applyWindowStyling() } } @@ -248,9 +196,7 @@ public enum ThemeManager { public static func applyWindowStyling() { mainWindow?.overrideUserInterfaceStyle = { - guard !Storage.shared[.themeMatchSystemDayNightCycle] else { - return .unspecified - } + guard !ThemeManager.matchSystemNightModeSetting else { return .unspecified } switch ThemeManager.currentTheme.interfaceStyle { case .light: return .light @@ -263,7 +209,7 @@ public enum ThemeManager { public static func onThemeChange(observer: AnyObject, callback: @escaping (Theme, Theme.PrimaryColor) -> ()) { ThemeManager.uiRegistry.setObject( - ThemeManager.ThemeApplier( + ThemeApplier( existingApplier: nil, info: [] ) { theme in callback(theme, ThemeManager.primaryColor) }, @@ -280,14 +226,14 @@ public enum ThemeManager { applyWindowStyling() } - fileprivate static func set( + internal static func set( _ view: T, keyPath: ReferenceWritableKeyPath, to value: ThemeValue?, for state: UIControl.State = .normal ) { ThemeManager.uiRegistry.setObject( - ThemeManager.ThemeApplier( + ThemeApplier( existingApplier: ThemeManager.get(for: view), info: [ keyPath ] ) { [weak view] theme in @@ -302,14 +248,14 @@ public enum ThemeManager { ) } - fileprivate static func set( + internal static func set( _ view: T, keyPath: ReferenceWritableKeyPath, to value: ThemeValue?, for state: UIControl.State = .normal ) { ThemeManager.uiRegistry.setObject( - ThemeManager.ThemeApplier( + ThemeApplier( existingApplier: ThemeManager.get(for: view), info: [ keyPath ] ) { [weak view] theme in @@ -324,9 +270,9 @@ public enum ThemeManager { ) } - fileprivate static func set( + internal static func set( _ view: T, - to applier: ThemeManager.ThemeApplier, + to applier: ThemeApplier, for state: UIControl.State = .normal ) { ThemeManager.uiRegistry.setObject(applier, forKey: view) @@ -335,135 +281,62 @@ public enum ThemeManager { /// Using a `UIColor(dynamicProvider:)` unfortunately doesn't seem to work properly for some controls (eg. UISwitch) so /// since we are already explicitly updating all UI when changing colours & states we just force-resolve the primary colour to avoid /// running into these glitches - fileprivate static func resolvedColor(_ color: UIColor?) -> UIColor? { + internal static func resolvedColor(_ color: UIColor?) -> UIColor? { return color?.resolvedColor(with: UITraitCollection()) } - fileprivate static func get(for view: AnyObject) -> ThemeApplier? { + internal static func get(for view: AnyObject) -> ThemeApplier? { return ThemeManager.uiRegistry.object(forKey: view) } } -// MARK: - View Extensions +// MARK: - ThemeApplier -public extension UIView { - var themeBackgroundColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.backgroundColor, to: newValue) } - get { return nil } +internal class ThemeApplier { + enum InfoKey: String { + case keyPath + case controlState } - var themeTintColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.tintColor, to: newValue) } - get { return nil } - } + private let applyTheme: (Theme) -> () + private let info: [AnyHashable] + private var otherAppliers: [ThemeApplier]? - var themeBorderColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.layer.borderColor, to: newValue) } - get { return nil } - } - - var themeShadowColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.layer.shadowColor, to: newValue) } - get { return nil } - } -} - -public extension UILabel { - var themeTextColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.textColor, to: newValue) } - get { return nil } - } -} - -public extension UITextView { - var themeTextColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.textColor, to: newValue) } - get { return nil } - } -} - -public extension UITextField { - var themeTextColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.textColor, to: newValue) } - get { return nil } - } -} - -public extension UIButton { - func setThemeBackgroundColor(_ value: ThemeValue?, for state: UIControl.State) { - let keyPath: KeyPath = \.imageView?.image + init( + existingApplier: ThemeApplier?, + info: [AnyHashable], + applyTheme: @escaping (Theme) -> () + ) { + self.applyTheme = applyTheme + self.info = info - ThemeManager.set( - self, - to: ThemeManager.ThemeApplier( - existingApplier: ThemeManager.get(for: self), - info: [ - keyPath, - state.rawValue - ] - ) { [weak self] theme in - guard - let value: ThemeValue = value, - let color: UIColor = ThemeManager.resolvedColor(theme.colors[value]) - else { - self?.setBackgroundImage(nil, for: state) - return - } - - self?.setBackgroundImage(color.toImage(), for: state) - } - ) - } - - func setThemeTitleColor(_ value: ThemeValue?, for state: UIControl.State) { - let keyPath: KeyPath = \.titleLabel?.textColor + // Store any existing "appliers" (removing their 'otherApplier' references to prevent + // loops and excluding any which match the current "info" as they should be replaced + // by this applier) + self.otherAppliers = [existingApplier] + .appending(contentsOf: existingApplier?.otherAppliers) + .compactMap { $0?.clearingOtherAppliers() } + .filter { $0.info != info } - ThemeManager.set( - self, - to: ThemeManager.ThemeApplier( - existingApplier: ThemeManager.get(for: self), - info: [ - keyPath, - state.rawValue - ] - ) { [weak self] theme in - guard let value: ThemeValue = value else { - self?.setTitleColor(nil, for: state) - return - } - - self?.setTitleColor( - ThemeManager.resolvedColor(theme.colors[value]), - for: state - ) - } - ) - } -} - -public extension UISwitch { - var themeOnTintColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.onTintColor, to: newValue) } - get { return nil } - } -} - -public extension UIBarButtonItem { - var themeTintColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.tintColor, to: newValue) } - get { return nil } - } -} - -public extension CAShapeLayer { - var themeStrokeColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.strokeColor, to: newValue) } - get { return nil } + // Automatically apply the theme immediately + self.apply(theme: ThemeManager.currentTheme) } - var themeFillColor: ThemeValue? { - set { ThemeManager.set(self, keyPath: \.fillColor, to: newValue) } - get { return nil } + // MARK: - Functions + + private func clearingOtherAppliers() -> ThemeApplier { + self.otherAppliers = nil + + return self + } + + fileprivate func apply(theme: Theme) { + self.applyTheme(theme) + + // If there are otherAppliers stored against this one then trigger those as well + self.otherAppliers?.forEach { applier in + applier.applyTheme(theme) + } } } diff --git a/SessionUIKit/Style Guide/Themes/Theme+ClassicDark.swift b/SessionUIKit/Style Guide/Themes/Theme+ClassicDark.swift index b90fa2b87..6492e1677 100644 --- a/SessionUIKit/Style Guide/Themes/Theme+ClassicDark.swift +++ b/SessionUIKit/Style Guide/Themes/Theme+ClassicDark.swift @@ -11,6 +11,7 @@ internal enum Theme_ClassicDark: ThemeColors { .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), + .backgroundTertiary: #colorLiteral(red: 0.1764705882, green: 0.1764705882, blue: 0.1764705882, alpha: 1), .textPrimary: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), .textSecondary: #colorLiteral(red: 0.631372549, green: 0.6352941176, blue: 0.631372549, alpha: 1), .borderSeparator: #colorLiteral(red: 0.2549019608, green: 0.2549019608, blue: 0.2549019608, alpha: 1), @@ -28,7 +29,8 @@ internal enum Theme_ClassicDark: ThemeColors { // MenuButton .menuButton_background: .primary, .menuButton_icon: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), - .menuButton_shadow: .primary, + .menuButton_outerShadow: .primary, + .menuButton_innerShadow: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), // RadioButton .radioButton_selectedBackground: .primary, @@ -60,6 +62,12 @@ internal enum Theme_ClassicDark: ThemeColors { // ConversationButton .conversationButton_background: #colorLiteral(red: 0.1058823529, green: 0.1058823529, blue: 0.1058823529, alpha: 1), - .conversationButton_highlight: #colorLiteral(red: 0.2549019608, green: 0.2549019608, blue: 0.2549019608, alpha: 1) + .conversationButton_highlight: #colorLiteral(red: 0.2549019608, green: 0.2549019608, blue: 0.2549019608, alpha: 1), + .conversationButton_unreadBackground: #colorLiteral(red: 0.1764705882, green: 0.1764705882, blue: 0.1764705882, alpha: 1), + .conversationButton_unreadHighlight: #colorLiteral(red: 0.2549019608, green: 0.2549019608, blue: 0.2549019608, alpha: 1), + .conversationButton_unreadStripBackground: .primary, + .conversationButton_unreadBubbleBackground: #colorLiteral(red: 0.2549019608, green: 0.2549019608, blue: 0.2549019608, alpha: 1), + .conversationButton_unreadBubbleText: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), + .conversationButton_pinBackground: Theme.PrimaryColor.yellow.color ] } diff --git a/SessionUIKit/Style Guide/Themes/Theme+ClassicLight.swift b/SessionUIKit/Style Guide/Themes/Theme+ClassicLight.swift index d51374908..7de7449c6 100644 --- a/SessionUIKit/Style Guide/Themes/Theme+ClassicLight.swift +++ b/SessionUIKit/Style Guide/Themes/Theme+ClassicLight.swift @@ -11,6 +11,7 @@ internal enum Theme_ClassicLight: ThemeColors { .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), + .backgroundTertiary: #colorLiteral(red: 0.9058823529, green: 0.9058823529, blue: 0.9058823529, alpha: 1), .textPrimary: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), .textSecondary: #colorLiteral(red: 0.4274509804, green: 0.4274509804, blue: 0.4274509804, alpha: 1), .borderSeparator: #colorLiteral(red: 0.631372549, green: 0.6352941176, blue: 0.631372549, alpha: 1), @@ -28,7 +29,8 @@ internal enum Theme_ClassicLight: ThemeColors { // MenuButton .menuButton_background: .primary, .menuButton_icon: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), - .menuButton_shadow: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), + .menuButton_outerShadow: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), + .menuButton_innerShadow: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), // RadioButton .radioButton_selectedBackground: .primary, @@ -60,6 +62,12 @@ internal enum Theme_ClassicLight: ThemeColors { // ConversationButton .conversationButton_background: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), - .conversationButton_highlight: #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9411764706, alpha: 1) + .conversationButton_highlight: #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9411764706, alpha: 1), + .conversationButton_unreadBackground: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), + .conversationButton_unreadHighlight: #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9411764706, alpha: 1), + .conversationButton_unreadStripBackground: .primary, + .conversationButton_unreadBubbleBackground: #colorLiteral(red: 0.8745098039, green: 0.8745098039, blue: 0.8745098039, alpha: 1), + .conversationButton_unreadBubbleText: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), + .conversationButton_pinBackground: Theme.PrimaryColor.yellow.color ] } diff --git a/SessionUIKit/Style Guide/Themes/Theme+OceanDark.swift b/SessionUIKit/Style Guide/Themes/Theme+OceanDark.swift index f437ca426..2bcb20f62 100644 --- a/SessionUIKit/Style Guide/Themes/Theme+OceanDark.swift +++ b/SessionUIKit/Style Guide/Themes/Theme+OceanDark.swift @@ -11,6 +11,7 @@ internal enum Theme_OceanDark: ThemeColors { .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), + .backgroundTertiary: #colorLiteral(red: 0.1725490196, green: 0.1803921569, blue: 0.2274509804, alpha: 1), .textPrimary: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), .textSecondary: #colorLiteral(red: 0.6509803922, green: 0.662745098, blue: 0.8078431373, alpha: 1), .borderSeparator: #colorLiteral(red: 0.2392156863, green: 0.2901960784, blue: 0.3647058824, alpha: 1), @@ -28,7 +29,8 @@ internal enum Theme_OceanDark: ThemeColors { // MenuButton .menuButton_background: .primary, .menuButton_icon: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), - .menuButton_shadow: .primary, + .menuButton_outerShadow: .primary, + .menuButton_innerShadow: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), // RadioButton .radioButton_selectedBackground: .primary, @@ -54,12 +56,18 @@ internal enum Theme_OceanDark: ThemeColors { .settings_tabHighlight: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1), // Appearance - .appearance_sectionBackground: #colorLiteral(red: 0.1019607843, green: 0.1098039216, blue: 0.1568627451, alpha: 1), - .appearance_buttonBackground: #colorLiteral(red: 0.1019607843, green: 0.1098039216, blue: 0.1568627451, alpha: 1), + .appearance_sectionBackground: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1), + .appearance_buttonBackground: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1), .appearance_buttonHighlight: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1), // ConversationButton .conversationButton_background: #colorLiteral(red: 0.168627451, green: 0.168627451, blue: 0.2509803922, alpha: 1), - .conversationButton_highlight: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1) + .conversationButton_highlight: #colorLiteral(red: 0.168627451, green: 0.1764705882, blue: 0.2509803922, alpha: 1), + .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_pinBackground: Theme.PrimaryColor.yellow.color ] } diff --git a/SessionUIKit/Style Guide/Themes/Theme+OceanLight.swift b/SessionUIKit/Style Guide/Themes/Theme+OceanLight.swift index d71572e98..b7eac4007 100644 --- a/SessionUIKit/Style Guide/Themes/Theme+OceanLight.swift +++ b/SessionUIKit/Style Guide/Themes/Theme+OceanLight.swift @@ -11,6 +11,7 @@ internal enum Theme_OceanLight: ThemeColors { .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), + .backgroundTertiary: #colorLiteral(red: 0.8549019608, green: 0.9098039216, blue: 0.9137254902, alpha: 1), .textPrimary: #colorLiteral(red: 0.09803921569, green: 0.2039215686, blue: 0.3647058824, alpha: 1), .textSecondary: #colorLiteral(red: 0.4156862745, green: 0.431372549, blue: 0.5647058824, alpha: 1), .borderSeparator: #colorLiteral(red: 0.3607843137, green: 0.6666666667, blue: 0.8, alpha: 1), @@ -28,7 +29,8 @@ internal enum Theme_OceanLight: ThemeColors { // MenuButton .menuButton_background: .primary, .menuButton_icon: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), - .menuButton_shadow: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), + .menuButton_outerShadow: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), + .menuButton_innerShadow: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), // RadioButton .radioButton_selectedBackground: .primary, @@ -60,6 +62,12 @@ internal enum Theme_OceanLight: ThemeColors { // ConversationButton .conversationButton_background: #colorLiteral(red: 0.9882352941, green: 1, blue: 1, alpha: 1), - .conversationButton_highlight: #colorLiteral(red: 0.9058823529, green: 0.9529411765, blue: 0.9568627451, alpha: 1) + .conversationButton_highlight: #colorLiteral(red: 0.9058823529, green: 0.9529411765, blue: 0.9568627451, alpha: 1), + .conversationButton_unreadBackground: #colorLiteral(red: 0.9254901961, green: 0.9803921569, blue: 0.9843137255, alpha: 1), + .conversationButton_unreadHighlight: #colorLiteral(red: 0.9058823529, green: 0.9529411765, blue: 0.9568627451, alpha: 1), + .conversationButton_unreadStripBackground: .primary, + .conversationButton_unreadBubbleBackground: .primary, + .conversationButton_unreadBubbleText: #colorLiteral(red: 0.09803921569, green: 0.2039215686, blue: 0.3647058824, alpha: 1), + .conversationButton_pinBackground: Theme.PrimaryColor.yellow.color ] } diff --git a/SessionUIKit/Style Guide/Themes/Theme.swift b/SessionUIKit/Style Guide/Themes/Theme.swift index 84d6ace35..daa0edb89 100644 --- a/SessionUIKit/Style Guide/Themes/Theme.swift +++ b/SessionUIKit/Style Guide/Themes/Theme.swift @@ -62,6 +62,7 @@ public enum ThemeValue { case clear case backgroundPrimary case backgroundSecondary + case backgroundTertiary case textPrimary case textSecondary case borderSeparator @@ -79,7 +80,8 @@ public enum ThemeValue { // MenuButton case menuButton_background case menuButton_icon - case menuButton_shadow + case menuButton_outerShadow + case menuButton_innerShadow // RadioButton case radioButton_selectedBackground @@ -112,4 +114,10 @@ public enum ThemeValue { // ConversationButton case conversationButton_background case conversationButton_highlight + case conversationButton_unreadBackground + case conversationButton_unreadHighlight + case conversationButton_unreadStripBackground + case conversationButton_unreadBubbleBackground + case conversationButton_unreadBubbleText + case conversationButton_pinBackground } diff --git a/SessionUIKit/Style Guide/Themes/UIKit+Theme.swift b/SessionUIKit/Style Guide/Themes/UIKit+Theme.swift new file mode 100644 index 000000000..a80511fee --- /dev/null +++ b/SessionUIKit/Style Guide/Themes/UIKit+Theme.swift @@ -0,0 +1,155 @@ +// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. + +import UIKit + +public extension UIView { + var themeBackgroundColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.backgroundColor, to: newValue) } + get { return nil } + } + + var themeTintColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.tintColor, to: newValue) } + get { return nil } + } + + var themeBorderColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.layer.borderColor, to: newValue) } + get { return nil } + } + + var themeShadowColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.layer.shadowColor, to: newValue) } + get { return nil } + } +} + +public extension UILabel { + var themeTextColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.textColor, to: newValue) } + get { return nil } + } +} + +public extension UITextView { + var themeTextColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.textColor, to: newValue) } + get { return nil } + } +} + +public extension UITextField { + var themeTextColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.textColor, to: newValue) } + get { return nil } + } +} + +public extension UIButton { + func setThemeBackgroundColor(_ value: ThemeValue?, for state: UIControl.State) { + let keyPath: KeyPath = \.imageView?.image + + ThemeManager.set( + self, + to: ThemeApplier( + existingApplier: ThemeManager.get(for: self), + info: [ + keyPath, + state.rawValue + ] + ) { [weak self] theme in + guard + let value: ThemeValue = value, + let color: UIColor = ThemeManager.resolvedColor(theme.colors[value]) + else { + self?.setBackgroundImage(nil, for: state) + return + } + + self?.setBackgroundImage(color.toImage(), for: state) + } + ) + } + + func setThemeTitleColor(_ value: ThemeValue?, for state: UIControl.State) { + let keyPath: KeyPath = \.titleLabel?.textColor + + ThemeManager.set( + self, + to: ThemeApplier( + existingApplier: ThemeManager.get(for: self), + info: [ + keyPath, + state.rawValue + ] + ) { [weak self] theme in + guard let value: ThemeValue = value else { + self?.setTitleColor(nil, for: state) + return + } + + self?.setTitleColor( + ThemeManager.resolvedColor(theme.colors[value]), + for: state + ) + } + ) + } +} + +public extension UISwitch { + var themeOnTintColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.onTintColor, to: newValue) } + get { return nil } + } +} + +public extension UIBarButtonItem { + var themeTintColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.tintColor, to: newValue) } + get { return nil } + } +} + +public extension UIProgressView { + var themeProgressTintColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.progressTintColor, to: newValue) } + get { return nil } + } + + var themeTrackTintColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.trackTintColor, to: newValue) } + get { return nil } + } +} + +public extension UITableViewRowAction { + var themeBackgroundColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.backgroundColor, to: newValue) } + get { return nil } + } +} + +public extension CAShapeLayer { + var themeStrokeColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.strokeColor, to: newValue) } + get { return nil } + } + + var themeFillColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.fillColor, to: newValue) } + get { return nil } + } +} + +public extension CALayer { + var themeBorderColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.borderColor, to: newValue) } + get { return nil } + } + + var themeShadowColor: ThemeValue? { + set { ThemeManager.set(self, keyPath: \.shadowColor, to: newValue) } + get { return nil } + } +} diff --git a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift index bdc17323e..4a59f1dc7 100644 --- a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift +++ b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift @@ -516,8 +516,14 @@ public class PagedDatabaseObserver: TransactionObserver where limit: queryInfo.limit, offset: queryInfo.offset ) - let newData: [T] = try dataQuery(pageRowIds) - .fetchAll(db) + let newData: [T] + + do { newData = try dataQuery(pageRowIds).fetchAll(db) } + catch { + SNLog("PagedDatabaseObserver threw exception: \(error)") + throw error + } + let updatedLimitInfo: PagedData.PageInfo = PagedData.PageInfo( pageSize: currentPageInfo.pageSize, pageOffset: queryInfo.updatedCacheOffset, diff --git a/SignalUtilitiesKit/Profile Pictures/Identicon+ObjC.swift b/SignalUtilitiesKit/Profile Pictures/Identicon+ObjC.swift index feac3ea3f..256438529 100644 --- a/SignalUtilitiesKit/Profile Pictures/Identicon+ObjC.swift +++ b/SignalUtilitiesKit/Profile Pictures/Identicon+ObjC.swift @@ -1,6 +1,7 @@ // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. import UIKit +import SessionUIKit import SessionUtilitiesKit @objc(LKIdenticon) diff --git a/SignalUtilitiesKit/Profile Pictures/PlaceholderIcon.swift b/SignalUtilitiesKit/Profile Pictures/PlaceholderIcon.swift index 450fcbcb4..41acffbd4 100644 --- a/SignalUtilitiesKit/Profile Pictures/PlaceholderIcon.swift +++ b/SignalUtilitiesKit/Profile Pictures/PlaceholderIcon.swift @@ -1,14 +1,14 @@ +// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. + +import UIKit import CryptoSwift +import SessionUIKit public class PlaceholderIcon { private let seed: Int + // Colour palette - private var colours: [UIColor] = [ - 0x5ff8b0, - 0x26cdb9, - 0xf3c615, - 0xfcac5a - ].map { UIColor(hex: $0) } + private var colours: [UIColor] = Theme.PrimaryColor.allCases.map { $0.color } init(seed: Int, colours: [UIColor]? = nil) { self.seed = seed diff --git a/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift b/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift index 5dd308a11..7cba13f55 100644 --- a/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift +++ b/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift @@ -19,8 +19,15 @@ public final class ProfilePictureView: UIView { // MARK: - Components - private lazy var imageView = getImageView() - private lazy var additionalImageView = getImageView() + private lazy var imageView: YYAnimatedImageView = getImageView() + private lazy var additionalImageView: YYAnimatedImageView = { + let result: YYAnimatedImageView = getImageView() + result.themeBackgroundColor = .backgroundTertiary + result.themeBorderColor = .backgroundPrimary + result.layer.borderWidth = Values.separatorThickness + + return result + }() // MARK: - Lifecycle